diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c9a0d32b9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "OpenCorePkg"] + path = OpenCorePkg + url = https://github.com/CloverHackyColor/OpenCorePkg.git diff --git a/Clover.dsc b/Clover.dsc index 0897fbbb7..0c23f0662 100644 --- a/Clover.dsc +++ b/Clover.dsc @@ -88,7 +88,7 @@ #EblCmdLib|EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - UefiCpuLib|CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf !ifdef ENABLE_SECURE_BOOT OpensslLib|Library/OpensslLib/openssl-$(OPENSSL_VERSION)/OpensslLib.inf IntrinsicLib|Library/IntrinsicLib/IntrinsicLib.inf @@ -134,11 +134,11 @@ PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf #SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf - SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf - MtrrLib|CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf + #SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf - LocalApicLib|CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf - #LocalApicLib|CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + #LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf # # To save size, use NULL library for DebugLib and ReportStatusCodeLib. @@ -147,11 +147,13 @@ !ifdef DEBUG_ON_SERIAL_PORT BaseSerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf !else BaseSerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf !endif BaseDebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugLib|OpenCorePkg/Library/OcDebugLogLib/OcDebugLogLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf @@ -170,35 +172,64 @@ # # OC libs # - OcGuardLib|Library/OcGuardLib/OcGuardLib.inf - OcAfterBootCompatLib|Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf - OcAppleBootPolicyLib|Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf - OcAppleChunklistLib|Library/OcAppleChunklistLib/OcAppleChunklistLib.inf - OcAppleDiskImageLib|Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf - OcAppleKeyMapLib|Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf - OcAppleKeysLib|Library/OcAppleKeysLib/OcAppleKeysLib.inf - OcAppleRamDiskLib|Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf - OcBootManagementLib|Library/OcBootManagementLib/OcBootManagementLib.inf - OcCompressionLib|Library/OcCompressionLib/OcCompressionLib.inf - OcConsoleLib|Library/OcConsoleLib/OcConsoleLib.inf - OcCpuLib|Library/OcCpuLib/OcCpuLib.inf - OcCryptoLib|Library/OcCryptoLib/OcCryptoLib.inf - OcDebugLogLib|Library/OcDebugLogLib/OcDebugLogLib.inf - OcDevicePathLib|Library/OcDevicePathLib/OcDevicePathLib.inf - OcFileLib|Library/OcFileLib/OcFileLib.inf - OcMemoryLib|Library/OcMemoryLib/OcMemoryLib.inf - OcMiscLib|Library/OcMiscLib/OcMiscLib.inf - OcOSInfoLib|Library/OcOSInfoLib/OcOSInfoLib.inf - OcRngLib|Library/OcRngLib/OcRngLib.inf - OcRtcLib|Library/OcRtcLib/OcRtcLib.inf - OcSerializeLib|Library/OcSerializeLib/OcSerializeLib.inf - OcStringLib|Library/OcStringLib/OcStringLib.inf - OcStorageLib|Library/OcStorageLib/OcStorageLib.inf - OcTemplateLib|Library/OcTemplateLib/OcTemplateLib.inf - OcXmlLib|Library/OcXmlLib/OcXmlLib.inf + OcGuardLib|OpenCorePkg/Library/OcGuardLib/OcGuardLib.inf + OcAfterBootCompatLib|OpenCorePkg/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf + OcAppleBootPolicyLib|OpenCorePkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf + OcAppleChunklistLib|OpenCorePkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf + OcAppleDiskImageLib|OpenCorePkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf + OcAppleKeyMapLib|OpenCorePkg/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf + OcAppleKeysLib|OpenCorePkg/Library/OcAppleKeysLib/OcAppleKeysLib.inf + OcAppleRamDiskLib|OpenCorePkg/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf + OcBootManagementLib|OpenCorePkg/Library/OcBootManagementLib/OcBootManagementLib.inf + OcCompressionLib|OpenCorePkg/Library/OcCompressionLib/OcCompressionLib.inf + OcConsoleLib|OpenCorePkg/Library/OcConsoleLib/OcConsoleLib.inf + OcCpuLib|OpenCorePkg/Library/OcCpuLib/OcCpuLib.inf + OcCryptoLib|OpenCorePkg/Library/OcCryptoLib/OcCryptoLib.inf + OcDebugLogLib|OpenCorePkg/Library/OcDebugLogLib/OcDebugLogLib.inf + OcDevicePathLib|OpenCorePkg/Library/OcDevicePathLib/OcDevicePathLib.inf + OcFileLib|OpenCorePkg/Library/OcFileLib/OcFileLib.inf + OcMemoryLib|OpenCorePkg/Library/OcMemoryLib/OcMemoryLib.inf + OcMiscLib|OpenCorePkg/Library/OcMiscLib/OcMiscLib.inf + OcOSInfoLib|OpenCorePkg/Library/OcOSInfoLib/OcOSInfoLib.inf + OcRngLib|OpenCorePkg/Library/OcRngLib/OcRngLib.inf + OcRtcLib|OpenCorePkg/Library/OcRtcLib/OcRtcLib.inf + OcSerializeLib|OpenCorePkg/Library/OcSerializeLib/OcSerializeLib.inf + OcStringLib|OpenCorePkg/Library/OcStringLib/OcStringLib.inf + OcStorageLib|OpenCorePkg/Library/OcStorageLib/OcStorageLib.inf + OcTemplateLib|OpenCorePkg/Library/OcTemplateLib/OcTemplateLib.inf + OcXmlLib|OpenCorePkg/Library/OcXmlLib/OcXmlLib.inf + OcDeviceTreeLib|OpenCorePkg/Library/OcDeviceTreeLib/OcDeviceTreeLib.inf + OcDebugLogLib|OpenCorePkg/Library/OcDebugLogLib/OcDebugLogLib.inf + OcDataHubLib|OpenCorePkg/Library/OcDataHubLib/OcDataHubLib.inf + OcAppleImg4Lib|OpenCorePkg/Library/OcAppleImg4Lib/OcAppleImg4Lib.inf + OcAppleKernelLib|OpenCorePkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf + OcMachoLib|OpenCorePkg/Library/OcMachoLib/OcMachoLib.inf + OcVirtualFsLib|OpenCorePkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf + OcMacInfoLib|OpenCorePkg/Library/OcMacInfoLib/OcMacInfoLib.inf + OcApfsLib|OpenCorePkg/Library/OcApfsLib/OcApfsLib.inf + OcAppleSecureBootLib|OpenCorePkg/Library/OcAppleSecureBootLib/OcAppleSecureBootLib.inf + OcAppleImageVerificationLib|OpenCorePkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf + OcDriverConnectionLib|OpenCorePkg/Library/OcDriverConnectionLib/OcDriverConnectionLib.inf + OcDebugLogLib|OpenCorePkg/Library/OcDebugLogLib/OcDebugLogLib.inf + OcAcpiLib|OpenCorePkg/Library/OcAcpiLib/OcAcpiLib.inf + OcAppleEventLib|OpenCorePkg/Library/OcAppleEventLib/OcAppleEventLib.inf + #OcAppleImageConversionLib|OpenCorePkg/Library/OcAppleImageConversionLib/OcAppleImageConversionLib.inf + OcAudioLib|OpenCorePkg/Library/OcAudioLib/OcAudioLib.inf + OcInputLib|OpenCorePkg/Library/OcInputLib/OcInputLib.inf + OcAppleUserInterfaceThemeLib|OpenCorePkg/Library/OcAppleUserInterfaceThemeLib/OcAppleUserInterfaceThemeLib.inf + OcConfigurationLib|OpenCorePkg/Library/OcConfigurationLib/OcConfigurationLib.inf + OcDevicePropertyLib|OpenCorePkg/Library/OcDevicePropertyLib/OcDevicePropertyLib.inf + OcFirmwareVolumeLib|OpenCorePkg/Library/OcFirmwareVolumeLib/OcFirmwareVolumeLib.inf + OcHashServicesLib|OpenCorePkg/Library/OcHashServicesLib/OcHashServicesLib.inf + OcSmbiosLib|OpenCorePkg/Library/OcSmbiosLib/OcSmbiosLib.inf + OcSmcLib|OpenCorePkg/Library/OcSmcLib/OcSmcLib.inf + OcUnicodeCollationEngGenericLib|OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngGenericLib.inf + OcPeCoffLib|OpenCorePkg/Library/OcPeCoffLib/OcPeCoffLib.inf + #OcPngLib|OpenCorePkg/Library/OcPngLib/OcPngLib.inf + + OpenCoreLib|OpenCorePkg/Platform/OpenCore/OpenCoreLib.inf - MachoLib|Library/MachoLib/MachoLib.inf - DeviceTreeLib|Library/DeviceTreeLib/DeviceTreeLib.inf + #MachoLib|Library/MachoLib/MachoLib.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf @@ -353,7 +384,7 @@ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf } MdeModulePkg/Universal/EbcDxe/EbcDxe.inf - CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf #UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf #UefiCpuPkg/CpuDxe/CpuDxe.inf #UefiCpuPkg/CpuDxe/CpuDxe.inf @@ -489,7 +520,7 @@ #MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf #MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf #SaveResume/BootScriptExecutorDxe/BootScriptExecutorDxe.inf - #CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf + #UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf # Bios Thunk #IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf @@ -610,7 +641,7 @@ SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf - DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf } !else rEFIt_UEFI/refit.inf { @@ -626,8 +657,8 @@ MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf MemoryFix/AptioMemoryFix/AptioMemoryFix.inf - MemoryFix/OpenRuntime/OpenRuntime.inf - MemoryFix/OcQuirks/OcQuirks.inf + OpenCorePkg/Platform/OpenRuntime/OpenRuntime.inf + !ifdef DEBUG_ON_SERIAL_PORT MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf { # @@ -714,14 +745,14 @@ DEFINE EXIT_USBKB_FLAG = -DEXIT_USBKB !endif -DEFINE BUILD_OPTIONS=-DMDEPKG_NDEBUG -DCLOVER_BUILD $(VBIOS_PATCH_CLOVEREFI_FLAG) $(ONLY_SATA_0_FLAG) $(BLOCKIO_FLAG) $(NOUSB_FLAG) $(NOUDMA_FLAG) $(AMD_FLAG) $(SECURE_BOOT_FLAG) $(ANDX86_FLAG) $(PS2MOUSE_LEGACYBOOT_FLAG) $(DEBUG_ON_SERIAL_PORT_FLAG) $(EXIT_USBKB_FLAG) +DEFINE BUILD_OPTIONS=-DCLOVER_BUILD $(VBIOS_PATCH_CLOVEREFI_FLAG) $(ONLY_SATA_0_FLAG) $(BLOCKIO_FLAG) $(NOUSB_FLAG) $(NOUDMA_FLAG) $(AMD_FLAG) $(SECURE_BOOT_FLAG) $(ANDX86_FLAG) $(PS2MOUSE_LEGACYBOOT_FLAG) $(DEBUG_ON_SERIAL_PORT_FLAG) $(EXIT_USBKB_FLAG) #MSFT:*_*_*_CC_FLAGS = /FAcs /FR$(@R).SBR /wd4701 /wd4703 $(BUILD_OPTIONS) - MSFT:*_*_*_CC_FLAGS = /FAcs $(BUILD_OPTIONS) -Dinline=__inline /Zi -D DISABLE_NEW_DEPRECATED_INTERFACES + MSFT:*_*_*_CC_FLAGS = /FAcs $(BUILD_OPTIONS) -Dinline=__inline /Zi -D DISABLE_NEW_DEPRECATED_INTERFACES -D OC_TARGET_DEBUG - XCODE:*_*_*_CC_FLAGS = -fno-unwind-tables -Wno-msvc-include -Os $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES - GCC:*_*_*_CC_FLAGS = $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES - GCC:*_*_*_CXX_FLAGS = $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES + XCODE:*_*_*_CC_FLAGS = -fno-unwind-tables -Wno-msvc-include -Os $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES -D OC_TARGET_DEBUG + GCC:*_*_*_CC_FLAGS = $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES -D OC_TARGET_DEBUG + GCC:*_*_*_CXX_FLAGS = $(BUILD_OPTIONS) $(DISABLE_LTO_FLAG) -D DISABLE_NEW_DEPRECATED_INTERFACES -D OC_TARGET_DEBUG #-fanalyzer -Wmismatched-tags #-Weffc++ #-Wunused-but-set-variable diff --git a/Clover.fdf b/Clover.fdf index febb5fdf8..940cd348c 100644 --- a/Clover.fdf +++ b/Clover.fdf @@ -104,7 +104,7 @@ INF CloverEFI/OsxSmbiosGenDxe/SmbiosGen.inf INF CloverEFI/OsxBdsDxe/BdsDxe.inf INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf -INF CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf +#INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf #INF UefiCpuPkg/CpuDxe/CpuDxe.inf #INF IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf diff --git a/CloverEFI/BiosKeyboard/BiosKeyboard.c b/CloverEFI/BiosKeyboard/BiosKeyboard.c index 2573eceb3..4699e3f41 100644 --- a/CloverEFI/BiosKeyboard/BiosKeyboard.c +++ b/CloverEFI/BiosKeyboard/BiosKeyboard.c @@ -37,7 +37,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define DBG(...) #endif -extern int MapBiosKey(EFI_KEY_DATA KeyData, APPLE_KEY* pKey, UINT8* pCurModifierMap); +extern int MapBiosKey(EFI_KEY_DATA KeyData, APPLE_KEY_CODE* pKey, UINT8* pCurModifierMap); // // EFI Driver Binding Protocol Instance // @@ -1840,7 +1840,7 @@ CheckKeyboardConnect ( **/ static int apple_need_zero = 0; -int MapBiosKey(EFI_KEY_DATA KeyData, APPLE_KEY* pKey, UINT8* pCurModifierMap) +int MapBiosKey(EFI_KEY_DATA KeyData, APPLE_KEY_CODE* pKey, UINT8* pCurModifierMap) { if ( KeyData.Key.UnicodeChar == 0 ) { @@ -2045,7 +2045,7 @@ BiosKeyboardTimerHandler ( BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; //for AppleDb UINTN NumberOfKeys; - APPLE_KEY Keys[8]; // APPLE_KEY is UINT16 + APPLE_KEY_CODE Keys[8]; // APPLE_KEY_CODE is UINT16 ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); @@ -2310,9 +2310,9 @@ BiosKeyboardTimerHandler ( */ // NumberOfKeys = 3; -// Keys[0] = (APPLE_KEY)KeyData.KeyState.KeyShiftState; -// Keys[1] = (APPLE_KEY)KeyData.KeyState.KeyToggleState; //or 0? -// Keys[2] = (APPLE_KEY)KeyData.Key.ScanCode; +// Keys[0] = (APPLE_KEY_CODE)KeyData.KeyState.KeyShiftState; +// Keys[1] = (APPLE_KEY_CODE)KeyData.KeyState.KeyToggleState; //or 0? +// Keys[2] = (APPLE_KEY_CODE)KeyData.Key.ScanCode; // Parse the modifier key, which is the first byte of keyboard input report. // diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.inf b/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.inf deleted file mode 100644 index 6fd981a7c..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.inf +++ /dev/null @@ -1,70 +0,0 @@ -## @file -# -# Component description file for simple CPU driver -# -# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = CpuDxeClover - FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = InitializeCpu - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - CpuLib - DebugLib - DxeServicesTableLib - MemoryAllocationLib - MtrrLib - UefiBootServicesTableLib - UefiDriverEntryPoint - LocalApicLib - UefiCpuLib - -[Sources] - CpuDxe.c - CpuDxe.h - CpuGdt.c - - Ia32/IvtAsm.asm | MSFT - Ia32/IvtAsm.asm | INTEL - Ia32/IvtAsm.S | GCC - -[Sources.IA32] - Ia32/CpuAsm.asm | MSFT - Ia32/CpuAsm.asm | INTEL - Ia32/CpuAsm.S | GCC - -[Sources.X64] - X64/CpuAsm.asm | MSFT - X64/CpuAsm.asm | INTEL - X64/CpuAsm.S | GCC - -[Protocols] - gEfiCpuArchProtocolGuid - -[Guids] - gIdleLoopEventGuid ## CONSUMES ## GUID - -[Depex] - TRUE - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/CpuGdt.c b/CloverEFI/UefiCpuPkg/CpuDxe/CpuGdt.c deleted file mode 100644 index f08c33cee..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/CpuGdt.c +++ /dev/null @@ -1,201 +0,0 @@ -/** @file - C based implemention of IA32 interrupt handling only - requiring a minimal assembly interrupt entry point. - - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "CpuDxe.h" - - -// -// Local structure definitions -// - -#pragma pack (1) - -// -// Global Descriptor Entry structures -// - -typedef struct _GDT_ENTRY { - UINT16 Limit15_0; - UINT16 Base15_0; - UINT8 Base23_16; - UINT8 Type; - UINT8 Limit19_16_and_flags; - UINT8 Base31_24; -} GDT_ENTRY; - -typedef -struct _GDT_ENTRIES { - GDT_ENTRY Null; - GDT_ENTRY Linear; - GDT_ENTRY LinearCode; - GDT_ENTRY SysData; - GDT_ENTRY SysCode; - GDT_ENTRY LinearCode64; - GDT_ENTRY Spare4; - GDT_ENTRY Spare5; -} GDT_ENTRIES; - -#define NULL_SEL OFFSET_OF (GDT_ENTRIES, Null) -#define LINEAR_SEL OFFSET_OF (GDT_ENTRIES, Linear) -#define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode) -#define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData) -#define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode) -#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64) -#define SPARE4_SEL OFFSET_OF (GDT_ENTRIES, Spare4) -#define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5) - -#if defined (MDE_CPU_IA32) -#define CPU_CODE_SEL LINEAR_CODE_SEL -#define CPU_DATA_SEL LINEAR_SEL -#elif defined (MDE_CPU_X64) -#define CPU_CODE_SEL LINEAR_CODE64_SEL -#define CPU_DATA_SEL LINEAR_SEL -//#else -//#error CPU type not supported for CPU GDT initialization! -#endif - -// -// Global descriptor table (GDT) Template -// -STATIC GDT_ENTRIES GdtTemplate = { - // - // NULL_SEL - // - { - 0x0, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x0, // type - 0x0, // limit 19:16, flags - 0x0, // base 31:24 - }, - // - // LINEAR_SEL - // - { - 0x0FFFF, // limit 0xFFFFF - 0x0, // base 0 - 0x0, - 0x092, // present, ring 0, data, expand-up, writable - 0x0CF, // page-granular, 32-bit - 0x0, - }, - // - // LINEAR_CODE_SEL - // - { - 0x0FFFF, // limit 0xFFFFF - 0x0, // base 0 - 0x0, - 0x09A, // present, ring 0, data, expand-up, writable - 0x0CF, // page-granular, 32-bit - 0x0, - }, - // - // SYS_DATA_SEL - // - { - 0x0FFFF, // limit 0xFFFFF - 0x0, // base 0 - 0x0, - 0x092, // present, ring 0, data, expand-up, writable - 0x0CF, // page-granular, 32-bit - 0x0, - }, - // - // SYS_CODE_SEL - // - { - 0x0FFFF, // limit 0xFFFFF - 0x0, // base 0 - 0x0, - 0x09A, // present, ring 0, data, expand-up, writable - 0x0CF, // page-granular, 32-bit - 0x0, - }, - // - // LINEAR_CODE64_SEL - // - { - 0x0FFFF, // limit 0xFFFFF - 0x0, // base 0 - 0x0, - 0x09B, // present, ring 0, code, expand-up, writable - 0x0AF, // LimitHigh (CS.L=1, CS.D=0) - 0x0, // base (high) - }, - // - // SPARE4_SEL - // - { - 0x0, // limit 0 - 0x0, // base 0 - 0x0, - 0x0, // present, ring 0, data, expand-up, writable - 0x0, // page-granular, 32-bit - 0x0, - }, - // - // SPARE5_SEL - // - { - 0x0, // limit 0 - 0x0, // base 0 - 0x0, - 0x0, // present, ring 0, data, expand-up, writable - 0x0, // page-granular, 32-bit - 0x0, - }, -}; - -/** - Initialize Global Descriptor Table. - -**/ -VOID -InitGlobalDescriptorTable ( - VOID - ) -{ - GDT_ENTRIES *gdt; - IA32_DESCRIPTOR gdtPtr; - - // - // Allocate Runtime Data for the GDT - // - gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); - ASSERT (gdt != NULL); - gdt = ALIGN_POINTER (gdt, 8); - - // - // Initialize all GDT entries - // - CopyMem(gdt, &GdtTemplate, sizeof (GdtTemplate)); - - // - // Write GDT register - // - //gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; - gdtPtr.Base = (UINTN)(VOID*) gdt; - gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); - AsmWriteGdtr (&gdtPtr); - - // - // Update selector (segment) registers base on new GDT - // - SetCodeSelector ((UINT16)CPU_CODE_SEL); - SetDataSelectors ((UINT16)CPU_DATA_SEL); -} - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S deleted file mode 100644 index 3b43b6fd8..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S +++ /dev/null @@ -1,365 +0,0 @@ -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
-#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* CpuAsm.S -#* -#* Abstract: -#* -#------------------------------------------------------------------------------ - - -#.MMX -#.XMM - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions - - -# -# point to the external interrupt vector table -# -ExternalVectorTablePtr: - .byte 0, 0, 0, 0 - -ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr) -ASM_PFX(InitializeExternalVectorTablePtr): - movl 4(%esp), %eax - movl %eax, ExternalVectorTablePtr - ret - -#------------------------------------------------------------------------------ -# VOID -# SetCodeSelector ( -# UINT16 Selector -# ); -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(SetCodeSelector) -ASM_PFX(SetCodeSelector): - movl 4(%esp), %ecx - subl $0x10, %esp - leal setCodeSelectorLongJump, %eax - movl %eax, (%esp) - movw %cx, 4(%esp) - .byte 0xFF, 0x2C, 0x24 # jmp *(%esp) note:(FWORD jmp) -setCodeSelectorLongJump: - addl $0x10, %esp - ret - -#------------------------------------------------------------------------------ -# VOID -# SetDataSelectors ( -# UINT16 Selector -# ); -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(SetDataSelectors) -ASM_PFX(SetDataSelectors): - movl 4(%esp), %ecx - movw %cx, %ss - movw %cx, %ds - movw %cx, %es - movw %cx, %fs - movw %cx, %gs - ret - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - - # - # Calculate vector number - # - # Get the return address of call, actually, it is the - # address of vector number. - # - xchgl (%esp), %ecx - movw (%ecx), %cx - andl $0x0FFFF, %ecx - cmpl $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - bt %ecx, ASM_PFX(mErrorCodeFlag) - jc HasErrorCode - -NoErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack - # - pushl %ecx - - # - # Put 0 (dummy) error code on stack, and restore ECX - # - xorl %ecx, %ecx # ECX = 0 - xchgl 4(%esp), %ecx - - jmp ErrorCodeAndVectorOnStack - -HasErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack and restore ECX - # - xchgl (%esp), %ecx - -ErrorCodeAndVectorOnStack: - pushl %ebp - movl %esp, %ebp - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + Vector Number + - # +---------------------+ - # + EBP + - # +---------------------+ <-- EBP - # - - # - # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 - # is 16-byte aligned - # - andl $0x0fffffff0, %esp - subl $12, %esp - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushl %eax - pushl %ecx - pushl %edx - pushl %ebx - leal 24(%ebp), %ecx - pushl %ecx # ESP - pushl (%ebp) # EBP - pushl %esi - pushl %edi - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; - movl %ss, %eax - pushl %eax - movzwl 16(%ebp), %eax - pushl %eax - movl %ds, %eax - pushl %eax - movl %es, %eax - pushl %eax - movl %fs, %eax - pushl %eax - movl %gs, %eax - pushl %eax - -#; UINT32 Eip; - movl 12(%ebp), %eax - pushl %eax - -#; UINT32 Gdtr[2], Idtr[2]; - subl $8, %esp - sidt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - - subl $8, %esp - sgdt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - -#; UINT32 Ldtr, Tr; - xorl %eax, %eax - str %ax - pushl %eax - sldt %ax - pushl %eax - -#; UINT32 EFlags; - movl 20(%ebp), %eax - pushl %eax - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - movl %cr4, %eax - orl $0x208, %eax - movl %eax, %cr4 - pushl %eax - movl %cr3, %eax - pushl %eax - movl %cr2, %eax - pushl %eax - xorl %eax, %eax - pushl %eax - movl %cr0, %eax - pushl %eax - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movl %dr7, %eax - pushl %eax - movl %dr6, %eax - pushl %eax - movl %dr3, %eax - pushl %eax - movl %dr2, %eax - pushl %eax - movl %dr1, %eax - pushl %eax - movl %dr0, %eax - pushl %eax - -#; FX_SAVE_STATE_IA32 FxSaveState; - subl $512, %esp - movl %esp, %edi - .byte 0x0f, 0x0ae, 0x07 #fxsave [edi] - -#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushl 8(%ebp) - -#; call into exception handler - movl ExternalVectorTablePtr, %eax # get the interrupt vectors base - orl %eax, %eax # NULL? - jz nullExternalExceptionHandler - - mov 4(%ebp), %ecx - movl (%eax,%ecx,4), %eax - orl %eax, %eax # NULL? - jz nullExternalExceptionHandler - -#; Prepare parameter and call - movl %esp, %edx - pushl %edx - movl 4(%ebp), %edx - pushl %edx - - # - # Call External Exception Handler - # - call *%eax - addl $8, %esp - -nullExternalExceptionHandler: - - cli -#; UINT32 ExceptionData; - addl $4, %esp - -#; FX_SAVE_STATE_IA32 FxSaveState; - movl %esp, %esi - .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi] - addl $512, %esp - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addl $24, %esp - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - popl %eax - movl %eax, %cr0 - addl $4, %esp # not for Cr1 - popl %eax - movl %eax, %cr2 - popl %eax - movl %eax, %cr3 - popl %eax - movl %eax, %cr4 - -#; UINT32 EFlags; - popl 20(%ebp) - -#; UINT32 Ldtr, Tr; -#; UINT32 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addl $24, %esp - -#; UINT32 Eip; - popl 12(%ebp) - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -#; NOTE - modified segment registers could hang the debugger... We -#; could attempt to insulate ourselves against this possibility, -#; but that poses risks as well. -#; - popl %gs - popl %fs - popl %es - popl %ds - popl 16(%ebp) - popl %ss - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popl %edi - popl %esi - addl $4, %esp # not for ebp - addl $4, %esp # not for esp - popl %ebx - popl %edx - popl %ecx - popl %eax - - movl %ebp, %esp - popl %ebp - addl $8, %esp - iretl - - -#END - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm b/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm deleted file mode 100644 index 0924dc5bb..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm +++ /dev/null @@ -1,363 +0,0 @@ - TITLE CpuAsm.asm: -;------------------------------------------------------------------------------ -;* -;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
-;* This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php -;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;* -;* CpuAsm.asm -;* -;* Abstract: -;* -;------------------------------------------------------------------------------ - - .686 - .model flat,C - .code - -EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions - -; -; point to the external interrupt vector table -; -ExternalVectorTablePtr DWORD 0 - -InitializeExternalVectorTablePtr PROC PUBLIC - mov eax, [esp+4] - mov ExternalVectorTablePtr, eax - ret -InitializeExternalVectorTablePtr ENDP - -;------------------------------------------------------------------------------ -; VOID -; SetCodeSelector ( -; UINT16 Selector -; ); -;------------------------------------------------------------------------------ -SetCodeSelector PROC PUBLIC - mov ecx, [esp+4] - sub esp, 0x10 - lea eax, setCodeSelectorLongJump - mov [esp], eax - mov [esp+4], cx - jmp fword ptr [esp] -setCodeSelectorLongJump: - add esp, 0x10 - ret -SetCodeSelector ENDP - -;------------------------------------------------------------------------------ -; VOID -; SetDataSelectors ( -; UINT16 Selector -; ); -;------------------------------------------------------------------------------ -SetDataSelectors PROC PUBLIC - mov ecx, [esp+4] - mov ss, cx - mov ds, cx - mov es, cx - mov fs, cx - mov gs, cx - ret -SetDataSelectors ENDP - -;---------------------------------------; -; CommonInterruptEntry ; -;---------------------------------------; -; The follow algorithm is used for the common interrupt routine. - -CommonInterruptEntry PROC PUBLIC - cli - ; - ; All interrupt handlers are invoked through interrupt gates, so - ; IF flag automatically cleared at the entry point - ; - - ; - ; Calculate vector number - ; - ; Get the return address of call, actually, it is the - ; address of vector number. - ; - xchg ecx, [esp] - mov cx, [ecx] - and ecx, 0FFFFh - cmp ecx, 32 ; Intel reserved vector for exceptions? - jae NoErrorCode - bt mErrorCodeFlag, ecx - jc HasErrorCode - -NoErrorCode: - - ; - ; Stack: - ; +---------------------+ - ; + EFlags + - ; +---------------------+ - ; + CS + - ; +---------------------+ - ; + EIP + - ; +---------------------+ - ; + ECX + - ; +---------------------+ <-- ESP - ; - ; Registers: - ; ECX - Vector Number - ; - - ; - ; Put Vector Number on stack - ; - push ecx - - ; - ; Put 0 (dummy) error code on stack, and restore ECX - ; - xor ecx, ecx ; ECX = 0 - xchg ecx, [esp+4] - - jmp ErrorCodeAndVectorOnStack - -HasErrorCode: - - ; - ; Stack: - ; +---------------------+ - ; + EFlags + - ; +---------------------+ - ; + CS + - ; +---------------------+ - ; + EIP + - ; +---------------------+ - ; + Error Code + - ; +---------------------+ - ; + ECX + - ; +---------------------+ <-- ESP - ; - ; Registers: - ; ECX - Vector Number - ; - - ; - ; Put Vector Number on stack and restore ECX - ; - xchg ecx, [esp] - -ErrorCodeAndVectorOnStack: - push ebp - mov ebp, esp - - ; - ; Stack: - ; +---------------------+ - ; + EFlags + - ; +---------------------+ - ; + CS + - ; +---------------------+ - ; + EIP + - ; +---------------------+ - ; + Error Code + - ; +---------------------+ - ; + Vector Number + - ; +---------------------+ - ; + EBP + - ; +---------------------+ <-- EBP - ; - - ; - ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 - ; is 16-byte aligned - ; - and esp, 0fffffff0h - sub esp, 12 - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - push eax - push ecx - push edx - push ebx - lea ecx, [ebp + 6 * 4] - push ecx ; ESP - push dword ptr [ebp] ; EBP - push esi - push edi - -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; - mov eax, ss - push eax - movzx eax, word ptr [ebp + 4 * 4] - push eax - mov eax, ds - push eax - mov eax, es - push eax - mov eax, fs - push eax - mov eax, gs - push eax - -;; UINT32 Eip; - mov eax, [ebp + 3 * 4] - push eax - -;; UINT32 Gdtr[2], Idtr[2]; - sub esp, 8 - sidt [esp] - mov eax, [esp + 2] - xchg eax, [esp] - and eax, 0FFFFh - mov [esp+4], eax - - sub esp, 8 - sgdt [esp] - mov eax, [esp + 2] - xchg eax, [esp] - and eax, 0FFFFh - mov [esp+4], eax - -;; UINT32 Ldtr, Tr; - xor eax, eax - str ax - push eax - sldt ax - push eax - -;; UINT32 EFlags; - mov eax, [ebp + 5 * 4] - push eax - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - mov eax, cr4 - or eax, 208h - mov cr4, eax - push eax - mov eax, cr3 - push eax - mov eax, cr2 - push eax - xor eax, eax - push eax - mov eax, cr0 - push eax - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov eax, dr7 - push eax - mov eax, dr6 - push eax - mov eax, dr3 - push eax - mov eax, dr2 - push eax - mov eax, dr1 - push eax - mov eax, dr0 - push eax - -;; FX_SAVE_STATE_IA32 FxSaveState; - sub esp, 512 - mov edi, esp - db 0fh, 0aeh, 07h ;fxsave [edi] - -;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -;; UINT32 ExceptionData; - push dword ptr [ebp + 2 * 4] - -;; call into exception handler - mov eax, ExternalVectorTablePtr ; get the interrupt vectors base - or eax, eax ; NULL? - jz nullExternalExceptionHandler - - mov ecx, [ebp + 4] - mov eax, [eax + ecx * 4] - or eax, eax ; NULL? - jz nullExternalExceptionHandler - -;; Prepare parameter and call - mov edx, esp - push edx - mov edx, dword ptr [ebp + 1 * 4] - push edx - - ; - ; Call External Exception Handler - ; - call eax - add esp, 8 - -nullExternalExceptionHandler: - - cli -;; UINT32 ExceptionData; - add esp, 4 - -;; FX_SAVE_STATE_IA32 FxSaveState; - mov esi, esp - db 0fh, 0aeh, 0eh ; fxrstor [esi] - add esp, 512 - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; Skip restoration of DRx registers to support in-circuit emualators -;; or debuggers set breakpoint in interrupt/exception context - add esp, 4 * 6 - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - pop eax - mov cr0, eax - add esp, 4 ; not for Cr1 - pop eax - mov cr2, eax - pop eax - mov cr3, eax - pop eax - mov cr4, eax - -;; UINT32 EFlags; - pop dword ptr [ebp + 5 * 4] - -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add esp, 24 - -;; UINT32 Eip; - pop dword ptr [ebp + 3 * 4] - -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -;; NOTE - modified segment registers could hang the debugger... We -;; could attempt to insulate ourselves against this possibility, -;; but that poses risks as well. -;; - pop gs - pop fs - pop es - pop ds - pop dword ptr [ebp + 4 * 4] - pop ss - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pop edi - pop esi - add esp, 4 ; not for ebp - add esp, 4 ; not for esp - pop ebx - pop edx - pop ecx - pop eax - - mov esp, ebp - pop ebp - add esp, 8 - iretd - -CommonInterruptEntry ENDP - -END diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S b/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S deleted file mode 100644 index c38461dc9..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S +++ /dev/null @@ -1,818 +0,0 @@ -#------------------------------------------------------------------------------ -# -# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# Module Name: -# -# IvtAsm.S -# -# Abstract: -# -# Interrupt Vector Table -# -#------------------------------------------------------------------------------ - -# -# Interrupt Vector Table -# - - -ASM_GLOBAL ASM_PFX(AsmIdtVector00) -.p2align 3 -ASM_PFX(AsmIdtVector00): - call ASM_PFX(CommonInterruptEntry) - .short 0x00 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x01 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x02 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x03 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x04 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x05 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x06 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x07 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x08 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x09 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x0f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x10 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x11 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x12 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x13 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x14 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x15 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x16 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x17 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x18 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x19 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x1f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x00 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x21 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x22 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x23 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x24 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x25 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x26 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x27 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x28 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x29 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x2f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x30 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x31 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x32 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x33 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x34 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x35 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x36 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x37 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x38 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x39 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x3f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x40 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x41 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x42 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x43 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x44 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x45 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x46 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x47 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x48 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x49 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x4f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x50 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x51 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x52 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x53 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x54 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x55 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x56 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x57 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x58 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x59 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x5f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x60 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x61 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x62 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x63 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x64 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x65 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x66 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x67 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x68 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x69 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x6f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x70 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x71 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x72 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x73 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x74 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x75 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x76 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x77 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x78 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x79 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x7f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x80 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x81 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x82 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x83 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x84 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x85 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x86 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x87 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x88 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x89 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x8f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0x90 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x91 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x92 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x93 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x94 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x95 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x96 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x97 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x98 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x99 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9a - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9b - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9c - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9d - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9e - nop - call ASM_PFX(CommonInterruptEntry) - .short 0x9f - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xa0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xa9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xaa - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xab - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xac - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xad - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xae - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xaf - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xb0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xb9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xba - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xbb - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xbc - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xbd - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xbe - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xbf - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xc0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xc9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xca - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xcb - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xcc - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xcd - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xce - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xcf - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xd0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xd9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xda - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xdb - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xdc - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xdd - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xde - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xdf - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xe0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xe9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xea - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xeb - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xec - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xed - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xee - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xef - nop - - call ASM_PFX(CommonInterruptEntry) - .short 0xf0 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf1 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf2 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf3 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf4 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf5 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf6 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf7 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf8 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xf9 - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xfa - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xfb - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xfc - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xfd - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xfe - nop - call ASM_PFX(CommonInterruptEntry) - .short 0xff - nop - -ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd) -ASM_PFX(AsmCommonIdtEnd): - .byte 0 - - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm b/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm deleted file mode 100644 index 02003c9fa..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm +++ /dev/null @@ -1,51 +0,0 @@ - TITLE IvtAsm.asm: -;------------------------------------------------------------------------------ -;* -;* Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-;* This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php -;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;* -;* IvtAsm.asm -;* -;* Abstract: -;* -;------------------------------------------------------------------------------ - -#include - -#ifdef MDE_CPU_IA32 - .686 - .model flat,C -#endif - .code - -;------------------------------------------------------------------------------ -; Generic IDT Vector Handlers for the Host. They are all the same so they -; will compress really well. -; -; By knowing the return address for Vector 00 you can can calculate the -; vector number by looking at the call CommonInterruptEntry return address. -; (return address - (AsmIdtVector00 + 5))/8 == IDT index -; -;------------------------------------------------------------------------------ - -EXTRN CommonInterruptEntry:PROC - -ALIGN 8 - -PUBLIC AsmIdtVector00 - -AsmIdtVector00 LABEL BYTE -REPEAT 256 - call CommonInterruptEntry - dw ($ - AsmIdtVector00 - 5) / 8 ; vector number - nop -ENDM - -END - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.S b/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.S deleted file mode 100644 index 3ea54090e..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.S +++ /dev/null @@ -1,346 +0,0 @@ -# TITLE CpuAsm.S: - -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
-#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* CpuAsm.S -#* -#* Abstract: -#* -#------------------------------------------------------------------------------ - - -#text SEGMENT - - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions - - -# -# point to the external interrupt vector table -# -ExternalVectorTablePtr: - .byte 0, 0, 0, 0, 0, 0, 0, 0 - -ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr) -ASM_PFX(InitializeExternalVectorTablePtr): - leaq ExternalVectorTablePtr(%rip), %rax # save vector number - movq %rcx, (%rax) - ret - - -#------------------------------------------------------------------------------ -# VOID -# SetCodeSelector ( -# UINT16 Selector -# ); -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(SetCodeSelector) -ASM_PFX(SetCodeSelector): - subq $0x14, %rsp - leaq L_setCodeSelectorLongJump(%rip), %rax - movq %rax, (%rsp) - movw %cx, 4(%rsp) - .byte 0x48, 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp -L_setCodeSelectorLongJump: - addq $0x14, %rsp - ret - -#------------------------------------------------------------------------------ -# VOID -# SetDataSelectors ( -# UINT16 Selector -# ); -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(SetDataSelectors) -ASM_PFX(SetDataSelectors): - movw %cx, %ss - movw %cx, %ds - movw %cx, %es - movw %cx, %fs - movw %cx, %gs - ret - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - # - # Calculate vector number - # - xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number. - movzwl (%rcx), %ecx - cmp $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - pushq %rax - leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax - bt %ecx, (%rax) - popq %rax - jc CommonInterruptEntry_al_0000 - -NoErrorCode: - - # - # Push a dummy error code on the stack - # to maintain coherent stack map - # - pushq (%rsp) - movq $0, 8(%rsp) -CommonInterruptEntry_al_0000: - pushq %rbp - movq %rsp, %rbp - - # - # Stack: - # +---------------------+ <-- 16-byte aligned ensured by processor - # + Old SS + - # +---------------------+ - # + Old RSP + - # +---------------------+ - # + RFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + RIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + RCX / Vector Number + - # +---------------------+ - # + RBP + - # +---------------------+ <-- RBP, 16-byte aligned - # - - - # - # Since here the stack pointer is 16-byte aligned, so - # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 - # is 16-byte aligned - # - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pushq %r15 - pushq %r14 - pushq %r13 - pushq %r12 - pushq %r11 - pushq %r10 - pushq %r9 - pushq %r8 - pushq %rax - pushq 8(%rbp) # RCX - pushq %rdx - pushq %rbx - pushq 48(%rbp) # RSP - pushq (%rbp) # RBP - pushq %rsi - pushq %rdi - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzwq 56(%rbp), %rax - pushq %rax # for ss - movzwq 32(%rbp), %rax - pushq %rax # for cs - movl %ds, %eax - pushq %rax - movl %es, %eax - pushq %rax - movl %fs, %eax - pushq %rax - movl %gs, %eax - pushq %rax - - movq %rcx, 8(%rbp) # save vector number - -#; UINT64 Rip; - pushq 24(%rbp) - -#; UINT64 Gdtr[2], Idtr[2]; - xorq %rax, %rax - pushq %rax - pushq %rax - sidt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - - xorq %rax, %rax - pushq %rax - pushq %rax - sgdt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - -#; UINT64 Ldtr, Tr; - xorq %rax, %rax - str %ax - pushq %rax - sldt %ax - pushq %rax - -#; UINT64 RFlags; - pushq 40(%rbp) - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - movq %cr8, %rax - pushq %rax - movq %cr4, %rax - orq $0x208, %rax - movq %rax, %cr4 - pushq %rax - mov %cr3, %rax - pushq %rax - mov %cr2, %rax - pushq %rax - xorq %rax, %rax - pushq %rax - mov %cr0, %rax - pushq %rax - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movq %dr7, %rax - pushq %rax - movq %dr6, %rax - pushq %rax - movq %dr3, %rax - pushq %rax - movq %dr2, %rax - pushq %rax - movq %dr1, %rax - pushq %rax - movq %dr0, %rax - pushq %rax - -#; FX_SAVE_STATE_X64 FxSaveState; - subq $512, %rsp - movq %rsp, %rdi - .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi] - -#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushq 16(%rbp) - -#; call into exception handler - movq 8(%rbp), %rcx - leaq ExternalVectorTablePtr(%rip), %rax -# movl (%eax), %eax - movq (%rax), %rax - movq (%rax,%rcx,8), %rax - orq %rax, %rax # NULL? - - je nonNullValue# - -#; Prepare parameter and call -# mov rcx, [rbp + 8] - mov %rsp, %rdx - # - # Per X64 calling convention, allocate maximum parameter stack space - # and make sure RSP is 16-byte aligned - # - subq $40, %rsp - call *%rax - addq $40, %rsp - -nonNullValue: - cli -#; UINT64 ExceptionData; - addq $8, %rsp - -#; FX_SAVE_STATE_X64 FxSaveState; - - movq %rsp, %rsi - .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi] - addq $512, %rsp - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addq $48, %rsp - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - popq %rax - movq %rax, %cr0 - addq $8, %rsp # not for Cr1 - popq %rax - movq %rax, %cr2 - popq %rax - movq %rax, %cr3 - popq %rax - movq %rax, %cr4 - popq %rax - movq %rax, %cr8 - -#; UINT64 RFlags; - popq 40(%rbp) - -#; UINT64 Ldtr, Tr; -#; UINT64 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addq $48, %rsp - -#; UINT64 Rip; - popq 24(%rbp) - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; - popq %rax - # mov %rax, %gs ; not for gs - popq %rax - # mov %rax, %fs ; not for fs - # (X64 will not use fs and gs, so we do not restore it) - popq %rax - movl %eax, %es - popq %rax - movl %eax, %ds - popq 32(%rbp) # for cs - popq 56(%rbp) # for ss - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - popq %rdi - popq %rsi - addq $8, %rsp # not for rbp - popq 48(%rbp) # for rsp - popq %rbx - popq %rdx - popq %rcx - popq %rax - popq %r8 - popq %r9 - popq %r10 - popq %r11 - popq %r12 - popq %r13 - popq %r14 - popq %r15 - - movq %rbp, %rsp - popq %rbp - addq $16, %rsp - iretq - - -#text ENDS - -#END - - diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm b/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm deleted file mode 100644 index 56955d37d..000000000 --- a/CloverEFI/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm +++ /dev/null @@ -1,337 +0,0 @@ - TITLE CpuAsm.asm: -;------------------------------------------------------------------------------ -;* -;* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
-;* This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php -;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;* -;* CpuAsm.asm -;* -;* Abstract: -;* -;------------------------------------------------------------------------------ - -.code - -EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions - -; -; point to the external interrupt vector table -; -ExternalVectorTablePtr QWORD 0 - -InitializeExternalVectorTablePtr PROC PUBLIC - mov ExternalVectorTablePtr, rcx - ret -InitializeExternalVectorTablePtr ENDP - -;------------------------------------------------------------------------------ -; VOID -; SetCodeSelector ( -; UINT16 Selector -; ); -;------------------------------------------------------------------------------ -SetCodeSelector PROC PUBLIC - sub rsp, 0x14 - lea rax, setCodeSelectorLongJump - mov [rsp], rax - mov [rsp+8], cx -;* I'm not sure how to encode this. We need to jmp [esp], where in esp there is -;* w16(selector):q64(address). -;* in gcc version this is encoded as 48 ff 2c 24 [ rex.W ljmpq (%esp) ] -;* but in VC jmp qword ptr [rsp] generates code ff 24 24 [ jmpq(%esp) ] -;* so I've just inserted db 0x48 to emit REX.W and get original 48 ff 2c 24 - db 0x48 - jmp fword ptr [rsp] -setCodeSelectorLongJump: - add rsp, 0x14 - ret -SetCodeSelector ENDP - -;------------------------------------------------------------------------------ -; VOID -; SetDataSelectors ( -; UINT16 Selector -; ); -;------------------------------------------------------------------------------ -SetDataSelectors PROC PUBLIC - mov ss, cx - mov ds, cx - mov es, cx - mov fs, cx - mov gs, cx - ret -SetDataSelectors ENDP - -;---------------------------------------; -; CommonInterruptEntry ; -;---------------------------------------; -; The follow algorithm is used for the common interrupt routine. - -CommonInterruptEntry PROC PUBLIC - cli - ; - ; All interrupt handlers are invoked through interrupt gates, so - ; IF flag automatically cleared at the entry point - ; - ; - ; Calculate vector number - ; - xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number. - movzx ecx, word ptr [rcx] - cmp ecx, 32 ; Intel reserved vector for exceptions? - jae NoErrorCode - bt mErrorCodeFlag, ecx - jc @F - -NoErrorCode: - - ; - ; Push a dummy error code on the stack - ; to maintain coherent stack map - ; - push [rsp] - mov qword ptr [rsp + 8], 0 -@@: - push rbp - mov rbp, rsp - - ; - ; Stack: - ; +---------------------+ <-- 16-byte aligned ensured by processor - ; + Old SS + - ; +---------------------+ - ; + Old RSP + - ; +---------------------+ - ; + RFlags + - ; +---------------------+ - ; + CS + - ; +---------------------+ - ; + RIP + - ; +---------------------+ - ; + Error Code + - ; +---------------------+ - ; + RCX / Vector Number + - ; +---------------------+ - ; + RBP + - ; +---------------------+ <-- RBP, 16-byte aligned - ; - - - ; - ; Since here the stack pointer is 16-byte aligned, so - ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 - ; is 16-byte aligned - ; - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rax - push qword ptr [rbp + 8] ; RCX - push rdx - push rbx - push qword ptr [rbp + 48] ; RSP - push qword ptr [rbp] ; RBP - push rsi - push rdi - -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzx rax, word ptr [rbp + 56] - push rax ; for ss - movzx rax, word ptr [rbp + 32] - push rax ; for cs - mov rax, ds - push rax - mov rax, es - push rax - mov rax, fs - push rax - mov rax, gs - push rax - - mov [rbp + 8], rcx ; save vector number - -;; UINT64 Rip; - push qword ptr [rbp + 24] - -;; UINT64 Gdtr[2], Idtr[2]; - xor rax, rax - push rax - push rax - sidt [rsp] - xchg rax, [rsp + 2] - xchg rax, [rsp] - xchg rax, [rsp + 8] - - xor rax, rax - push rax - push rax - sgdt [rsp] - xchg rax, [rsp + 2] - xchg rax, [rsp] - xchg rax, [rsp + 8] - -;; UINT64 Ldtr, Tr; - xor rax, rax - str ax - push rax - sldt ax - push rax - -;; UINT64 RFlags; - push qword ptr [rbp + 40] - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - mov rax, cr8 - push rax - mov rax, cr4 - or rax, 208h - mov cr4, rax - push rax - mov rax, cr3 - push rax - mov rax, cr2 - push rax - xor rax, rax - push rax - mov rax, cr0 - push rax - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov rax, dr7 - push rax - mov rax, dr6 - push rax - mov rax, dr3 - push rax - mov rax, dr2 - push rax - mov rax, dr1 - push rax - mov rax, dr0 - push rax - -;; FX_SAVE_STATE_X64 FxSaveState; - sub rsp, 512 - mov rdi, rsp - db 0fh, 0aeh, 07h ;fxsave [rdi] - -;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -;; UINT32 ExceptionData; - push qword ptr [rbp + 16] - -;; call into exception handler - mov rcx, [rbp + 8] - mov rax, ExternalVectorTablePtr ; get the interrupt vectors base - mov rax, [rax + rcx * 8] - or rax, rax ; NULL? - - je nonNullValue; - -;; Prepare parameter and call -; mov rcx, [rbp + 8] - mov rdx, rsp - ; - ; Per X64 calling convention, allocate maximum parameter stack space - ; and make sure RSP is 16-byte aligned - ; - sub rsp, 4 * 8 + 8 - call rax - add rsp, 4 * 8 + 8 - -nonNullValue: - cli -;; UINT64 ExceptionData; - add rsp, 8 - -;; FX_SAVE_STATE_X64 FxSaveState; - - mov rsi, rsp - db 0fh, 0aeh, 0Eh ; fxrstor [rsi] - add rsp, 512 - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; Skip restoration of DRx registers to support in-circuit emualators -;; or debuggers set breakpoint in interrupt/exception context - add rsp, 8 * 6 - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - pop rax - mov cr0, rax - add rsp, 8 ; not for Cr1 - pop rax - mov cr2, rax - pop rax - mov cr3, rax - pop rax - mov cr4, rax - pop rax - mov cr8, rax - -;; UINT64 RFlags; - pop qword ptr [rbp + 40] - -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add rsp, 48 - -;; UINT64 Rip; - pop qword ptr [rbp + 24] - -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; - pop rax - ; mov gs, rax ; not for gs - pop rax - ; mov fs, rax ; not for fs - ; (X64 will not use fs and gs, so we do not restore it) - pop rax - mov es, rax - pop rax - mov ds, rax - pop qword ptr [rbp + 32] ; for cs - pop qword ptr [rbp + 56] ; for ss - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - add rsp, 8 ; not for rbp - pop qword ptr [rbp + 48] ; for rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - - mov rsp, rbp - pop rbp - add rsp, 16 - iretq - -CommonInterruptEntry ENDP - -END - diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf b/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf deleted file mode 100644 index 3abf2677f..000000000 --- a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf +++ /dev/null @@ -1,54 +0,0 @@ -## @file -# Produces the CPU I/O 2 Protocol. -# -# This DXE driver produces of the CPU I/O 2 Protocol, as introduced by PI 1.2. -# -# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = CpuIo2Dxe - FILE_GUID = A19B1FE7-C1BC-49F8-875F-54A5D542443F - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = CpuIo2Initialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - CpuIo2Dxe.c - CpuIo2Dxe.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - DebugLib - IoLib - UefiBootServicesTableLib - -[Protocols] - gEfiCpuIo2ProtocolGuid ## PRODUCES - -[Depex] - TRUE - -[BuildOptions] - XCODE:*_*_*_CC_FLAGS = -Os -DMDEPKG_NDEBUG - GCC:*_*_*_CC_FLAGS = -O0 -DMDEPKG_NDEBUG - MSFT:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf b/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf deleted file mode 100644 index e77b61f65..000000000 --- a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf +++ /dev/null @@ -1,48 +0,0 @@ -## @file -# Module that produces the SMM CPU I/O 2 Protocol using the services of the I/O Library -# -# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = CpuIo2Smm - FILE_GUID = A47EE2D8-F60E-42fd-8E58-7BD65EE4C29B - MODULE_TYPE = DXE_SMM_DRIVER - VERSION_STRING = 1.0 - PI_SPECIFICATION_VERSION = 0x0001000A - ENTRY_POINT = SmmCpuIo2Initialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - CpuIo2Smm.c - CpuIo2Smm.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - DebugLib - IoLib - SmmServicesTableLib - BaseMemoryLib - -[Protocols] - gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - -[Depex] - TRUE diff --git a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.inf b/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.inf deleted file mode 100644 index 4ebd9e2fb..000000000 --- a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.inf +++ /dev/null @@ -1,49 +0,0 @@ -## @file -# Produces the CPU I/O PPI. -# -# This PEIM produces of the CPU I/O PPI. -# -# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = CpuIoPei - FILE_GUID = AE265864-CF5D-41a8-913D-71C155E76442 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - ENTRY_POINT = CpuIoInitialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - CpuIoPei.c - CpuIoPei.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - PeimEntryPoint - BaseLib - DebugLib - IoLib - PeiServicesLib - -[Ppis] - gEfiPeiCpuIoPpiInstalledGuid # PPI ALWAYS_PRODUCED - -[Depex] - TRUE diff --git a/CloverEFI/UefiCpuPkg/Include/Library/MtrrLib.h b/CloverEFI/UefiCpuPkg/Include/Library/MtrrLib.h deleted file mode 100644 index d24f10f36..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Library/MtrrLib.h +++ /dev/null @@ -1,334 +0,0 @@ -/** @file - MTRR setting library - - Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _MTRR_LIB_H_ -#define _MTRR_LIB_H_ - -// -// According to IA32 SDM, MTRRs number and msr offset are always consistent -// for IA32 processor family -// - -// -// The semantics of below macro is MAX_MTRR_NUMBER_OF_VARIABLE_MTRR, the real number can be read out from MTRR_CAP register. -// -#define MTRR_NUMBER_OF_VARIABLE_MTRR 32 -// -// Firmware need reserve 2 MTRR for OS -// -#define RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER 2 - -#define MTRR_NUMBER_OF_FIXED_MTRR 11 -// -// Below macro is deprecated, and should not be used. -// -#define FIRMWARE_VARIABLE_MTRR_NUMBER 6 -#define MTRR_LIB_IA32_MTRR_CAP 0x0FE -#define MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK 0x0FF -#define MTRR_LIB_IA32_MTRR_FIX64K_00000 0x250 -#define MTRR_LIB_IA32_MTRR_FIX16K_80000 0x258 -#define MTRR_LIB_IA32_MTRR_FIX16K_A0000 0x259 -#define MTRR_LIB_IA32_MTRR_FIX4K_C0000 0x268 -#define MTRR_LIB_IA32_MTRR_FIX4K_C8000 0x269 -#define MTRR_LIB_IA32_MTRR_FIX4K_D0000 0x26A -#define MTRR_LIB_IA32_MTRR_FIX4K_D8000 0x26B -#define MTRR_LIB_IA32_MTRR_FIX4K_E0000 0x26C -#define MTRR_LIB_IA32_MTRR_FIX4K_E8000 0x26D -#define MTRR_LIB_IA32_MTRR_FIX4K_F0000 0x26E -#define MTRR_LIB_IA32_MTRR_FIX4K_F8000 0x26F -#define MTRR_LIB_IA32_VARIABLE_MTRR_BASE 0x200 -// -// Below macro is deprecated, and should not be used. -// -#define MTRR_LIB_IA32_VARIABLE_MTRR_END 0x20F -#define MTRR_LIB_IA32_MTRR_DEF_TYPE 0x2FF -#define MTRR_LIB_MSR_VALID_MASK 0xFFFFFFFFFULL -#define MTRR_LIB_CACHE_VALID_ADDRESS 0xFFFFFF000ULL -#define MTRR_LIB_CACHE_MTRR_ENABLED 0x800 -#define MTRR_LIB_CACHE_FIXED_MTRR_ENABLED 0x400 - -// -// Structure to describe a fixed MTRR -// -typedef struct { - UINT32 Msr; - UINT32 BaseAddress; - UINT32 Length; -} FIXED_MTRR; - -// -// Structure to describe a variable MTRR -// -typedef struct { - UINT64 BaseAddress; - UINT64 Length; - UINT64 Type; - UINT32 Msr; - BOOLEAN Valid; - BOOLEAN Used; -} VARIABLE_MTRR; - -// -// Structure to hold base and mask pair for variable MTRR register -// -typedef struct _MTRR_VARIABLE_SETTING_ { - UINT64 Base; - UINT64 Mask; -} MTRR_VARIABLE_SETTING; - -// -// Array for variable MTRRs -// -typedef struct _MTRR_VARIABLE_SETTINGS_ { - MTRR_VARIABLE_SETTING Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; -} MTRR_VARIABLE_SETTINGS; - -// -// Array for fixed mtrrs -// -typedef struct _MTRR_FIXED_SETTINGS_ { - UINT64 Mtrr[MTRR_NUMBER_OF_FIXED_MTRR]; -} MTRR_FIXED_SETTINGS; - -// -// Structure to hold all MTRRs -// -typedef struct _MTRR_SETTINGS_ { - MTRR_FIXED_SETTINGS Fixed; - MTRR_VARIABLE_SETTINGS Variables; - UINT64 MtrrDefType; -} MTRR_SETTINGS; - -// -// Memory cache types -// -typedef enum { - CacheUncacheable = 0, - CacheWriteCombining = 1, - CacheWriteThrough = 4, - CacheWriteProtected = 5, - CacheWriteBack = 6 -} MTRR_MEMORY_CACHE_TYPE; - -#define MTRR_CACHE_UNCACHEABLE 0 -#define MTRR_CACHE_WRITE_COMBINING 1 -#define MTRR_CACHE_WRITE_THROUGH 4 -#define MTRR_CACHE_WRITE_PROTECTED 5 -#define MTRR_CACHE_WRITE_BACK 6 -#define MTRR_CACHE_INVALID_TYPE 7 - -/** - Returns the variable MTRR count for the CPU. - - @return Variable MTRR count - -**/ -UINT32 -EFIAPI -GetVariableMtrrCount ( - VOID - ); - -/** - Returns the firmware usable variable MTRR count for the CPU. - - @return Firmware usable variable MTRR count - -**/ -UINT32 -EFIAPI -GetFirmwareVariableMtrrCount ( - VOID - ); - -/** - This function attempts to set the attributes for a memory range. - - @param BaseAddress The physical address that is the start address of a memory region. - @param Length The size in bytes of the memory region. - @param Attributes The bit mask of attributes to set for the memory region. - - @retval RETURN_SUCCESS The attributes were set for the memory region. - @retval RETURN_INVALID_PARAMETER Length is zero. - @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the - memory resource range specified by BaseAddress and Length. - @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource - range specified by BaseAddress and Length. - @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by - BaseAddress and Length cannot be modified. - @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of - the memory resource range. - -**/ -RETURN_STATUS -EFIAPI -MtrrSetMemoryAttribute ( - IN PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN MTRR_MEMORY_CACHE_TYPE Attribute - ); - - -/** - This function will get the memory cache type of the specific address. - This function is mainly for debugging purposes. - - @param Address The specific address - - @return The memory cache type of the specific address - -**/ -MTRR_MEMORY_CACHE_TYPE -EFIAPI -MtrrGetMemoryAttribute ( - IN PHYSICAL_ADDRESS Address - ); - - -/** - This function will get the raw value in variable MTRRs - - @param VariableSettings A buffer to hold variable MTRRs content. - - @return The buffer point to MTRR_VARIABLE_SETTINGS in which holds the content of the variable mtrr - -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrGetVariableMtrr ( - OUT MTRR_VARIABLE_SETTINGS *VariableSettings - ); - - -/** - This function sets fixed MTRRs - - @param VariableSettings A buffer to hold variable MTRRs content. - - @return The pointer of VariableSettings - -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrSetVariableMtrr ( - IN MTRR_VARIABLE_SETTINGS *VariableSettings - ); - - -/** - This function gets the content in fixed MTRRs - - @param FixedSettings A buffer to hold fixed MTRRs content. - - @return The pointer of FixedSettings - -**/ -MTRR_FIXED_SETTINGS* -EFIAPI -MtrrGetFixedMtrr ( - OUT MTRR_FIXED_SETTINGS *FixedSettings - ); - - -/** - This function sets fixed MTRRs - - @param FixedSettings A buffer holding fixed MTRRs content. - - @return The pointer of FixedSettings - -**/ -MTRR_FIXED_SETTINGS* -EFIAPI -MtrrSetFixedMtrr ( - IN MTRR_FIXED_SETTINGS *FixedSettings - ); - - -/** - This function gets the content in all MTRRs (variable and fixed) - - @param MtrrSetting A buffer to hold all MTRRs content. - - @return The pointer of MtrrSetting - -**/ -MTRR_SETTINGS * -EFIAPI -MtrrGetAllMtrrs ( - OUT MTRR_SETTINGS *MtrrSetting - ); - - -/** - This function sets all MTRRs (variable and fixed) - - @param MtrrSetting A buffer to hold all MTRRs content. - - @return The pointer of MtrrSetting - -**/ -MTRR_SETTINGS * -EFIAPI -MtrrSetAllMtrrs ( - IN MTRR_SETTINGS *MtrrSetting - ); - - -/** - Get the attribute of variable MTRRs. - - This function shadows the content of variable MTRRs into - an internal array: VariableMtrr - - @param MtrrValidBitsMask The mask for the valid bit of the MTRR - @param MtrrValidAddressMask The valid address mask for MTRR since the base address in - MTRR must align to 4K, so valid address mask equal to - MtrrValidBitsMask & 0xfffffffffffff000ULL - @param VariableMtrr The array to shadow variable MTRRs content - @return The ruturn value of this paramter indicates the number of - MTRRs which has been used. -**/ -UINT32 -EFIAPI -MtrrGetMemoryAttributeInVariableMtrr ( - IN UINT64 MtrrValidBitsMask, - IN UINT64 MtrrValidAddressMask, - OUT VARIABLE_MTRR *VariableMtrr - ); - - -/** - This function prints all MTRRs for debugging. -**/ -VOID -EFIAPI -MtrrDebugPrintAllMtrrs ( - VOID - ); - -/** - Checks if MTRR is supported. - - @retval TRUE MTRR is supported. - @retval FALSE MTRR is not supported. - -**/ -BOOLEAN -EFIAPI -IsMtrrSupported ( - VOID - ); - -#endif // _MTRR_LIB_H_ diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Cpuid.h b/CloverEFI/UefiCpuPkg/Include/Register/Amd/Cpuid.h deleted file mode 100644 index e262bfcf3..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Cpuid.h +++ /dev/null @@ -1,743 +0,0 @@ -/** @file - CPUID leaf definitions. - - Provides defines for CPUID leaf indexes. Data structures are provided for - registers returned by a CPUID leaf that contain one or more bit fields. - If a register returned is a single 32-bit value, then a data structure is - not provided for that register. - - Copyright (c) 2017, Advanced Micro Devices. All rights reserved.
- - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - AMD64 Architecture Programming Manaul volume 2, March 2017, Sections 15.34 - -**/ - -#ifndef __AMD_CPUID_H__ -#define __AMD_CPUID_H__ - -/** -CPUID Signature Information - -@param EAX CPUID_SIGNATURE (0x00) - -@retval EAX Returns the highest value the CPUID instruction recognizes for - returning basic processor information. The value is returned is - processor specific. -@retval EBX First 4 characters of a vendor identification string. -@retval ECX Last 4 characters of a vendor identification string. -@retval EDX Middle 4 characters of a vendor identification string. - -**/ - -/// -/// @{ CPUID signature values returned by AMD processors -/// -#define CPUID_SIGNATURE_AUTHENTIC_AMD_EBX SIGNATURE_32 ('A', 'u', 't', 'h') -#define CPUID_SIGNATURE_AUTHENTIC_AMD_EDX SIGNATURE_32 ('e', 'n', 't', 'i') -#define CPUID_SIGNATURE_AUTHENTIC_AMD_ECX SIGNATURE_32 ('c', 'A', 'M', 'D') -/// -/// @} -/// - - -/** - CPUID Extended Processor Signature and Features - - @param EAX CPUID_EXTENDED_CPU_SIG (0x80000001) - - @retval EAX Extended Family, Model, Stepping Identifiers - described by the type CPUID_AMD_EXTENDED_CPU_SIG_EAX. - @retval EBX Brand Identifier - described by the type CPUID_AMD_EXTENDED_CPU_SIG_EBX. - @retval ECX Extended Feature Identifiers - described by the type CPUID_AMD_EXTENDED_CPU_SIG_ECX. - @retval EDX Extended Feature Identifiers - described by the type CPUID_AMD_EXTENDED_CPU_SIG_EDX. -**/ - -/** - CPUID Extended Processor Signature and Features EAX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Stepping. - /// - UINT32 Stepping:4; - /// - /// [Bits 7:4] Base Model. - /// - UINT32 BaseModel:4; - /// - /// [Bits 11:8] Base Family. - /// - UINT32 BaseFamily:4; - /// - /// [Bit 15:12] Reserved. - /// - UINT32 Reserved1:4; - /// - /// [Bits 19:16] Extended Model. - /// - UINT32 ExtModel:4; - /// - /// [Bits 27:20] Extended Family. - /// - UINT32 ExtFamily:8; - /// - /// [Bit 31:28] Reserved. - /// - UINT32 Reserved2:4; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_EXTENDED_CPU_SIG_EAX; - -/** - CPUID Extended Processor Signature and Features EBX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 27:0] Reserved. - /// - UINT32 Reserved:28; - /// - /// [Bit 31:28] Package Type. - /// - UINT32 PkgType:4; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_EXTENDED_CPU_SIG_EBX; - -/** - CPUID Extended Processor Signature and Features ECX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LAHF/SAHF available in 64-bit mode. - /// - UINT32 LAHF_SAHF:1; - /// - /// [Bit 1] Core multi-processing legacy mode. - /// - UINT32 CmpLegacy:1; - /// - /// [Bit 2] Secure Virtual Mode feature. - /// - UINT32 SVM:1; - /// - /// [Bit 3] Extended APIC register space. - /// - UINT32 ExtApicSpace:1; - /// - /// [Bit 4] LOCK MOV CR0 means MOV CR8. - /// - UINT32 AltMovCr8:1; - /// - /// [Bit 5] LZCNT instruction support. - /// - UINT32 LZCNT:1; - /// - /// [Bit 6] SSE4A instruction support. - /// - UINT32 SSE4A:1; - /// - /// [Bit 7] Misaligned SSE Mode. - /// - UINT32 MisAlignSse:1; - /// - /// [Bit 8] ThreeDNow Prefetch instructions. - /// - UINT32 PREFETCHW:1; - /// - /// [Bit 9] OS Visible Work-around support. - /// - UINT32 OSVW:1; - /// - /// [Bit 10] Instruction Based Sampling. - /// - UINT32 IBS:1; - /// - /// [Bit 11] Extended Operation Support. - /// - UINT32 XOP:1; - /// - /// [Bit 12] SKINIT and STGI support. - /// - UINT32 SKINIT:1; - /// - /// [Bit 13] Watchdog Timer support. - /// - UINT32 WDT:1; - /// - /// [Bit 14] Reserved. - /// - UINT32 Reserved1:1; - /// - /// [Bit 15] Lightweight Profiling support. - /// - UINT32 LWP:1; - /// - /// [Bit 16] 4-Operand FMA instruction support. - /// - UINT32 FMA4:1; - /// - /// [Bit 17] Translation Cache Extension. - /// - UINT32 TCE:1; - /// - /// [Bit 21:18] Reserved. - /// - UINT32 Reserved2:4; - /// - /// [Bit 22] Topology Extensions support. - /// - UINT32 TopologyExtensions:1; - /// - /// [Bit 23] Core Performance Counter Extensions. - /// - UINT32 PerfCtrExtCore:1; - /// - /// [Bit 25:24] Reserved. - /// - UINT32 Reserved3:2; - /// - /// [Bit 26] Data Breakpoint Extension. - /// - UINT32 DataBreakpointExtension:1; - /// - /// [Bit 27] Performance Time-Stamp Counter. - /// - UINT32 PerfTsc:1; - /// - /// [Bit 28] L3 Performance Counter Extensions. - /// - UINT32 PerfCtrExtL3:1; - /// - /// [Bit 29] MWAITX and MONITORX capability. - /// - UINT32 MwaitExtended:1; - /// - /// [Bit 31:30] Reserved. - /// - UINT32 Reserved4:2; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_EXTENDED_CPU_SIG_ECX; - -/** - CPUID Extended Processor Signature and Features EDX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] x87 floating point unit on-chip. - /// - UINT32 FPU:1; - /// - /// [Bit 1] Virtual-mode enhancements. - /// - UINT32 VME:1; - /// - /// [Bit 2] Debugging extensions, IO breakpoints, CR4.DE. - /// - UINT32 DE:1; - /// - /// [Bit 3] Page-size extensions (4 MB pages). - /// - UINT32 PSE:1; - /// - /// [Bit 4] Time stamp counter, RDTSC/RDTSCP instructions, CR4.TSD. - /// - UINT32 TSC:1; - /// - /// [Bit 5] MSRs, with RDMSR and WRMSR instructions. - /// - UINT32 MSR:1; - /// - /// [Bit 6] Physical-address extensions (PAE). - /// - UINT32 PAE:1; - /// - /// [Bit 7] Machine check exception, CR4.MCE. - /// - UINT32 MCE:1; - /// - /// [Bit 8] CMPXCHG8B instruction. - /// - UINT32 CMPXCHG8B:1; - /// - /// [Bit 9] APIC exists and is enabled. - /// - UINT32 APIC:1; - /// - /// [Bit 10] Reserved. - /// - UINT32 Reserved1:1; - /// - /// [Bit 11] SYSCALL and SYSRET instructions. - /// - UINT32 SYSCALL_SYSRET:1; - /// - /// [Bit 12] Memory-type range registers. - /// - UINT32 MTRR:1; - /// - /// [Bit 13] Page global extension, CR4.PGE. - /// - UINT32 PGE:1; - /// - /// [Bit 14] Machine check architecture, MCG_CAP. - /// - UINT32 MCA:1; - /// - /// [Bit 15] Conditional move instructions, CMOV, FCOMI, FCMOV. - /// - UINT32 CMOV:1; - /// - /// [Bit 16] Page attribute table. - /// - UINT32 PAT:1; - /// - /// [Bit 17] Page-size extensions. - /// - UINT32 PSE36 : 1; - /// - /// [Bit 19:18] Reserved. - /// - UINT32 Reserved2:2; - /// - /// [Bit 20] No-execute page protection. - /// - UINT32 NX:1; - /// - /// [Bit 21] Reserved. - /// - UINT32 Reserved3:1; - /// - /// [Bit 22] AMD Extensions to MMX instructions. - /// - UINT32 MmxExt:1; - /// - /// [Bit 23] MMX instructions. - /// - UINT32 MMX:1; - /// - /// [Bit 24] FXSAVE and FXRSTOR instructions. - /// - UINT32 FFSR:1; - /// - /// [Bit 25] FXSAVE and FXRSTOR instruction optimizations. - /// - UINT32 FFXSR:1; - /// - /// [Bit 26] 1-GByte large page support. - /// - UINT32 Page1GB:1; - /// - /// [Bit 27] RDTSCP intructions. - /// - UINT32 RDTSCP:1; - /// - /// [Bit 28] Reserved. - /// - UINT32 Reserved4:1; - /// - /// [Bit 29] Long Mode. - /// - UINT32 LM:1; - /// - /// [Bit 30] 3DNow! instructions. - /// - UINT32 ThreeDNow:1; - /// - /// [Bit 31] AMD Extensions to 3DNow! instructions. - /// - UINT32 ThreeDNowExt:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_EXTENDED_CPU_SIG_EDX; - - -/** -CPUID Linear Physical Address Size - -@param EAX CPUID_VIR_PHY_ADDRESS_SIZE (0x80000008) - -@retval EAX Linear/Physical Address Size described by the type - CPUID_AMD_VIR_PHY_ADDRESS_SIZE_EAX. -@retval EBX Linear/Physical Address Size described by the type - CPUID_AMD_VIR_PHY_ADDRESS_SIZE_EBX. -@retval ECX Linear/Physical Address Size described by the type - CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX. -@retval EDX Reserved. -**/ - -/** - CPUID Linear Physical Address Size EAX for CPUID leaf - #CPUID_VIR_PHY_ADDRESS_SIZE. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Maximum physical byte address size in bits. - /// - UINT32 PhysicalAddressBits:8; - /// - /// [Bits 15:8] Maximum linear byte address size in bits. - /// - UINT32 LinearAddressBits:8; - /// - /// [Bits 23:16] Maximum guest physical byte address size in bits. - /// - UINT32 GuestPhysAddrSize:8; - /// - /// [Bit 31:24] Reserved. - /// - UINT32 Reserved:8; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_VIR_PHY_ADDRESS_SIZE_EAX; - -/** - CPUID Linear Physical Address Size EBX for CPUID leaf - #CPUID_VIR_PHY_ADDRESS_SIZE. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 0] Clear Zero Instruction. - /// - UINT32 CLZERO:1; - /// - /// [Bits 1] Instructions retired count support. - /// - UINT32 IRPerf:1; - /// - /// [Bits 2] Restore error pointers for XSave instructions. - /// - UINT32 XSaveErPtr:1; - /// - /// [Bit 31:3] Reserved. - /// - UINT32 Reserved:29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_VIR_PHY_ADDRESS_SIZE_EBX; - -/** - CPUID Linear Physical Address Size ECX for CPUID leaf - #CPUID_VIR_PHY_ADDRESS_SIZE. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Number of threads - 1. - /// - UINT32 NC:8; - /// - /// [Bit 11:8] Reserved. - /// - UINT32 Reserved1:4; - /// - /// [Bits 15:12] APIC ID size. - /// - UINT32 ApicIdCoreIdSize:4; - /// - /// [Bits 17:16] Performance time-stamp counter size. - /// - UINT32 PerfTscSize:2; - /// - /// [Bit 31:18] Reserved. - /// - UINT32 Reserved2:14; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX; - - -/** - CPUID AMD Processor Topology - - @param EAX CPUID_AMD_PROCESSOR_TOPOLOGY (0x8000001E) - - @retval EAX Extended APIC ID described by the type - CPUID_AMD_PROCESSOR_TOPOLOGY_EAX. - @retval EBX Core Indentifiers described by the type - CPUID_AMD_PROCESSOR_TOPOLOGY_EBX. - @retval ECX Node Indentifiers described by the type - CPUID_AMD_PROCESSOR_TOPOLOGY_ECX. - @retval EDX Reserved. -**/ -#define CPUID_AMD_PROCESSOR_TOPOLOGY 0x8000001E - -/** - CPUID AMD Processor Topology EAX for CPUID leaf - #CPUID_AMD_PROCESSOR_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 31:0] Extended APIC Id. - /// - UINT32 ExtendedApicId; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_PROCESSOR_TOPOLOGY_EAX; - -/** - CPUID AMD Processor Topology EBX for CPUID leaf - #CPUID_AMD_PROCESSOR_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Core Id. - /// - UINT32 CoreId:8; - /// - /// [Bits 15:8] Threads per core. - /// - UINT32 ThreadsPerCore:8; - /// - /// [Bit 31:16] Reserved. - /// - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_PROCESSOR_TOPOLOGY_EBX; - -/** - CPUID AMD Processor Topology ECX for CPUID leaf - #CPUID_AMD_PROCESSOR_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Node Id. - /// - UINT32 NodeId:8; - /// - /// [Bits 10:8] Nodes per processor. - /// - UINT32 NodesPerProcessor:3; - /// - /// [Bit 31:11] Reserved. - /// - UINT32 Reserved:21; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_AMD_PROCESSOR_TOPOLOGY_ECX; - - -/** - CPUID Memory Encryption Information - - @param EAX CPUID_MEMORY_ENCRYPTION_INFO (0x8000001F) - - @retval EAX Returns the memory encryption feature support status. - @retval EBX If memory encryption feature is present then return - the page table bit number used to enable memory encryption support - and reducing of physical address space in bits. - @retval ECX Returns number of encrypted guest supported simultaneously. - @retval EDX Returns minimum SEV enabled and SEV disabled ASID. - - Example usage - @code - UINT32 Eax; - UINT32 Ebx; - UINT32 Ecx; - UINT32 Edx; - - AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax, &Ebx, &Ecx, &Edx); - @endcode -**/ - -#define CPUID_MEMORY_ENCRYPTION_INFO 0x8000001F - -/** - CPUID Memory Encryption support information EAX for CPUID leaf - #CPUID_MEMORY_ENCRYPTION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Secure Memory Encryption (Sme) Support - /// - UINT32 SmeBit:1; - - /// - /// [Bit 1] Secure Encrypted Virtualization (Sev) Support - /// - UINT32 SevBit:1; - - /// - /// [Bit 2] Page flush MSR support - /// - UINT32 PageFlushMsrBit:1; - - /// - /// [Bit 3] Encrypted state support - /// - UINT32 SevEsBit:1; - - /// - /// [Bit 31:4] Reserved - /// - UINT32 ReservedBits:28; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MEMORY_ENCRYPTION_INFO_EAX; - -/** - CPUID Memory Encryption support information EBX for CPUID leaf - #CPUID_MEMORY_ENCRYPTION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 5:0] Page table bit number used to enable memory encryption - /// - UINT32 PtePosBits:6; - - /// - /// [Bit 11:6] Reduction of system physical address space bits when - /// memory encryption is enabled - /// - UINT32 ReducedPhysBits:5; - - /// - /// [Bit 31:12] Reserved - /// - UINT32 ReservedBits:21; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MEMORY_ENCRYPTION_INFO_EBX; - -/** - CPUID Memory Encryption support information ECX for CPUID leaf - #CPUID_MEMORY_ENCRYPTION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 31:0] Number of encrypted guest supported simultaneously - /// - UINT32 NumGuests; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MEMORY_ENCRYPTION_INFO_ECX; - -/** - CPUID Memory Encryption support information EDX for CPUID leaf - #CPUID_MEMORY_ENCRYPTION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 31:0] Minimum SEV enabled, SEV-ES disabled ASID - /// - UINT32 MinAsid; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MEMORY_ENCRYPTION_INFO_EDX; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Fam17Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Amd/Fam17Msr.h deleted file mode 100644 index 9a79de1e9..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Fam17Msr.h +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - MSR Definitions. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2017, Advanced Micro Devices. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - AMD64 Architecture Programming Manaul volume 2, March 2017, Sections 15.34 - -**/ - -#ifndef __FAM17_MSR_H__ -#define __FAM17_MSR_H__ - -/** - Secure Encrypted Virtualization (SEV) status register - -**/ -#define MSR_SEV_STATUS 0xc0010131 - -/** - MSR information returned for #MSR_SEV_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled - /// - UINT32 SevBit:1; - - /// - /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled - /// - UINT32 SevEsBit:1; - - UINT32 Reserved:30; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SEV_STATUS_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Amd/Msr.h deleted file mode 100644 index bde830feb..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Amd/Msr.h +++ /dev/null @@ -1,29 +0,0 @@ -/** @file - MSR Definitions. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2017, Advanced Micro Devices. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - AMD64 Architecture Programming Manaul volume 2, March 2017, Sections 15.34 - -**/ - -#ifndef __AMD_MSR_H__ -#define __AMD_MSR_H__ - -#include -#include - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/ArchitecturalMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/ArchitecturalMsr.h deleted file mode 100644 index 34fdf5be3..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/ArchitecturalMsr.h +++ /dev/null @@ -1,6518 +0,0 @@ -/** @file - Architectural MSR Definitions. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.1. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Appendix A VMX Capability Reporting Facility, Section A.1. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Appendix A VMX Capability Reporting Facility, Section A.6. - -**/ - -#ifndef __ARCHITECTURAL_MSR_H__ -#define __ARCHITECTURAL_MSR_H__ - -/** - See Section 35.22, "MSRs in Pentium Processors.". Pentium Processor (05_01H). - - @param ECX MSR_IA32_P5_MC_ADDR (0x00000000) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_P5_MC_ADDR); - AsmWriteMsr64 (MSR_IA32_P5_MC_ADDR, Msr); - @endcode - @note MSR_IA32_P5_MC_ADDR is defined as IA32_P5_MC_ADDR in SDM. -**/ -#define MSR_IA32_P5_MC_ADDR 0x00000000 - - -/** - See Section 35.22, "MSRs in Pentium Processors.". DF_DM = 05_01H. - - @param ECX MSR_IA32_P5_MC_TYPE (0x00000001) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_P5_MC_TYPE); - AsmWriteMsr64 (MSR_IA32_P5_MC_TYPE, Msr); - @endcode - @note MSR_IA32_P5_MC_TYPE is defined as IA32_P5_MC_TYPE in SDM. -**/ -#define MSR_IA32_P5_MC_TYPE 0x00000001 - - -/** - See Section 8.10.5, "Monitor/Mwait Address Range Determination.". Introduced - at Display Family / Display Model 0F_03H. - - @param ECX MSR_IA32_MONITOR_FILTER_SIZE (0x00000006) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MONITOR_FILTER_SIZE); - AsmWriteMsr64 (MSR_IA32_MONITOR_FILTER_SIZE, Msr); - @endcode - @note MSR_IA32_MONITOR_FILTER_SIZE is defined as IA32_MONITOR_FILTER_SIZE in SDM. -**/ -#define MSR_IA32_MONITOR_FILTER_SIZE 0x00000006 - - -/** - See Section 17.15, "Time-Stamp Counter.". Introduced at Display Family / - Display Model 05_01H. - - @param ECX MSR_IA32_TIME_STAMP_COUNTER (0x00000010) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_TIME_STAMP_COUNTER); - AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, Msr); - @endcode - @note MSR_IA32_TIME_STAMP_COUNTER is defined as IA32_TIME_STAMP_COUNTER in SDM. -**/ -#define MSR_IA32_TIME_STAMP_COUNTER 0x00000010 - - -/** - Platform ID (RO) The operating system can use this MSR to determine "slot" - information for the processor and the proper microcode update to load. - Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_IA32_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID); - @endcode - @note MSR_IA32_PLATFORM_ID is defined as IA32_PLATFORM_ID in SDM. -**/ -#define MSR_IA32_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_IA32_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:18; - /// - /// [Bits 52:50] Platform Id (RO) Contains information concerning the - /// intended platform for the processor. - /// 52 51 50 - /// -- -- -- - /// 0 0 0 Processor Flag 0. - /// 0 0 1 Processor Flag 1 - /// 0 1 0 Processor Flag 2 - /// 0 1 1 Processor Flag 3 - /// 1 0 0 Processor Flag 4 - /// 1 0 1 Processor Flag 5 - /// 1 1 0 Processor Flag 6 - /// 1 1 1 Processor Flag 7 - /// - UINT32 PlatformId:3; - UINT32 Reserved3:11; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PLATFORM_ID_REGISTER; - - -/** - 06_01H. - - @param ECX MSR_IA32_APIC_BASE (0x0000001B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_APIC_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_APIC_BASE_REGISTER. - - Example usage - @code - MSR_IA32_APIC_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); - AsmWriteMsr64 (MSR_IA32_APIC_BASE, Msr.Uint64); - @endcode - @note MSR_IA32_APIC_BASE is defined as IA32_APIC_BASE in SDM. -**/ -#define MSR_IA32_APIC_BASE 0x0000001B - -/** - MSR information returned for MSR index #MSR_IA32_APIC_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bit 8] BSP flag (R/W). - /// - UINT32 BSP:1; - UINT32 Reserved2:1; - /// - /// [Bit 10] Enable x2APIC mode. Introduced at Display Family / Display - /// Model 06_1AH. - /// - UINT32 EXTD:1; - /// - /// [Bit 11] APIC Global Enable (R/W). - /// - UINT32 EN:1; - /// - /// [Bits 31:12] APIC Base (R/W). - /// - UINT32 ApicBase:20; - /// - /// [Bits 63:32] APIC Base (R/W). - /// - UINT32 ApicBaseHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_APIC_BASE_REGISTER; - - -/** - Control Features in Intel 64 Processor (R/W). If any one enumeration - condition for defined bit field holds. - - @param ECX MSR_IA32_FEATURE_CONTROL (0x0000003A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_IA32_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_IA32_FEATURE_CONTROL is defined as IA32_FEATURE_CONTROL in SDM. -**/ -#define MSR_IA32_FEATURE_CONTROL 0x0000003A - -/** - MSR information returned for MSR index #MSR_IA32_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock bit (R/WO): (1 = locked). When set, locks this MSR from - /// being written, writes to this bit will result in GP(0). Note: Once the - /// Lock bit is set, the contents of this register cannot be modified. - /// Therefore the lock bit must be set after configuring support for Intel - /// Virtualization Technology and prior to transferring control to an - /// option ROM or the OS. Hence, once the Lock bit is set, the entire - /// IA32_FEATURE_CONTROL contents are preserved across RESET when PWRGOOD - /// is not deasserted. If any one enumeration condition for defined bit - /// field position greater than bit 0 holds. - /// - UINT32 Lock:1; - /// - /// [Bit 1] Enable VMX inside SMX operation (R/WL): This bit enables a - /// system executive to use VMX in conjunction with SMX to support - /// Intel(R) Trusted Execution Technology. BIOS must set this bit only - /// when the CPUID function 1 returns VMX feature flag and SMX feature - /// flag set (ECX bits 5 and 6 respectively). If CPUID.01H:ECX[5] = 1 && - /// CPUID.01H:ECX[6] = 1. - /// - UINT32 EnableVmxInsideSmx:1; - /// - /// [Bit 2] Enable VMX outside SMX operation (R/WL): This bit enables VMX - /// for system executive that do not require SMX. BIOS must set this bit - /// only when the CPUID function 1 returns VMX feature flag set (ECX bit - /// 5). If CPUID.01H:ECX[5] = 1. - /// - UINT32 EnableVmxOutsideSmx:1; - UINT32 Reserved1:5; - /// - /// [Bits 14:8] SENTER Local Function Enables (R/WL): When set, each bit - /// in the field represents an enable control for a corresponding SENTER - /// function. This bit is supported only if CPUID.1:ECX.[bit 6] is set. If - /// CPUID.01H:ECX[6] = 1. - /// - UINT32 SenterLocalFunctionEnables:7; - /// - /// [Bit 15] SENTER Global Enable (R/WL): This bit must be set to enable - /// SENTER leaf functions. This bit is supported only if CPUID.1:ECX.[bit - /// 6] is set. If CPUID.01H:ECX[6] = 1. - /// - UINT32 SenterGlobalEnable:1; - UINT32 Reserved2:1; - /// - /// [Bit 17] SGX Launch Control Enable (R/WL): This bit must be set to - /// enable runtime reconfiguration of SGX Launch Control via - /// IA32_SGXLEPUBKEYHASHn MSR. If CPUID.(EAX=07H, ECX=0H): ECX[30] = 1. - /// - UINT32 SgxLaunchControlEnable:1; - /// - /// [Bit 18] SGX Global Enable (R/WL): This bit must be set to enable SGX - /// leaf functions. If CPUID.(EAX=07H, ECX=0H): EBX[2] = 1. - /// - UINT32 SgxEnable:1; - UINT32 Reserved3:1; - /// - /// [Bit 20] LMCE On (R/WL): When set, system software can program the - /// MSRs associated with LMCE to configure delivery of some machine check - /// exceptions to a single logical processor. If IA32_MCG_CAP[27] = 1. - /// - UINT32 LmceOn:1; - UINT32 Reserved4:11; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_FEATURE_CONTROL_REGISTER; - - -/** - Per Logical Processor TSC Adjust (R/Write to clear). If CPUID.(EAX=07H, - ECX=0H): EBX[1] = 1. THREAD_ADJUST: Local offset value of the IA32_TSC for - a logical processor. Reset value is Zero. A write to IA32_TSC will modify - the local offset in IA32_TSC_ADJUST and the content of IA32_TSC, but does - not affect the internal invariant TSC hardware. - - @param ECX MSR_IA32_TSC_ADJUST (0x0000003B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_TSC_ADJUST); - AsmWriteMsr64 (MSR_IA32_TSC_ADJUST, Msr); - @endcode - @note MSR_IA32_TSC_ADJUST is defined as IA32_TSC_ADJUST in SDM. -**/ -#define MSR_IA32_TSC_ADJUST 0x0000003B - - -/** - BIOS Update Trigger (W) Executing a WRMSR instruction to this MSR causes a - microcode update to be loaded into the processor. See Section 9.11.6, - "Microcode Update Loader." A processor may prevent writing to this MSR when - loading guest states on VM entries or saving guest states on VM exits. - Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_BIOS_UPDT_TRIG (0x00000079) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = 0; - AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, Msr); - @endcode - @note MSR_IA32_BIOS_UPDT_TRIG is defined as IA32_BIOS_UPDT_TRIG in SDM. -**/ -#define MSR_IA32_BIOS_UPDT_TRIG 0x00000079 - - -/** - BIOS Update Signature (RO) Returns the microcode update signature following - the execution of CPUID.01H. A processor may prevent writing to this MSR when - loading guest states on VM entries or saving guest states on VM exits. - Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_BIOS_SIGN_ID (0x0000008B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_BIOS_SIGN_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_BIOS_SIGN_ID_REGISTER. - - Example usage - @code - MSR_IA32_BIOS_SIGN_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); - @endcode - @note MSR_IA32_BIOS_SIGN_ID is defined as IA32_BIOS_SIGN_ID in SDM. -**/ -#define MSR_IA32_BIOS_SIGN_ID 0x0000008B - -/** - MSR information returned for MSR index #MSR_IA32_BIOS_SIGN_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:32; - /// - /// [Bits 63:32] Microcode update signature. This field contains the - /// signature of the currently loaded microcode update when read following - /// the execution of the CPUID instruction, function 1. It is required - /// that this register field be pre-loaded with zero prior to executing - /// the CPUID, function 1. If the field remains equal to zero, then there - /// is no microcode update loaded. Another nonzero value will be the - /// signature. - /// - UINT32 MicrocodeUpdateSignature:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_BIOS_SIGN_ID_REGISTER; - - -/** - IA32_SGXLEPUBKEYHASH[(64*n+63):(64*n)] (R/W) Bits (64*n+63):(64*n) of the - SHA256 digest of the SIGSTRUCT.MODULUS for SGX Launch Enclave. On reset, the - default value is the digest of Intel's signing key. Read permitted If - CPUID.(EAX=12H,ECX=0H):EAX[0]=1, Write permitted if CPUID.(EAX=12H,ECX=0H): - EAX[0]=1 && IA32_FEATURE_CONTROL[17] = 1 && IA32_FEATURE_CONTROL[0] = 1. - - @param ECX MSR_IA32_SGXLEPUBKEYHASHn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_SGXLEPUBKEYHASHn); - AsmWriteMsr64 (MSR_IA32_SGXLEPUBKEYHASHn, Msr); - @endcode - @note MSR_IA32_SGXLEPUBKEYHASH0 is defined as IA32_SGXLEPUBKEYHASH0 in SDM. - MSR_IA32_SGXLEPUBKEYHASH1 is defined as IA32_SGXLEPUBKEYHASH1 in SDM. - MSR_IA32_SGXLEPUBKEYHASH2 is defined as IA32_SGXLEPUBKEYHASH2 in SDM. - MSR_IA32_SGXLEPUBKEYHASH3 is defined as IA32_SGXLEPUBKEYHASH3 in SDM. - @{ -**/ -#define MSR_IA32_SGXLEPUBKEYHASH0 0x0000008C -#define MSR_IA32_SGXLEPUBKEYHASH1 0x0000008D -#define MSR_IA32_SGXLEPUBKEYHASH2 0x0000008E -#define MSR_IA32_SGXLEPUBKEYHASH3 0x0000008F -/// @} - - -/** - SMM Monitor Configuration (R/W). If CPUID.01H: ECX[5]=1 or CPUID.01H: ECX[6] = - 1. - - @param ECX MSR_IA32_SMM_MONITOR_CTL (0x0000009B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_SMM_MONITOR_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_SMM_MONITOR_CTL_REGISTER. - - Example usage - @code - MSR_IA32_SMM_MONITOR_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SMM_MONITOR_CTL); - AsmWriteMsr64 (MSR_IA32_SMM_MONITOR_CTL, Msr.Uint64); - @endcode - @note MSR_IA32_SMM_MONITOR_CTL is defined as IA32_SMM_MONITOR_CTL in SDM. -**/ -#define MSR_IA32_SMM_MONITOR_CTL 0x0000009B - -/** - MSR information returned for MSR index #MSR_IA32_SMM_MONITOR_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Valid (R/W). The STM may be invoked using VMCALL only if this - /// bit is 1. Because VMCALL is used to activate the dual-monitor treatment - /// (see Section 34.15.6), the dual-monitor treatment cannot be activated - /// if the bit is 0. This bit is cleared when the logical processor is - /// reset. - /// - UINT32 Valid:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Determines whether executions of VMXOFF unblock SMIs under the - /// default treatment of SMIs and SMM. Executions of VMXOFF unblock SMIs - /// unless bit 2 is 1 (the value of bit 0 is irrelevant). - /// - UINT32 BlockSmi:1; - UINT32 Reserved2:9; - /// - /// [Bits 31:12] MSEG Base (R/W). - /// - UINT32 MsegBase:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_SMM_MONITOR_CTL_REGISTER; - -/** - MSEG header that is located at the physical address specified by the MsegBase - field of #MSR_IA32_SMM_MONITOR_CTL_REGISTER. -**/ -typedef struct { - /// - /// Different processors may use different MSEG revision identifiers. These - /// identifiers enable software to avoid using an MSEG header formatted for - /// one processor on a processor that uses a different format. Software can - /// discover the MSEG revision identifier that a processor uses by reading - /// the VMX capability MSR IA32_VMX_MISC. - // - UINT32 MsegHeaderRevision; - /// - /// Bits 31:1 of this field are reserved and must be zero. Bit 0 of the field - /// is the IA-32e mode SMM feature bit. It indicates whether the logical - /// processor will be in IA-32e mode after the STM is activated. - /// - UINT32 MonitorFeatures; - UINT32 GdtrLimit; - UINT32 GdtrBaseOffset; - UINT32 CsSelector; - UINT32 EipOffset; - UINT32 EspOffset; - UINT32 Cr3Offset; - /// - /// Pad header so total size is 2KB - /// - UINT8 Reserved[SIZE_2KB - 8 * sizeof (UINT32)]; -} MSEG_HEADER; - -/// -/// @{ Define values for the MonitorFeatures field of #MSEG_HEADER -/// -#define STM_FEATURES_IA32E 0x1 -/// -/// @} -/// - -/** - Base address of the logical processor's SMRAM image (RO, SMM only). If - IA32_VMX_MISC[15]. - - @param ECX MSR_IA32_SMBASE (0x0000009E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_SMBASE); - @endcode - @note MSR_IA32_SMBASE is defined as IA32_SMBASE in SDM. -**/ -#define MSR_IA32_SMBASE 0x0000009E - - -/** - General Performance Counters (R/W). - MSR_IA32_PMCn is supported if CPUID.0AH: EAX[15:8] > n. - - @param ECX MSR_IA32_PMCn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_PMC0); - AsmWriteMsr64 (MSR_IA32_PMC0, Msr); - @endcode - @note MSR_IA32_PMC0 is defined as IA32_PMC0 in SDM. - MSR_IA32_PMC1 is defined as IA32_PMC1 in SDM. - MSR_IA32_PMC2 is defined as IA32_PMC2 in SDM. - MSR_IA32_PMC3 is defined as IA32_PMC3 in SDM. - MSR_IA32_PMC4 is defined as IA32_PMC4 in SDM. - MSR_IA32_PMC5 is defined as IA32_PMC5 in SDM. - MSR_IA32_PMC6 is defined as IA32_PMC6 in SDM. - MSR_IA32_PMC7 is defined as IA32_PMC7 in SDM. - @{ -**/ -#define MSR_IA32_PMC0 0x000000C1 -#define MSR_IA32_PMC1 0x000000C2 -#define MSR_IA32_PMC2 0x000000C3 -#define MSR_IA32_PMC3 0x000000C4 -#define MSR_IA32_PMC4 0x000000C5 -#define MSR_IA32_PMC5 0x000000C6 -#define MSR_IA32_PMC6 0x000000C7 -#define MSR_IA32_PMC7 0x000000C8 -/// @} - - -/** - TSC Frequency Clock Counter (R/Write to clear). If CPUID.06H: ECX[0] = 1. - C0_MCNT: C0 TSC Frequency Clock Count Increments at fixed interval (relative - to TSC freq.) when the logical processor is in C0. Cleared upon overflow / - wrap-around of IA32_APERF. - - @param ECX MSR_IA32_MPERF (0x000000E7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MPERF); - AsmWriteMsr64 (MSR_IA32_MPERF, Msr); - @endcode - @note MSR_IA32_MPERF is defined as IA32_MPERF in SDM. -**/ -#define MSR_IA32_MPERF 0x000000E7 - - -/** - Actual Performance Clock Counter (R/Write to clear). If CPUID.06H: ECX[0] = - 1. C0_ACNT: C0 Actual Frequency Clock Count Accumulates core clock counts at - the coordinated clock frequency, when the logical processor is in C0. - Cleared upon overflow / wrap-around of IA32_MPERF. - - @param ECX MSR_IA32_APERF (0x000000E8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_APERF); - AsmWriteMsr64 (MSR_IA32_APERF, Msr); - @endcode - @note MSR_IA32_APERF is defined as IA32_APERF in SDM. -**/ -#define MSR_IA32_APERF 0x000000E8 - - -/** - MTRR Capability (RO) Section 11.11.2.1, "IA32_MTRR_DEF_TYPE MSR.". - Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_MTRRCAP (0x000000FE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MTRRCAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MTRRCAP_REGISTER. - - Example usage - @code - MSR_IA32_MTRRCAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP); - @endcode - @note MSR_IA32_MTRRCAP is defined as IA32_MTRRCAP in SDM. -**/ -#define MSR_IA32_MTRRCAP 0x000000FE - -/** - MSR information returned for MSR index #MSR_IA32_MTRRCAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] VCNT: The number of variable memory type ranges in the - /// processor. - /// - UINT32 VCNT:8; - /// - /// [Bit 8] Fixed range MTRRs are supported when set. - /// - UINT32 FIX:1; - UINT32 Reserved1:1; - /// - /// [Bit 10] WC Supported when set. - /// - UINT32 WC:1; - /// - /// [Bit 11] SMRR Supported when set. - /// - UINT32 SMRR:1; - UINT32 Reserved2:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MTRRCAP_REGISTER; - - -/** - SYSENTER_CS_MSR (R/W). Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_SYSENTER_CS (0x00000174) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_SYSENTER_CS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_SYSENTER_CS_REGISTER. - - Example usage - @code - MSR_IA32_SYSENTER_CS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SYSENTER_CS); - AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr.Uint64); - @endcode - @note MSR_IA32_SYSENTER_CS is defined as IA32_SYSENTER_CS in SDM. -**/ -#define MSR_IA32_SYSENTER_CS 0x00000174 - -/** - MSR information returned for MSR index #MSR_IA32_SYSENTER_CS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] CS Selector. - /// - UINT32 CS:16; - UINT32 Reserved1:16; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_SYSENTER_CS_REGISTER; - - -/** - SYSENTER_ESP_MSR (R/W). Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_SYSENTER_ESP (0x00000175) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_SYSENTER_ESP); - AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); - @endcode - @note MSR_IA32_SYSENTER_ESP is defined as IA32_SYSENTER_ESP in SDM. -**/ -#define MSR_IA32_SYSENTER_ESP 0x00000175 - - -/** - SYSENTER_EIP_MSR (R/W). Introduced at Display Family / Display Model 06_01H. - - @param ECX MSR_IA32_SYSENTER_EIP (0x00000176) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_SYSENTER_EIP); - AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); - @endcode - @note MSR_IA32_SYSENTER_EIP is defined as IA32_SYSENTER_EIP in SDM. -**/ -#define MSR_IA32_SYSENTER_EIP 0x00000176 - - -/** - Global Machine Check Capability (RO). Introduced at Display Family / Display - Model 06_01H. - - @param ECX MSR_IA32_MCG_CAP (0x00000179) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MCG_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MCG_CAP_REGISTER. - - Example usage - @code - MSR_IA32_MCG_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); - @endcode - @note MSR_IA32_MCG_CAP is defined as IA32_MCG_CAP in SDM. -**/ -#define MSR_IA32_MCG_CAP 0x00000179 - -/** - MSR information returned for MSR index #MSR_IA32_MCG_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Count: Number of reporting banks. - /// - UINT32 Count:8; - /// - /// [Bit 8] MCG_CTL_P: IA32_MCG_CTL is present if this bit is set. - /// - UINT32 MCG_CTL_P:1; - /// - /// [Bit 9] MCG_EXT_P: Extended machine check state registers are present - /// if this bit is set. - /// - UINT32 MCG_EXT_P:1; - /// - /// [Bit 10] MCP_CMCI_P: Support for corrected MC error event is present. - /// Introduced at Display Family / Display Model 06_01H. - /// - UINT32 MCP_CMCI_P:1; - /// - /// [Bit 11] MCG_TES_P: Threshold-based error status register are present - /// if this bit is set. - /// - UINT32 MCG_TES_P:1; - UINT32 Reserved1:4; - /// - /// [Bits 23:16] MCG_EXT_CNT: Number of extended machine check state - /// registers present. - /// - UINT32 MCG_EXT_CNT:8; - /// - /// [Bit 24] MCG_SER_P: The processor supports software error recovery if - /// this bit is set. - /// - UINT32 MCG_SER_P:1; - UINT32 Reserved2:1; - /// - /// [Bit 26] MCG_ELOG_P: Indicates that the processor allows platform - /// firmware to be invoked when an error is detected so that it may - /// provide additional platform specific information in an ACPI format - /// "Generic Error Data Entry" that augments the data included in machine - /// check bank registers. Introduced at Display Family / Display Model - /// 06_3EH. - /// - UINT32 MCG_ELOG_P:1; - /// - /// [Bit 27] MCG_LMCE_P: Indicates that the processor support extended - /// state in IA32_MCG_STATUS and associated MSR necessary to configure - /// Local Machine Check Exception (LMCE). Introduced at Display Family / - /// Display Model 06_3EH. - /// - UINT32 MCG_LMCE_P:1; - UINT32 Reserved3:4; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MCG_CAP_REGISTER; - - -/** - Global Machine Check Status (R/W0). Introduced at Display Family / Display - Model 06_01H. - - @param ECX MSR_IA32_MCG_STATUS (0x0000017A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MCG_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MCG_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_MCG_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_STATUS); - AsmWriteMsr64 (MSR_IA32_MCG_STATUS, Msr.Uint64); - @endcode - @note MSR_IA32_MCG_STATUS is defined as IA32_MCG_STATUS in SDM. -**/ -#define MSR_IA32_MCG_STATUS 0x0000017A - -/** - MSR information returned for MSR index #MSR_IA32_MCG_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] RIPV. Restart IP valid. Introduced at Display Family / Display - /// Model 06_01H. - /// - UINT32 RIPV:1; - /// - /// [Bit 1] EIPV. Error IP valid. Introduced at Display Family / Display - /// Model 06_01H. - /// - UINT32 EIPV:1; - /// - /// [Bit 2] MCIP. Machine check in progress. Introduced at Display Family - /// / Display Model 06_01H. - /// - UINT32 MCIP:1; - /// - /// [Bit 3] LMCE_S. If IA32_MCG_CAP.LMCE_P[2 7] =1. - /// - UINT32 LMCE_S:1; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MCG_STATUS_REGISTER; - - -/** - Global Machine Check Control (R/W). If IA32_MCG_CAP.CTL_P[8] =1. - - @param ECX MSR_IA32_MCG_CTL (0x0000017B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MCG_CTL); - AsmWriteMsr64 (MSR_IA32_MCG_CTL, Msr); - @endcode - @note MSR_IA32_MCG_CTL is defined as IA32_MCG_CTL in SDM. -**/ -#define MSR_IA32_MCG_CTL 0x0000017B - - -/** - Performance Event Select Register n (R/W). If CPUID.0AH: EAX[15:8] > n. - - @param ECX MSR_IA32_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERFEVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERFEVTSEL_REGISTER. - - Example usage - @code - MSR_IA32_PERFEVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERFEVTSEL0); - AsmWriteMsr64 (MSR_IA32_PERFEVTSEL0, Msr.Uint64); - @endcode - @note MSR_IA32_PERFEVTSEL0 is defined as IA32_PERFEVTSEL0 in SDM. - MSR_IA32_PERFEVTSEL1 is defined as IA32_PERFEVTSEL1 in SDM. - MSR_IA32_PERFEVTSEL2 is defined as IA32_PERFEVTSEL2 in SDM. - MSR_IA32_PERFEVTSEL3 is defined as IA32_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_IA32_PERFEVTSEL0 0x00000186 -#define MSR_IA32_PERFEVTSEL1 0x00000187 -#define MSR_IA32_PERFEVTSEL2 0x00000188 -#define MSR_IA32_PERFEVTSEL3 0x00000189 -/// @} - -/** - MSR information returned for MSR indexes #MSR_IA32_PERFEVTSEL0 to - #MSR_IA32_PERFEVTSEL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Event Select: Selects a performance event logic unit. - /// - UINT32 EventSelect:8; - /// - /// [Bits 15:8] UMask: Qualifies the microarchitectural condition to - /// detect on the selected event logic. - /// - UINT32 UMASK:8; - /// - /// [Bit 16] USR: Counts while in privilege level is not ring 0. - /// - UINT32 USR:1; - /// - /// [Bit 17] OS: Counts while in privilege level is ring 0. - /// - UINT32 OS:1; - /// - /// [Bit 18] Edge: Enables edge detection if set. - /// - UINT32 E:1; - /// - /// [Bit 19] PC: enables pin control. - /// - UINT32 PC:1; - /// - /// [Bit 20] INT: enables interrupt on counter overflow. - /// - UINT32 INT:1; - /// - /// [Bit 21] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. - /// - UINT32 ANY:1; - /// - /// [Bit 22] EN: enables the corresponding performance counter to commence - /// counting when this bit is set. - /// - UINT32 EN:1; - /// - /// [Bit 23] INV: invert the CMASK. - /// - UINT32 INV:1; - /// - /// [Bits 31:24] CMASK: When CMASK is not zero, the corresponding - /// performance counter increments each cycle if the event count is - /// greater than or equal to the CMASK. - /// - UINT32 CMASK:8; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERFEVTSEL_REGISTER; - - -/** - Current performance state(P-State) operating point (RO). Introduced at - Display Family / Display Model 0F_03H. - - @param ECX MSR_IA32_PERF_STATUS (0x00000198) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_PERF_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS); - @endcode - @note MSR_IA32_PERF_STATUS is defined as IA32_PERF_STATUS in SDM. -**/ -#define MSR_IA32_PERF_STATUS 0x00000198 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Current performance State Value. - /// - UINT32 State:16; - UINT32 Reserved1:16; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_STATUS_REGISTER; - - -/** - (R/W). Introduced at Display Family / Display Model 0F_03H. - - @param ECX MSR_IA32_PERF_CTL (0x00000199) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_CTL_REGISTER. - - Example usage - @code - MSR_IA32_PERF_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_CTL); - AsmWriteMsr64 (MSR_IA32_PERF_CTL, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_CTL is defined as IA32_PERF_CTL in SDM. -**/ -#define MSR_IA32_PERF_CTL 0x00000199 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Target performance State Value. - /// - UINT32 TargetState:16; - UINT32 Reserved1:16; - /// - /// [Bit 32] IDA Engage. (R/W) When set to 1: disengages IDA. 06_0FH - /// (Mobile only). - /// - UINT32 IDA:1; - UINT32 Reserved2:31; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_CTL_REGISTER; - - -/** - Clock Modulation Control (R/W) See Section 14.7.3, "Software Controlled - Clock Modulation.". If CPUID.01H:EDX[22] = 1. - - @param ECX MSR_IA32_CLOCK_MODULATION (0x0000019A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_CLOCK_MODULATION_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_CLOCK_MODULATION_REGISTER. - - Example usage - @code - MSR_IA32_CLOCK_MODULATION_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_CLOCK_MODULATION); - AsmWriteMsr64 (MSR_IA32_CLOCK_MODULATION, Msr.Uint64); - @endcode - @note MSR_IA32_CLOCK_MODULATION is defined as IA32_CLOCK_MODULATION in SDM. -**/ -#define MSR_IA32_CLOCK_MODULATION 0x0000019A - -/** - MSR information returned for MSR index #MSR_IA32_CLOCK_MODULATION -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Extended On-Demand Clock Modulation Duty Cycle:. If - /// CPUID.06H:EAX[5] = 1. - /// - UINT32 ExtendedOnDemandClockModulationDutyCycle:1; - /// - /// [Bits 3:1] On-Demand Clock Modulation Duty Cycle: Specific encoded - /// values for target duty cycle modulation. If CPUID.01H:EDX[22] = 1. - /// - UINT32 OnDemandClockModulationDutyCycle:3; - /// - /// [Bit 4] On-Demand Clock Modulation Enable: Set 1 to enable modulation. - /// If CPUID.01H:EDX[22] = 1. - /// - UINT32 OnDemandClockModulationEnable:1; - UINT32 Reserved1:27; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_CLOCK_MODULATION_REGISTER; - - -/** - Thermal Interrupt Control (R/W) Enables and disables the generation of an - interrupt on temperature transitions detected with the processor's thermal - sensors and thermal monitor. See Section 14.7.2, "Thermal Monitor.". - If CPUID.01H:EDX[22] = 1 - - @param ECX MSR_IA32_THERM_INTERRUPT (0x0000019B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_THERM_INTERRUPT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_THERM_INTERRUPT_REGISTER. - - Example usage - @code - MSR_IA32_THERM_INTERRUPT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_THERM_INTERRUPT); - AsmWriteMsr64 (MSR_IA32_THERM_INTERRUPT, Msr.Uint64); - @endcode - @note MSR_IA32_THERM_INTERRUPT is defined as IA32_THERM_INTERRUPT in SDM. -**/ -#define MSR_IA32_THERM_INTERRUPT 0x0000019B - -/** - MSR information returned for MSR index #MSR_IA32_THERM_INTERRUPT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] High-Temperature Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 HighTempEnable:1; - /// - /// [Bit 1] Low-Temperature Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 LowTempEnable:1; - /// - /// [Bit 2] PROCHOT# Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 PROCHOT_Enable:1; - /// - /// [Bit 3] FORCEPR# Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 FORCEPR_Enable:1; - /// - /// [Bit 4] Critical Temperature Interrupt Enable. - /// If CPUID.01H:EDX[22] = 1. - /// - UINT32 CriticalTempEnable:1; - UINT32 Reserved1:3; - /// - /// [Bits 14:8] Threshold #1 Value. If CPUID.01H:EDX[22] = 1. - /// - UINT32 Threshold1:7; - /// - /// [Bit 15] Threshold #1 Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 Threshold1Enable:1; - /// - /// [Bits 22:16] Threshold #2 Value. If CPUID.01H:EDX[22] = 1. - /// - UINT32 Threshold2:7; - /// - /// [Bit 23] Threshold #2 Interrupt Enable. If CPUID.01H:EDX[22] = 1. - /// - UINT32 Threshold2Enable:1; - /// - /// [Bit 24] Power Limit Notification Enable. If CPUID.06H:EAX[4] = 1. - /// - UINT32 PowerLimitNotificationEnable:1; - UINT32 Reserved2:7; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_THERM_INTERRUPT_REGISTER; - - -/** - Thermal Status Information (RO) Contains status information about the - processor's thermal sensor and automatic thermal monitoring facilities. See - Section 14.7.2, "Thermal Monitor". If CPUID.01H:EDX[22] = 1. - - @param ECX MSR_IA32_THERM_STATUS (0x0000019C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_THERM_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_THERM_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_THERM_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_THERM_STATUS); - @endcode - @note MSR_IA32_THERM_STATUS is defined as IA32_THERM_STATUS in SDM. -**/ -#define MSR_IA32_THERM_STATUS 0x0000019C - -/** - MSR information returned for MSR index #MSR_IA32_THERM_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thermal Status (RO):. If CPUID.01H:EDX[22] = 1. - /// - UINT32 ThermalStatus:1; - /// - /// [Bit 1] Thermal Status Log (R/W):. If CPUID.01H:EDX[22] = 1. - /// - UINT32 ThermalStatusLog:1; - /// - /// [Bit 2] PROCHOT # or FORCEPR# event (RO). If CPUID.01H:EDX[22] = 1. - /// - UINT32 PROCHOT_FORCEPR_Event:1; - /// - /// [Bit 3] PROCHOT # or FORCEPR# log (R/WC0). If CPUID.01H:EDX[22] = 1. - /// - UINT32 PROCHOT_FORCEPR_Log:1; - /// - /// [Bit 4] Critical Temperature Status (RO). If CPUID.01H:EDX[22] = 1. - /// - UINT32 CriticalTempStatus:1; - /// - /// [Bit 5] Critical Temperature Status log (R/WC0). - /// If CPUID.01H:EDX[22] = 1. - /// - UINT32 CriticalTempStatusLog:1; - /// - /// [Bit 6] Thermal Threshold #1 Status (RO). If CPUID.01H:ECX[8] = 1. - /// - UINT32 ThermalThreshold1Status:1; - /// - /// [Bit 7] Thermal Threshold #1 log (R/WC0). If CPUID.01H:ECX[8] = 1. - /// - UINT32 ThermalThreshold1Log:1; - /// - /// [Bit 8] Thermal Threshold #2 Status (RO). If CPUID.01H:ECX[8] = 1. - /// - UINT32 ThermalThreshold2Status:1; - /// - /// [Bit 9] Thermal Threshold #2 log (R/WC0). If CPUID.01H:ECX[8] = 1. - /// - UINT32 ThermalThreshold2Log:1; - /// - /// [Bit 10] Power Limitation Status (RO). If CPUID.06H:EAX[4] = 1. - /// - UINT32 PowerLimitStatus:1; - /// - /// [Bit 11] Power Limitation log (R/WC0). If CPUID.06H:EAX[4] = 1. - /// - UINT32 PowerLimitLog:1; - /// - /// [Bit 12] Current Limit Status (RO). If CPUID.06H:EAX[7] = 1. - /// - UINT32 CurrentLimitStatus:1; - /// - /// [Bit 13] Current Limit log (R/WC0). If CPUID.06H:EAX[7] = 1. - /// - UINT32 CurrentLimitLog:1; - /// - /// [Bit 14] Cross Domain Limit Status (RO). If CPUID.06H:EAX[7] = 1. - /// - UINT32 CrossDomainLimitStatus:1; - /// - /// [Bit 15] Cross Domain Limit log (R/WC0). If CPUID.06H:EAX[7] = 1. - /// - UINT32 CrossDomainLimitLog:1; - /// - /// [Bits 22:16] Digital Readout (RO). If CPUID.06H:EAX[0] = 1. - /// - UINT32 DigitalReadout:7; - UINT32 Reserved1:4; - /// - /// [Bits 30:27] Resolution in Degrees Celsius (RO). If CPUID.06H:EAX[0] = - /// 1. - /// - UINT32 ResolutionInDegreesCelsius:4; - /// - /// [Bit 31] Reading Valid (RO). If CPUID.06H:EAX[0] = 1. - /// - UINT32 ReadingValid:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_THERM_STATUS_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fast-Strings Enable When set, the fast-strings feature (for - /// REP MOVS and REP STORS) is enabled (default); when clear, fast-strings - /// are disabled. Introduced at Display Family / Display Model 0F_0H. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Automatic Thermal Control Circuit Enable (R/W) 1 = Setting - /// this bit enables the thermal control circuit (TCC) portion of the - /// Intel Thermal Monitor feature. This allows the processor to - /// automatically reduce power consumption in response to TCC activation. - /// 0 = Disabled. Note: In some products clearing this bit might be - /// ignored in critical thermal conditions, and TM1, TM2 and adaptive - /// thermal throttling will still be activated. The default value of this - /// field varies with product. See respective tables where default value is - /// listed. Introduced at Display Family / Display Model 0F_0H. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Performance Monitoring Available (R) 1 = Performance - /// monitoring enabled 0 = Performance monitoring disabled. Introduced at - /// Display Family / Display Model 0F_0H. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:3; - /// - /// [Bit 11] Branch Trace Storage Unavailable (RO) 1 = Processor doesn't - /// support branch trace storage (BTS) 0 = BTS is supported. Introduced at - /// Display Family / Display Model 0F_0H. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Processor Event Based Sampling (PEBS) Unavailable (RO) 1 = - /// PEBS is not supported; 0 = PEBS is supported. Introduced at Display - /// Family / Display Model 06_0FH. - /// - UINT32 PEBS:1; - UINT32 Reserved4:3; - /// - /// [Bit 16] Enhanced Intel SpeedStep Technology Enable (R/W) 0= Enhanced - /// Intel SpeedStep Technology disabled 1 = Enhanced Intel SpeedStep - /// Technology enabled. If CPUID.01H: ECX[7] =1. - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] ENABLE MONITOR FSM (R/W) When this bit is set to 0, the - /// MONITOR feature flag is not set (CPUID.01H:ECX[bit 3] = 0). This - /// indicates that MONITOR/MWAIT are not supported. Software attempts to - /// execute MONITOR/MWAIT will cause #UD when this bit is 0. When this bit - /// is set to 1 (default), MONITOR/MWAIT are supported (CPUID.01H:ECX[bit - /// 3] = 1). If the SSE3 feature flag ECX[0] is not set (CPUID.01H:ECX[bit - /// 0] = 0), the OS must not attempt to alter this bit. BIOS must leave it - /// in the default state. Writing this bit when the SSE3 feature flag is - /// set to 0 may generate a #GP exception. Introduced at Display Family / - /// Display Model 0F_03H. - /// - UINT32 MONITOR:1; - UINT32 Reserved6:3; - /// - /// [Bit 22] Limit CPUID Maxval (R/W) When this bit is set to 1, CPUID.00H - /// returns a maximum value in EAX[7:0] of 2. BIOS should contain a setup - /// question that allows users to specify when the installed OS does not - /// support CPUID functions greater than 2. Before setting this bit, BIOS - /// must execute the CPUID.0H and examine the maximum value returned in - /// EAX[7:0]. If the maximum value is greater than 2, this bit is - /// supported. Otherwise, this bit is not supported. Setting this bit when - /// the maximum value is not greater than 2 may generate a #GP exception. - /// Setting this bit may cause unexpected behavior in software that - /// depends on the availability of CPUID leaves greater than 2. Introduced - /// at Display Family / Display Model 0F_03H. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] xTPR Message Disable (R/W) When set to 1, xTPR messages are - /// disabled. xTPR messages are optional messages that allow the processor - /// to inform the chipset of its priority. if CPUID.01H:ECX[14] = 1. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] XD Bit Disable (R/W) When set to 1, the Execute Disable Bit - /// feature (XD Bit) is disabled and the XD Bit extended feature flag will - /// be clear (CPUID.80000001H: EDX[20]=0). When set to a 0 (default), the - /// Execute Disable Bit feature (if available) allows the OS to enable PAE - /// paging and take advantage of data only pages. BIOS must not alter the - /// contents of this bit location, if XD bit is not supported. Writing - /// this bit to 1 when the XD Bit extended feature flag is set to 0 may - /// generate a #GP exception. if CPUID.80000001H:EDX[2 0] = 1. - /// - UINT32 XD:1; - UINT32 Reserved9:29; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MISC_ENABLE_REGISTER; - - -/** - Performance Energy Bias Hint (R/W). if CPUID.6H:ECX[3] = 1. - - @param ECX MSR_IA32_ENERGY_PERF_BIAS (0x000001B0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_ENERGY_PERF_BIAS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_ENERGY_PERF_BIAS_REGISTER. - - Example usage - @code - MSR_IA32_ENERGY_PERF_BIAS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_ENERGY_PERF_BIAS); - AsmWriteMsr64 (MSR_IA32_ENERGY_PERF_BIAS, Msr.Uint64); - @endcode - @note MSR_IA32_ENERGY_PERF_BIAS is defined as IA32_ENERGY_PERF_BIAS in SDM. -**/ -#define MSR_IA32_ENERGY_PERF_BIAS 0x000001B0 - -/** - MSR information returned for MSR index #MSR_IA32_ENERGY_PERF_BIAS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Power Policy Preference: 0 indicates preference to highest - /// performance. 15 indicates preference to maximize energy saving. - /// - UINT32 PowerPolicyPreference:4; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_ENERGY_PERF_BIAS_REGISTER; - - -/** - Package Thermal Status Information (RO) Contains status information about - the package's thermal sensor. See Section 14.8, "Package Level Thermal - Management.". If CPUID.06H: EAX[6] = 1. - - @param ECX MSR_IA32_PACKAGE_THERM_STATUS (0x000001B1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PACKAGE_THERM_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PACKAGE_THERM_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_PACKAGE_THERM_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PACKAGE_THERM_STATUS); - @endcode - @note MSR_IA32_PACKAGE_THERM_STATUS is defined as IA32_PACKAGE_THERM_STATUS in SDM. -**/ -#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001B1 - -/** - MSR information returned for MSR index #MSR_IA32_PACKAGE_THERM_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Pkg Thermal Status (RO):. - /// - UINT32 ThermalStatus:1; - /// - /// [Bit 1] Pkg Thermal Status Log (R/W):. - /// - UINT32 ThermalStatusLog:1; - /// - /// [Bit 2] Pkg PROCHOT # event (RO). - /// - UINT32 PROCHOT_Event:1; - /// - /// [Bit 3] Pkg PROCHOT # log (R/WC0). - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 4] Pkg Critical Temperature Status (RO). - /// - UINT32 CriticalTempStatus:1; - /// - /// [Bit 5] Pkg Critical Temperature Status log (R/WC0). - /// - UINT32 CriticalTempStatusLog:1; - /// - /// [Bit 6] Pkg Thermal Threshold #1 Status (RO). - /// - UINT32 ThermalThreshold1Status:1; - /// - /// [Bit 7] Pkg Thermal Threshold #1 log (R/WC0). - /// - UINT32 ThermalThreshold1Log:1; - /// - /// [Bit 8] Pkg Thermal Threshold #2 Status (RO). - /// - UINT32 ThermalThreshold2Status:1; - /// - /// [Bit 9] Pkg Thermal Threshold #1 log (R/WC0). - /// - UINT32 ThermalThreshold2Log:1; - /// - /// [Bit 10] Pkg Power Limitation Status (RO). - /// - UINT32 PowerLimitStatus:1; - /// - /// [Bit 11] Pkg Power Limitation log (R/WC0). - /// - UINT32 PowerLimitLog:1; - UINT32 Reserved1:4; - /// - /// [Bits 22:16] Pkg Digital Readout (RO). - /// - UINT32 DigitalReadout:7; - UINT32 Reserved2:9; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PACKAGE_THERM_STATUS_REGISTER; - - -/** - Pkg Thermal Interrupt Control (R/W) Enables and disables the generation of - an interrupt on temperature transitions detected with the package's thermal - sensor. See Section 14.8, "Package Level Thermal Management.". If CPUID.06H: - EAX[6] = 1. - - @param ECX MSR_IA32_PACKAGE_THERM_INTERRUPT (0x000001B2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PACKAGE_THERM_INTERRUPT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PACKAGE_THERM_INTERRUPT_REGISTER. - - Example usage - @code - MSR_IA32_PACKAGE_THERM_INTERRUPT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PACKAGE_THERM_INTERRUPT); - AsmWriteMsr64 (MSR_IA32_PACKAGE_THERM_INTERRUPT, Msr.Uint64); - @endcode - @note MSR_IA32_PACKAGE_THERM_INTERRUPT is defined as IA32_PACKAGE_THERM_INTERRUPT in SDM. -**/ -#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001B2 - -/** - MSR information returned for MSR index #MSR_IA32_PACKAGE_THERM_INTERRUPT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Pkg High-Temperature Interrupt Enable. - /// - UINT32 HighTempEnable:1; - /// - /// [Bit 1] Pkg Low-Temperature Interrupt Enable. - /// - UINT32 LowTempEnable:1; - /// - /// [Bit 2] Pkg PROCHOT# Interrupt Enable. - /// - UINT32 PROCHOT_Enable:1; - UINT32 Reserved1:1; - /// - /// [Bit 4] Pkg Overheat Interrupt Enable. - /// - UINT32 OverheatEnable:1; - UINT32 Reserved2:3; - /// - /// [Bits 14:8] Pkg Threshold #1 Value. - /// - UINT32 Threshold1:7; - /// - /// [Bit 15] Pkg Threshold #1 Interrupt Enable. - /// - UINT32 Threshold1Enable:1; - /// - /// [Bits 22:16] Pkg Threshold #2 Value. - /// - UINT32 Threshold2:7; - /// - /// [Bit 23] Pkg Threshold #2 Interrupt Enable. - /// - UINT32 Threshold2Enable:1; - /// - /// [Bit 24] Pkg Power Limit Notification Enable. - /// - UINT32 PowerLimitNotificationEnable:1; - UINT32 Reserved3:7; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PACKAGE_THERM_INTERRUPT_REGISTER; - - -/** - Trace/Profile Resource Control (R/W). Introduced at Display Family / Display - Model 06_0EH. - - @param ECX MSR_IA32_DEBUGCTL (0x000001D9) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_DEBUGCTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_DEBUGCTL_REGISTER. - - Example usage - @code - MSR_IA32_DEBUGCTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_DEBUGCTL); - AsmWriteMsr64 (MSR_IA32_DEBUGCTL, Msr.Uint64); - @endcode - @note MSR_IA32_DEBUGCTL is defined as IA32_DEBUGCTL in SDM. -**/ -#define MSR_IA32_DEBUGCTL 0x000001D9 - -/** - MSR information returned for MSR index #MSR_IA32_DEBUGCTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LBR: Setting this bit to 1 enables the processor to record a - /// running trace of the most recent branches taken by the processor in - /// the LBR stack. Introduced at Display Family / Display Model 06_01H. - /// - UINT32 LBR:1; - /// - /// [Bit 1] BTF: Setting this bit to 1 enables the processor to treat - /// EFLAGS.TF as single-step on branches instead of single-step on - /// instructions. Introduced at Display Family / Display Model 06_01H. - /// - UINT32 BTF:1; - UINT32 Reserved1:4; - /// - /// [Bit 6] TR: Setting this bit to 1 enables branch trace messages to be - /// sent. Introduced at Display Family / Display Model 06_0EH. - /// - UINT32 TR:1; - /// - /// [Bit 7] BTS: Setting this bit enables branch trace messages (BTMs) to - /// be logged in a BTS buffer. Introduced at Display Family / Display - /// Model 06_0EH. - /// - UINT32 BTS:1; - /// - /// [Bit 8] BTINT: When clear, BTMs are logged in a BTS buffer in circular - /// fashion. When this bit is set, an interrupt is generated by the BTS - /// facility when the BTS buffer is full. Introduced at Display Family / - /// Display Model 06_0EH. - /// - UINT32 BTINT:1; - /// - /// [Bit 9] BTS_OFF_OS: When set, BTS or BTM is skipped if CPL = 0. - /// Introduced at Display Family / Display Model 06_0FH. - /// - UINT32 BTS_OFF_OS:1; - /// - /// [Bit 10] BTS_OFF_USR: When set, BTS or BTM is skipped if CPL > 0. - /// Introduced at Display Family / Display Model 06_0FH. - /// - UINT32 BTS_OFF_USR:1; - /// - /// [Bit 11] FREEZE_LBRS_ON_PMI: When set, the LBR stack is frozen on a - /// PMI request. If CPUID.01H: ECX[15] = 1 && CPUID.0AH: EAX[7:0] > 1. - /// - UINT32 FREEZE_LBRS_ON_PMI:1; - /// - /// [Bit 12] FREEZE_PERFMON_ON_PMI: When set, each ENABLE bit of the - /// global counter control MSR are frozen (address 38FH) on a PMI request. - /// If CPUID.01H: ECX[15] = 1 && CPUID.0AH: EAX[7:0] > 1. - /// - UINT32 FREEZE_PERFMON_ON_PMI:1; - /// - /// [Bit 13] ENABLE_UNCORE_PMI: When set, enables the logical processor to - /// receive and generate PMI on behalf of the uncore. Introduced at - /// Display Family / Display Model 06_1AH. - /// - UINT32 ENABLE_UNCORE_PMI:1; - /// - /// [Bit 14] FREEZE_WHILE_SMM: When set, freezes perfmon and trace - /// messages while in SMM. If IA32_PERF_CAPABILITIES[ 12] = 1. - /// - UINT32 FREEZE_WHILE_SMM:1; - /// - /// [Bit 15] RTM_DEBUG: When set, enables DR7 debug bit on XBEGIN. If - /// (CPUID.(EAX=07H, ECX=0):EBX[11] = 1). - /// - UINT32 RTM_DEBUG:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_DEBUGCTL_REGISTER; - - -/** - SMRR Base Address (Writeable only in SMM) Base address of SMM memory range. - If IA32_MTRRCAP.SMRR[11] = 1. - - @param ECX MSR_IA32_SMRR_PHYSBASE (0x000001F2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_SMRR_PHYSBASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_SMRR_PHYSBASE_REGISTER. - - Example usage - @code - MSR_IA32_SMRR_PHYSBASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SMRR_PHYSBASE); - AsmWriteMsr64 (MSR_IA32_SMRR_PHYSBASE, Msr.Uint64); - @endcode - @note MSR_IA32_SMRR_PHYSBASE is defined as IA32_SMRR_PHYSBASE in SDM. -**/ -#define MSR_IA32_SMRR_PHYSBASE 0x000001F2 - -/** - MSR information returned for MSR index #MSR_IA32_SMRR_PHYSBASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Type. Specifies memory type of the range. - /// - UINT32 Type:8; - UINT32 Reserved1:4; - /// - /// [Bits 31:12] PhysBase. SMRR physical Base Address. - /// - UINT32 PhysBase:20; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_SMRR_PHYSBASE_REGISTER; - - -/** - SMRR Range Mask. (Writeable only in SMM) Range Mask of SMM memory range. If - IA32_MTRRCAP[SMRR] = 1. - - @param ECX MSR_IA32_SMRR_PHYSMASK (0x000001F3) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_SMRR_PHYSMASK_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_SMRR_PHYSMASK_REGISTER. - - Example usage - @code - MSR_IA32_SMRR_PHYSMASK_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SMRR_PHYSMASK); - AsmWriteMsr64 (MSR_IA32_SMRR_PHYSMASK, Msr.Uint64); - @endcode - @note MSR_IA32_SMRR_PHYSMASK is defined as IA32_SMRR_PHYSMASK in SDM. -**/ -#define MSR_IA32_SMRR_PHYSMASK 0x000001F3 - -/** - MSR information returned for MSR index #MSR_IA32_SMRR_PHYSMASK -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:11; - /// - /// [Bit 11] Valid Enable range mask. - /// - UINT32 Valid:1; - /// - /// [Bits 31:12] PhysMask SMRR address range mask. - /// - UINT32 PhysMask:20; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_SMRR_PHYSMASK_REGISTER; - - -/** - DCA Capability (R). If CPUID.01H: ECX[18] = 1. - - @param ECX MSR_IA32_PLATFORM_DCA_CAP (0x000001F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_PLATFORM_DCA_CAP); - @endcode - @note MSR_IA32_PLATFORM_DCA_CAP is defined as IA32_PLATFORM_DCA_CAP in SDM. -**/ -#define MSR_IA32_PLATFORM_DCA_CAP 0x000001F8 - - -/** - If set, CPU supports Prefetch-Hint type. If CPUID.01H: ECX[18] = 1. - - @param ECX MSR_IA32_CPU_DCA_CAP (0x000001F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_CPU_DCA_CAP); - AsmWriteMsr64 (MSR_IA32_CPU_DCA_CAP, Msr); - @endcode - @note MSR_IA32_CPU_DCA_CAP is defined as IA32_CPU_DCA_CAP in SDM. -**/ -#define MSR_IA32_CPU_DCA_CAP 0x000001F9 - - -/** - DCA type 0 Status and Control register. If CPUID.01H: ECX[18] = 1. - - @param ECX MSR_IA32_DCA_0_CAP (0x000001FA) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_DCA_0_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_DCA_0_CAP_REGISTER. - - Example usage - @code - MSR_IA32_DCA_0_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_DCA_0_CAP); - AsmWriteMsr64 (MSR_IA32_DCA_0_CAP, Msr.Uint64); - @endcode - @note MSR_IA32_DCA_0_CAP is defined as IA32_DCA_0_CAP in SDM. -**/ -#define MSR_IA32_DCA_0_CAP 0x000001FA - -/** - MSR information returned for MSR index #MSR_IA32_DCA_0_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] DCA_ACTIVE: Set by HW when DCA is fuseenabled and no - /// defeatures are set. - /// - UINT32 DCA_ACTIVE:1; - /// - /// [Bits 2:1] TRANSACTION. - /// - UINT32 TRANSACTION:2; - /// - /// [Bits 6:3] DCA_TYPE. - /// - UINT32 DCA_TYPE:4; - /// - /// [Bits 10:7] DCA_QUEUE_SIZE. - /// - UINT32 DCA_QUEUE_SIZE:4; - UINT32 Reserved1:2; - /// - /// [Bits 16:13] DCA_DELAY: Writes will update the register but have no HW - /// side-effect. - /// - UINT32 DCA_DELAY:4; - UINT32 Reserved2:7; - /// - /// [Bit 24] SW_BLOCK: SW can request DCA block by setting this bit. - /// - UINT32 SW_BLOCK:1; - UINT32 Reserved3:1; - /// - /// [Bit 26] HW_BLOCK: Set when DCA is blocked by HW (e.g. CR0.CD = 1). - /// - UINT32 HW_BLOCK:1; - UINT32 Reserved4:5; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_DCA_0_CAP_REGISTER; - - -/** - MTRRphysBasen. See Section 11.11.2.3, "Variable Range MTRRs". - If CPUID.01H: EDX.MTRR[12] = 1 and IA32_MTRRCAP[7:0] > n. - - @param ECX MSR_IA32_MTRR_PHYSBASEn - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_PHYSBASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_PHYSBASE_REGISTER. - - Example usage - @code - MSR_IA32_MTRR_PHYSBASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0); - AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0, Msr.Uint64); - @endcode - @note MSR_IA32_MTRR_PHYSBASE0 is defined as IA32_MTRR_PHYSBASE0 in SDM. - MSR_IA32_MTRR_PHYSBASE1 is defined as IA32_MTRR_PHYSBASE1 in SDM. - MSR_IA32_MTRR_PHYSBASE2 is defined as IA32_MTRR_PHYSBASE2 in SDM. - MSR_IA32_MTRR_PHYSBASE3 is defined as IA32_MTRR_PHYSBASE3 in SDM. - MSR_IA32_MTRR_PHYSBASE4 is defined as IA32_MTRR_PHYSBASE4 in SDM. - MSR_IA32_MTRR_PHYSBASE5 is defined as IA32_MTRR_PHYSBASE5 in SDM. - MSR_IA32_MTRR_PHYSBASE6 is defined as IA32_MTRR_PHYSBASE6 in SDM. - MSR_IA32_MTRR_PHYSBASE7 is defined as IA32_MTRR_PHYSBASE7 in SDM. - MSR_IA32_MTRR_PHYSBASE8 is defined as IA32_MTRR_PHYSBASE8 in SDM. - MSR_IA32_MTRR_PHYSBASE9 is defined as IA32_MTRR_PHYSBASE9 in SDM. - @{ -**/ -#define MSR_IA32_MTRR_PHYSBASE0 0x00000200 -#define MSR_IA32_MTRR_PHYSBASE1 0x00000202 -#define MSR_IA32_MTRR_PHYSBASE2 0x00000204 -#define MSR_IA32_MTRR_PHYSBASE3 0x00000206 -#define MSR_IA32_MTRR_PHYSBASE4 0x00000208 -#define MSR_IA32_MTRR_PHYSBASE5 0x0000020A -#define MSR_IA32_MTRR_PHYSBASE6 0x0000020C -#define MSR_IA32_MTRR_PHYSBASE7 0x0000020E -#define MSR_IA32_MTRR_PHYSBASE8 0x00000210 -#define MSR_IA32_MTRR_PHYSBASE9 0x00000212 -/// @} - -/** - MSR information returned for MSR indexes #MSR_IA32_MTRR_PHYSBASE0 to - #MSR_IA32_MTRR_PHYSBASE9 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Type. Specifies memory type of the range. - /// - UINT32 Type:8; - UINT32 Reserved1:4; - /// - /// [Bits 31:12] PhysBase. MTRR physical Base Address. - /// - UINT32 PhysBase:20; - /// - /// [Bits MAXPHYSADDR:32] PhysBase. Upper bits of MTRR physical Base Address. - /// MAXPHYADDR: The bit position indicated by MAXPHYADDR depends on the - /// maximum physical address range supported by the processor. It is - /// reported by CPUID leaf function 80000008H. If CPUID does not support - /// leaf 80000008H, the processor supports 36-bit physical address size, - /// then bit PhysMask consists of bits 35:12, and bits 63:36 are reserved. - /// - UINT32 PhysBaseHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MTRR_PHYSBASE_REGISTER; - - -/** - MTRRphysMaskn. See Section 11.11.2.3, "Variable Range MTRRs". - If CPUID.01H: EDX.MTRR[12] = 1 and IA32_MTRRCAP[7:0] > n. - - @param ECX MSR_IA32_MTRR_PHYSMASKn - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_PHYSMASK_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_PHYSMASK_REGISTER. - - Example usage - @code - MSR_IA32_MTRR_PHYSMASK_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0); - AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0, Msr.Uint64); - @endcode - @note MSR_IA32_MTRR_PHYSMASK0 is defined as IA32_MTRR_PHYSMASK0 in SDM. - MSR_IA32_MTRR_PHYSMASK1 is defined as IA32_MTRR_PHYSMASK1 in SDM. - MSR_IA32_MTRR_PHYSMASK2 is defined as IA32_MTRR_PHYSMASK2 in SDM. - MSR_IA32_MTRR_PHYSMASK3 is defined as IA32_MTRR_PHYSMASK3 in SDM. - MSR_IA32_MTRR_PHYSMASK4 is defined as IA32_MTRR_PHYSMASK4 in SDM. - MSR_IA32_MTRR_PHYSMASK5 is defined as IA32_MTRR_PHYSMASK5 in SDM. - MSR_IA32_MTRR_PHYSMASK6 is defined as IA32_MTRR_PHYSMASK6 in SDM. - MSR_IA32_MTRR_PHYSMASK7 is defined as IA32_MTRR_PHYSMASK7 in SDM. - MSR_IA32_MTRR_PHYSMASK8 is defined as IA32_MTRR_PHYSMASK8 in SDM. - MSR_IA32_MTRR_PHYSMASK9 is defined as IA32_MTRR_PHYSMASK9 in SDM. - @{ -**/ -#define MSR_IA32_MTRR_PHYSMASK0 0x00000201 -#define MSR_IA32_MTRR_PHYSMASK1 0x00000203 -#define MSR_IA32_MTRR_PHYSMASK2 0x00000205 -#define MSR_IA32_MTRR_PHYSMASK3 0x00000207 -#define MSR_IA32_MTRR_PHYSMASK4 0x00000209 -#define MSR_IA32_MTRR_PHYSMASK5 0x0000020B -#define MSR_IA32_MTRR_PHYSMASK6 0x0000020D -#define MSR_IA32_MTRR_PHYSMASK7 0x0000020F -#define MSR_IA32_MTRR_PHYSMASK8 0x00000211 -#define MSR_IA32_MTRR_PHYSMASK9 0x00000213 -/// @} - -/** - MSR information returned for MSR indexes #MSR_IA32_MTRR_PHYSMASK0 to - #MSR_IA32_MTRR_PHYSMASK9 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:11; - /// - /// [Bit 11] Valid Enable range mask. - /// - UINT32 V:1; - /// - /// [Bits 31:12] PhysMask. MTRR address range mask. - /// - UINT32 PhysMask:20; - /// - /// [Bits MAXPHYSADDR:32] PhysMask. Upper bits of MTRR address range mask. - /// MAXPHYADDR: The bit position indicated by MAXPHYADDR depends on the - /// maximum physical address range supported by the processor. It is - /// reported by CPUID leaf function 80000008H. If CPUID does not support - /// leaf 80000008H, the processor supports 36-bit physical address size, - /// then bit PhysMask consists of bits 35:12, and bits 63:36 are reserved. - /// - UINT32 PhysMaskHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MTRR_PHYSMASK_REGISTER; - - -/** - MTRRfix64K_00000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX64K_00000 (0x00000250) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX64K_00000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX64K_00000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX64K_00000 is defined as IA32_MTRR_FIX64K_00000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX64K_00000 0x00000250 - - -/** - MTRRfix16K_80000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX16K_80000 (0x00000258) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX16K_80000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX16K_80000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX16K_80000 is defined as IA32_MTRR_FIX16K_80000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX16K_80000 0x00000258 - - -/** - MTRRfix16K_A0000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX16K_A0000 (0x00000259) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX16K_A0000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX16K_A0000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX16K_A0000 is defined as IA32_MTRR_FIX16K_A0000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX16K_A0000 0x00000259 - - -/** - See Section 11.11.2.2, "Fixed Range MTRRs.". If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_C0000 (0x00000268) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_C0000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_C0000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_C0000 is defined as IA32_MTRR_FIX4K_C0000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_C0000 0x00000268 - - -/** - MTRRfix4K_C8000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_C8000 (0x00000269) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_C8000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_C8000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_C8000 is defined as IA32_MTRR_FIX4K_C8000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_C8000 0x00000269 - - -/** - MTRRfix4K_D0000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_D0000 (0x0000026A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_D0000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_D0000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_D0000 is defined as IA32_MTRR_FIX4K_D0000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_D0000 0x0000026A - - -/** - MTRRfix4K_D8000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_D8000 (0x0000026B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_D8000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_D8000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_D8000 is defined as IA32_MTRR_FIX4K_D8000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_D8000 0x0000026B - - -/** - MTRRfix4K_E0000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_E0000 (0x0000026C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_E0000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_E0000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_E0000 is defined as IA32_MTRR_FIX4K_E0000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_E0000 0x0000026C - - -/** - MTRRfix4K_E8000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_E8000 (0x0000026D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_E8000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_E8000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_E8000 is defined as IA32_MTRR_FIX4K_E8000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_E8000 0x0000026D - - -/** - MTRRfix4K_F0000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_F0000 (0x0000026E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_F0000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_F0000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_F0000 is defined as IA32_MTRR_FIX4K_F0000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_F0000 0x0000026E - - -/** - MTRRfix4K_F8000. If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_FIX4K_F8000 (0x0000026F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_F8000); - AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_F8000, Msr); - @endcode - @note MSR_IA32_MTRR_FIX4K_F8000 is defined as IA32_MTRR_FIX4K_F8000 in SDM. -**/ -#define MSR_IA32_MTRR_FIX4K_F8000 0x0000026F - - -/** - IA32_PAT (R/W). If CPUID.01H: EDX.MTRR[16] =1. - - @param ECX MSR_IA32_PAT (0x00000277) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PAT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PAT_REGISTER. - - Example usage - @code - MSR_IA32_PAT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PAT); - AsmWriteMsr64 (MSR_IA32_PAT, Msr.Uint64); - @endcode - @note MSR_IA32_PAT is defined as IA32_PAT in SDM. -**/ -#define MSR_IA32_PAT 0x00000277 - -/** - MSR information returned for MSR index #MSR_IA32_PAT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] PA0. - /// - UINT32 PA0:3; - UINT32 Reserved1:5; - /// - /// [Bits 10:8] PA1. - /// - UINT32 PA1:3; - UINT32 Reserved2:5; - /// - /// [Bits 18:16] PA2. - /// - UINT32 PA2:3; - UINT32 Reserved3:5; - /// - /// [Bits 26:24] PA3. - /// - UINT32 PA3:3; - UINT32 Reserved4:5; - /// - /// [Bits 34:32] PA4. - /// - UINT32 PA4:3; - UINT32 Reserved5:5; - /// - /// [Bits 42:40] PA5. - /// - UINT32 PA5:3; - UINT32 Reserved6:5; - /// - /// [Bits 50:48] PA6. - /// - UINT32 PA6:3; - UINT32 Reserved7:5; - /// - /// [Bits 58:56] PA7. - /// - UINT32 PA7:3; - UINT32 Reserved8:5; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PAT_REGISTER; - - -/** - Provides the programming interface to use corrected MC error signaling - capability (R/W). If IA32_MCG_CAP[10] = 1 && IA32_MCG_CAP[7:0] > n. - - @param ECX MSR_IA32_MCn_CTL2 - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MC_CTL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MC_CTL2_REGISTER. - - Example usage - @code - MSR_IA32_MC_CTL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MC0_CTL2); - AsmWriteMsr64 (MSR_IA32_MC0_CTL2, Msr.Uint64); - @endcode - @note MSR_IA32_MC0_CTL2 is defined as IA32_MC0_CTL2 in SDM. - MSR_IA32_MC1_CTL2 is defined as IA32_MC1_CTL2 in SDM. - MSR_IA32_MC2_CTL2 is defined as IA32_MC2_CTL2 in SDM. - MSR_IA32_MC3_CTL2 is defined as IA32_MC3_CTL2 in SDM. - MSR_IA32_MC4_CTL2 is defined as IA32_MC4_CTL2 in SDM. - MSR_IA32_MC5_CTL2 is defined as IA32_MC5_CTL2 in SDM. - MSR_IA32_MC6_CTL2 is defined as IA32_MC6_CTL2 in SDM. - MSR_IA32_MC7_CTL2 is defined as IA32_MC7_CTL2 in SDM. - MSR_IA32_MC8_CTL2 is defined as IA32_MC8_CTL2 in SDM. - MSR_IA32_MC9_CTL2 is defined as IA32_MC9_CTL2 in SDM. - MSR_IA32_MC10_CTL2 is defined as IA32_MC10_CTL2 in SDM. - MSR_IA32_MC11_CTL2 is defined as IA32_MC11_CTL2 in SDM. - MSR_IA32_MC12_CTL2 is defined as IA32_MC12_CTL2 in SDM. - MSR_IA32_MC13_CTL2 is defined as IA32_MC13_CTL2 in SDM. - MSR_IA32_MC14_CTL2 is defined as IA32_MC14_CTL2 in SDM. - MSR_IA32_MC15_CTL2 is defined as IA32_MC15_CTL2 in SDM. - MSR_IA32_MC16_CTL2 is defined as IA32_MC16_CTL2 in SDM. - MSR_IA32_MC17_CTL2 is defined as IA32_MC17_CTL2 in SDM. - MSR_IA32_MC18_CTL2 is defined as IA32_MC18_CTL2 in SDM. - MSR_IA32_MC19_CTL2 is defined as IA32_MC19_CTL2 in SDM. - MSR_IA32_MC20_CTL2 is defined as IA32_MC20_CTL2 in SDM. - MSR_IA32_MC21_CTL2 is defined as IA32_MC21_CTL2 in SDM. - MSR_IA32_MC22_CTL2 is defined as IA32_MC22_CTL2 in SDM. - MSR_IA32_MC23_CTL2 is defined as IA32_MC23_CTL2 in SDM. - MSR_IA32_MC24_CTL2 is defined as IA32_MC24_CTL2 in SDM. - MSR_IA32_MC25_CTL2 is defined as IA32_MC25_CTL2 in SDM. - MSR_IA32_MC26_CTL2 is defined as IA32_MC26_CTL2 in SDM. - MSR_IA32_MC27_CTL2 is defined as IA32_MC27_CTL2 in SDM. - MSR_IA32_MC28_CTL2 is defined as IA32_MC28_CTL2 in SDM. - MSR_IA32_MC29_CTL2 is defined as IA32_MC29_CTL2 in SDM. - MSR_IA32_MC30_CTL2 is defined as IA32_MC30_CTL2 in SDM. - MSR_IA32_MC31_CTL2 is defined as IA32_MC31_CTL2 in SDM. - @{ -**/ -#define MSR_IA32_MC0_CTL2 0x00000280 -#define MSR_IA32_MC1_CTL2 0x00000281 -#define MSR_IA32_MC2_CTL2 0x00000282 -#define MSR_IA32_MC3_CTL2 0x00000283 -#define MSR_IA32_MC4_CTL2 0x00000284 -#define MSR_IA32_MC5_CTL2 0x00000285 -#define MSR_IA32_MC6_CTL2 0x00000286 -#define MSR_IA32_MC7_CTL2 0x00000287 -#define MSR_IA32_MC8_CTL2 0x00000288 -#define MSR_IA32_MC9_CTL2 0x00000289 -#define MSR_IA32_MC10_CTL2 0x0000028A -#define MSR_IA32_MC11_CTL2 0x0000028B -#define MSR_IA32_MC12_CTL2 0x0000028C -#define MSR_IA32_MC13_CTL2 0x0000028D -#define MSR_IA32_MC14_CTL2 0x0000028E -#define MSR_IA32_MC15_CTL2 0x0000028F -#define MSR_IA32_MC16_CTL2 0x00000290 -#define MSR_IA32_MC17_CTL2 0x00000291 -#define MSR_IA32_MC18_CTL2 0x00000292 -#define MSR_IA32_MC19_CTL2 0x00000293 -#define MSR_IA32_MC20_CTL2 0x00000294 -#define MSR_IA32_MC21_CTL2 0x00000295 -#define MSR_IA32_MC22_CTL2 0x00000296 -#define MSR_IA32_MC23_CTL2 0x00000297 -#define MSR_IA32_MC24_CTL2 0x00000298 -#define MSR_IA32_MC25_CTL2 0x00000299 -#define MSR_IA32_MC26_CTL2 0x0000029A -#define MSR_IA32_MC27_CTL2 0x0000029B -#define MSR_IA32_MC28_CTL2 0x0000029C -#define MSR_IA32_MC29_CTL2 0x0000029D -#define MSR_IA32_MC30_CTL2 0x0000029E -#define MSR_IA32_MC31_CTL2 0x0000029F -/// @} - -/** - MSR information returned for MSR indexes #MSR_IA32_MC0_CTL2 - to #MSR_IA32_MC31_CTL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Corrected error count threshold. - /// - UINT32 CorrectedErrorCountThreshold:15; - UINT32 Reserved1:15; - /// - /// [Bit 30] CMCI_EN. - /// - UINT32 CMCI_EN:1; - UINT32 Reserved2:1; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MC_CTL2_REGISTER; - - -/** - MTRRdefType (R/W). If CPUID.01H: EDX.MTRR[12] =1. - - @param ECX MSR_IA32_MTRR_DEF_TYPE (0x000002FF) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_DEF_TYPE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MTRR_DEF_TYPE_REGISTER. - - Example usage - @code - MSR_IA32_MTRR_DEF_TYPE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); - AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, Msr.Uint64); - @endcode - @note MSR_IA32_MTRR_DEF_TYPE is defined as IA32_MTRR_DEF_TYPE in SDM. -**/ -#define MSR_IA32_MTRR_DEF_TYPE 0x000002FF - -/** - MSR information returned for MSR index #MSR_IA32_MTRR_DEF_TYPE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Default Memory Type. - /// - UINT32 Type:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] Fixed Range MTRR Enable. - /// - UINT32 FE:1; - /// - /// [Bit 11] MTRR Enable. - /// - UINT32 E:1; - UINT32 Reserved2:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MTRR_DEF_TYPE_REGISTER; - - -/** - Fixed-Function Performance Counter 0 (R/W): Counts Instr_Retired.Any. If - CPUID.0AH: EDX[4:0] > 0. - - @param ECX MSR_IA32_FIXED_CTR0 (0x00000309) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR0); - AsmWriteMsr64 (MSR_IA32_FIXED_CTR0, Msr); - @endcode - @note MSR_IA32_FIXED_CTR0 is defined as IA32_FIXED_CTR0 in SDM. -**/ -#define MSR_IA32_FIXED_CTR0 0x00000309 - - -/** - Fixed-Function Performance Counter 1 (R/W): Counts CPU_CLK_Unhalted.Core. If - CPUID.0AH: EDX[4:0] > 1. - - @param ECX MSR_IA32_FIXED_CTR1 (0x0000030A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR1); - AsmWriteMsr64 (MSR_IA32_FIXED_CTR1, Msr); - @endcode - @note MSR_IA32_FIXED_CTR1 is defined as IA32_FIXED_CTR1 in SDM. -**/ -#define MSR_IA32_FIXED_CTR1 0x0000030A - - -/** - Fixed-Function Performance Counter 2 (R/W): Counts CPU_CLK_Unhalted.Ref. If - CPUID.0AH: EDX[4:0] > 2. - - @param ECX MSR_IA32_FIXED_CTR2 (0x0000030B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR2); - AsmWriteMsr64 (MSR_IA32_FIXED_CTR2, Msr); - @endcode - @note MSR_IA32_FIXED_CTR2 is defined as IA32_FIXED_CTR2 in SDM. -**/ -#define MSR_IA32_FIXED_CTR2 0x0000030B - - -/** - RO. If CPUID.01H: ECX[15] = 1. - - @param ECX MSR_IA32_PERF_CAPABILITIES (0x00000345) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_CAPABILITIES_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_CAPABILITIES_REGISTER. - - Example usage - @code - MSR_IA32_PERF_CAPABILITIES_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_CAPABILITIES); - AsmWriteMsr64 (MSR_IA32_PERF_CAPABILITIES, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_CAPABILITIES is defined as IA32_PERF_CAPABILITIES in SDM. -**/ -#define MSR_IA32_PERF_CAPABILITIES 0x00000345 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_CAPABILITIES -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 5:0] LBR format. - /// - UINT32 LBR_FMT:6; - /// - /// [Bit 6] PEBS Trap. - /// - UINT32 PEBS_TRAP:1; - /// - /// [Bit 7] PEBSSaveArchRegs. - /// - UINT32 PEBS_ARCH_REG:1; - /// - /// [Bits 11:8] PEBS Record Format. - /// - UINT32 PEBS_REC_FMT:4; - /// - /// [Bit 12] 1: Freeze while SMM is supported. - /// - UINT32 SMM_FREEZE:1; - /// - /// [Bit 13] 1: Full width of counter writable via IA32_A_PMCx. - /// - UINT32 FW_WRITE:1; - UINT32 Reserved1:18; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_CAPABILITIES_REGISTER; - - -/** - Fixed-Function Performance Counter Control (R/W) Counter increments while - the results of ANDing respective enable bit in IA32_PERF_GLOBAL_CTRL with - the corresponding OS or USR bits in this MSR is true. If CPUID.0AH: EAX[7:0] - > 1. - - @param ECX MSR_IA32_FIXED_CTR_CTRL (0x0000038D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_FIXED_CTR_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_FIXED_CTR_CTRL_REGISTER. - - Example usage - @code - MSR_IA32_FIXED_CTR_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_FIXED_CTR_CTRL); - AsmWriteMsr64 (MSR_IA32_FIXED_CTR_CTRL, Msr.Uint64); - @endcode - @note MSR_IA32_FIXED_CTR_CTRL is defined as IA32_FIXED_CTR_CTRL in SDM. -**/ -#define MSR_IA32_FIXED_CTR_CTRL 0x0000038D - -/** - MSR information returned for MSR index #MSR_IA32_FIXED_CTR_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] EN0_OS: Enable Fixed Counter 0 to count while CPL = 0. - /// - UINT32 EN0_OS:1; - /// - /// [Bit 1] EN0_Usr: Enable Fixed Counter 0 to count while CPL > 0. - /// - UINT32 EN0_Usr:1; - /// - /// [Bit 2] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. If CPUID.0AH: EAX[7:0] > 2. - /// - UINT32 AnyThread0:1; - /// - /// [Bit 3] EN0_PMI: Enable PMI when fixed counter 0 overflows. - /// - UINT32 EN0_PMI:1; - /// - /// [Bit 4] EN1_OS: Enable Fixed Counter 1 to count while CPL = 0. - /// - UINT32 EN1_OS:1; - /// - /// [Bit 5] EN1_Usr: Enable Fixed Counter 1 to count while CPL > 0. - /// - UINT32 EN1_Usr:1; - /// - /// [Bit 6] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. If CPUID.0AH: EAX[7:0] > 2. - /// - UINT32 AnyThread1:1; - /// - /// [Bit 7] EN1_PMI: Enable PMI when fixed counter 1 overflows. - /// - UINT32 EN1_PMI:1; - /// - /// [Bit 8] EN2_OS: Enable Fixed Counter 2 to count while CPL = 0. - /// - UINT32 EN2_OS:1; - /// - /// [Bit 9] EN2_Usr: Enable Fixed Counter 2 to count while CPL > 0. - /// - UINT32 EN2_Usr:1; - /// - /// [Bit 10] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. If CPUID.0AH: EAX[7:0] > 2. - /// - UINT32 AnyThread2:1; - /// - /// [Bit 11] EN2_PMI: Enable PMI when fixed counter 2 overflows. - /// - UINT32 EN2_PMI:1; - UINT32 Reserved1:20; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_FIXED_CTR_CTRL_REGISTER; - - -/** - Global Performance Counter Status (RO). If CPUID.0AH: EAX[7:0] > 0. - - @param ECX MSR_IA32_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_STATUS); - @endcode - @note MSR_IA32_PERF_GLOBAL_STATUS is defined as IA32_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_STATUS 0x0000038E - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Ovf_PMC0: Overflow status of IA32_PMC0. If CPUID.0AH: - /// EAX[15:8] > 0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Ovf_PMC1: Overflow status of IA32_PMC1. If CPUID.0AH: - /// EAX[15:8] > 1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Ovf_PMC2: Overflow status of IA32_PMC2. If CPUID.0AH: - /// EAX[15:8] > 2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Ovf_PMC3: Overflow status of IA32_PMC3. If CPUID.0AH: - /// EAX[15:8] > 3. - /// - UINT32 Ovf_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Ovf_FixedCtr0: Overflow status of IA32_FIXED_CTR0. If - /// CPUID.0AH: EAX[7:0] > 1. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Ovf_FixedCtr1: Overflow status of IA32_FIXED_CTR1. If - /// CPUID.0AH: EAX[7:0] > 1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Ovf_FixedCtr2: Overflow status of IA32_FIXED_CTR2. If - /// CPUID.0AH: EAX[7:0] > 1. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Trace_ToPA_PMI: A PMI occurred due to a ToPA entry memory - /// buffer was completely filled. If (CPUID.(EAX=07H, ECX=0):EBX[25] = 1) - /// && IA32_RTIT_CTL.ToPA = 1. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] LBR_Frz: LBRs are frozen due to - - /// IA32_DEBUGCTL.FREEZE_LBR_ON_PMI=1, - The LBR stack overflowed. If - /// CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] CTR_Frz: Performance counters in the core PMU are frozen due - /// to - IA32_DEBUGCTL.FREEZE_PERFMON_ON_ PMI=1, - one or more core PMU - /// counters overflowed. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] ASCI: Data in the performance counters in the core PMU may - /// include contributions from the direct or indirect operation intel SGX - /// to protect an enclave. If CPUID.(EAX=07H, ECX=0):EBX[2] = 1. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Ovf_Uncore: Uncore counter overflow status. If CPUID.0AH: - /// EAX[7:0] > 2. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] OvfBuf: DS SAVE area Buffer overflow status. If CPUID.0AH: - /// EAX[7:0] > 0. - /// - UINT32 OvfBuf:1; - /// - /// [Bit 63] CondChgd: status bits of this register has changed. If - /// CPUID.0AH: EAX[7:0] > 0. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Global Performance Counter Control (R/W) Counter increments while the result - of ANDing respective enable bit in this MSR with the corresponding OS or USR - bits in the general-purpose or fixed counter control MSR is true. If - CPUID.0AH: EAX[7:0] > 0. - - @param ECX MSR_IA32_PERF_GLOBAL_CTRL (0x0000038F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_CTRL_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_IA32_PERF_GLOBAL_CTRL, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_GLOBAL_CTRL is defined as IA32_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_CTRL 0x0000038F - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_CTRL -**/ -typedef union { - /// - /// Individual bit fields -/// - struct { - /// - /// [Bits 31:0] EN_PMCn. If CPUID.0AH: EAX[15:8] > n. - /// Enable bitmask. Only the first n-1 bits are valid. - /// Bits n..31 are reserved. - /// - UINT32 EN_PMCn:32; - /// - /// [Bits 63:32] EN_FIXED_CTRn. If CPUID.0AH: EDX[4:0] > n. - /// Enable bitmask. Only the first n-1 bits are valid. - /// Bits 31:n are reserved. - /// - UINT32 EN_FIXED_CTRn:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_CTRL_REGISTER; - - -/** - Global Performance Counter Overflow Control (R/W). If CPUID.0AH: EAX[7:0] > - 0 && CPUID.0AH: EAX[7:0] <= 3. - - @param ECX MSR_IA32_PERF_GLOBAL_OVF_CTRL (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_IA32_PERF_GLOBAL_OVF_CTRL, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_GLOBAL_OVF_CTRL is defined as IA32_PERF_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_OVF_CTRL 0x00000390 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_OVF_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Set 1 to Clear Ovf_PMC0 bit. If CPUID.0AH: EAX[15:8] > n. - /// Clear bitmask. Only the first n-1 bits are valid. - /// Bits 31:n are reserved. - /// - UINT32 Ovf_PMCn:32; - /// - /// [Bits 54:32] Set 1 to Clear Ovf_FIXED_CTR0 bit. - /// If CPUID.0AH: EDX[4:0] > n. - /// Clear bitmask. Only the first n-1 bits are valid. - /// Bits 22:n are reserved. - /// - UINT32 Ovf_FIXED_CTRn:23; - /// - /// [Bit 55] Set 1 to Clear Trace_ToPA_PMI bit. If (CPUID.(EAX=07H, - /// ECX=0):EBX[25] = 1) && IA32_RTIT_CTL.ToPA = 1. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved2:5; - /// - /// [Bit 61] Set 1 to Clear Ovf_Uncore bit. Introduced at Display Family / - /// Display Model 06_2EH. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Set 1 to Clear OvfBuf: bit. If CPUID.0AH: EAX[7:0] > 0. - /// - UINT32 OvfBuf:1; - /// - /// [Bit 63] Set to 1to clear CondChgd: bit. If CPUID.0AH: EAX[7:0] > 0. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER; - - -/** - Global Performance Counter Overflow Reset Control (R/W). If CPUID.0AH: - EAX[7:0] > 3. - - @param ECX MSR_IA32_PERF_GLOBAL_STATUS_RESET (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_STATUS_RESET); - AsmWriteMsr64 (MSR_IA32_PERF_GLOBAL_STATUS_RESET, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_GLOBAL_STATUS_RESET is defined as IA32_PERF_GLOBAL_STATUS_RESET in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_STATUS_RESET 0x00000390 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_STATUS_RESET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Set 1 to Clear Ovf_PMC0 bit. If CPUID.0AH: EAX[15:8] > n. - /// Clear bitmask. Only the first n-1 bits are valid. - /// Bits 31:n are reserved. - /// - UINT32 Ovf_PMCn:32; - /// - /// [Bits 54:32] Set 1 to Clear Ovf_FIXED_CTR0 bit. - /// If CPUID.0AH: EDX[4:0] > n. - /// Clear bitmask. Only the first n-1 bits are valid. - /// Bits 22:n are reserved. - /// - UINT32 Ovf_FIXED_CTRn:23; - /// - /// [Bit 55] Set 1 to Clear Trace_ToPA_PMI bit. If (CPUID.(EAX=07H, - /// ECX=0):EBX[25] = 1) && IA32_RTIT_CTL.ToPA[8] = 1. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved2:2; - /// - /// [Bit 58] Set 1 to Clear LBR_Frz bit. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Set 1 to Clear CTR_Frz bit. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Set 1 to Clear ASCI bit. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Set 1 to Clear Ovf_Uncore bit. Introduced at Display Family / - /// Display Model 06_2EH. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Set 1 to Clear OvfBuf: bit. If CPUID.0AH: EAX[7:0] > 0. - /// - UINT32 OvfBuf:1; - /// - /// [Bit 63] Set to 1to clear CondChgd: bit. If CPUID.0AH: EAX[7:0] > 0. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER; - - -/** - Global Performance Counter Overflow Set Control (R/W). If CPUID.0AH: - EAX[7:0] > 3. - - @param ECX MSR_IA32_PERF_GLOBAL_STATUS_SET (0x00000391) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_STATUS_SET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_STATUS_SET); - AsmWriteMsr64 (MSR_IA32_PERF_GLOBAL_STATUS_SET, Msr.Uint64); - @endcode - @note MSR_IA32_PERF_GLOBAL_STATUS_SET is defined as IA32_PERF_GLOBAL_STATUS_SET in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_STATUS_SET 0x00000391 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_STATUS_SET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Set 1 to cause Ovf_PMCn = 1. If CPUID.0AH: EAX[7:0] > n. - /// Set bitmask. Only the first n-1 bits are valid. - /// Bits 31:n are reserved. - /// - UINT32 Ovf_PMCn:32; - /// - /// [Bits 54:32] Set 1 to cause Ovf_FIXED_CTRn = 1. - /// If CPUID.0AH: EAX[7:0] > n. - /// Set bitmask. Only the first n-1 bits are valid. - /// Bits 22:n are reserved. - /// - UINT32 Ovf_FIXED_CTRn:23; - /// - /// [Bit 55] Set 1 to cause Trace_ToPA_PMI = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved2:2; - /// - /// [Bit 58] Set 1 to cause LBR_Frz = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Set 1 to cause CTR_Frz = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Set 1 to cause ASCI = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Set 1 to cause Ovf_Uncore = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Set 1 to cause OvfBuf = 1. If CPUID.0AH: EAX[7:0] > 3. - /// - UINT32 OvfBuf:1; - UINT32 Reserved3:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_STATUS_SET_REGISTER; - - -/** - Indicator of core perfmon interface is in use (RO). If CPUID.0AH: EAX[7:0] > - 3. - - @param ECX MSR_IA32_PERF_GLOBAL_INUSE (0x00000392) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_INUSE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PERF_GLOBAL_INUSE_REGISTER. - - Example usage - @code - MSR_IA32_PERF_GLOBAL_INUSE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_INUSE); - @endcode - @note MSR_IA32_PERF_GLOBAL_INUSE is defined as IA32_PERF_GLOBAL_INUSE in SDM. -**/ -#define MSR_IA32_PERF_GLOBAL_INUSE 0x00000392 - -/** - MSR information returned for MSR index #MSR_IA32_PERF_GLOBAL_INUSE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] IA32_PERFEVTSELn in use. If CPUID.0AH: EAX[7:0] > n. - /// Status bitmask. Only the first n-1 bits are valid. - /// Bits 31:n are reserved. - /// - UINT32 IA32_PERFEVTSELn:32; - /// - /// [Bits 62:32] IA32_FIXED_CTRn in use. - /// If CPUID.0AH: EAX[7:0] > n. - /// Status bitmask. Only the first n-1 bits are valid. - /// Bits 30:n are reserved. - /// - UINT32 IA32_FIXED_CTRn:31; - /// - /// [Bit 63] PMI in use. - /// - UINT32 PMI:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PERF_GLOBAL_INUSE_REGISTER; - - -/** - PEBS Control (R/W). - - @param ECX MSR_IA32_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_IA32_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PEBS_ENABLE); - AsmWriteMsr64 (MSR_IA32_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_IA32_PEBS_ENABLE is defined as IA32_PEBS_ENABLE in SDM. -**/ -#define MSR_IA32_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_IA32_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. Introduced at Display Family / - /// Display Model 06_0FH. - /// - UINT32 Enable:1; - /// - /// [Bits 3:1] Reserved or Model specific. - /// - UINT32 Reserved1:3; - UINT32 Reserved2:28; - /// - /// [Bits 35:32] Reserved or Model specific. - /// - UINT32 Reserved3:4; - UINT32 Reserved4:28; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PEBS_ENABLE_REGISTER; - - -/** - MCn_CTL. If IA32_MCG_CAP.CNT > n. - - @param ECX MSR_IA32_MCn_CTL - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MC0_CTL); - AsmWriteMsr64 (MSR_IA32_MC0_CTL, Msr); - @endcode - @note MSR_IA32_MC0_CTL is defined as IA32_MC0_CTL in SDM. - MSR_IA32_MC1_CTL is defined as IA32_MC1_CTL in SDM. - MSR_IA32_MC2_CTL is defined as IA32_MC2_CTL in SDM. - MSR_IA32_MC3_CTL is defined as IA32_MC3_CTL in SDM. - MSR_IA32_MC4_CTL is defined as IA32_MC4_CTL in SDM. - MSR_IA32_MC5_CTL is defined as IA32_MC5_CTL in SDM. - MSR_IA32_MC6_CTL is defined as IA32_MC6_CTL in SDM. - MSR_IA32_MC7_CTL is defined as IA32_MC7_CTL in SDM. - MSR_IA32_MC8_CTL is defined as IA32_MC8_CTL in SDM. - MSR_IA32_MC9_CTL is defined as IA32_MC9_CTL in SDM. - MSR_IA32_MC10_CTL is defined as IA32_MC10_CTL in SDM. - MSR_IA32_MC11_CTL is defined as IA32_MC11_CTL in SDM. - MSR_IA32_MC12_CTL is defined as IA32_MC12_CTL in SDM. - MSR_IA32_MC13_CTL is defined as IA32_MC13_CTL in SDM. - MSR_IA32_MC14_CTL is defined as IA32_MC14_CTL in SDM. - MSR_IA32_MC15_CTL is defined as IA32_MC15_CTL in SDM. - MSR_IA32_MC16_CTL is defined as IA32_MC16_CTL in SDM. - MSR_IA32_MC17_CTL is defined as IA32_MC17_CTL in SDM. - MSR_IA32_MC18_CTL is defined as IA32_MC18_CTL in SDM. - MSR_IA32_MC19_CTL is defined as IA32_MC19_CTL in SDM. - MSR_IA32_MC20_CTL is defined as IA32_MC20_CTL in SDM. - MSR_IA32_MC21_CTL is defined as IA32_MC21_CTL in SDM. - MSR_IA32_MC22_CTL is defined as IA32_MC22_CTL in SDM. - MSR_IA32_MC23_CTL is defined as IA32_MC23_CTL in SDM. - MSR_IA32_MC24_CTL is defined as IA32_MC24_CTL in SDM. - MSR_IA32_MC25_CTL is defined as IA32_MC25_CTL in SDM. - MSR_IA32_MC26_CTL is defined as IA32_MC26_CTL in SDM. - MSR_IA32_MC27_CTL is defined as IA32_MC27_CTL in SDM. - MSR_IA32_MC28_CTL is defined as IA32_MC28_CTL in SDM. - @{ -**/ -#define MSR_IA32_MC0_CTL 0x00000400 -#define MSR_IA32_MC1_CTL 0x00000404 -#define MSR_IA32_MC2_CTL 0x00000408 -#define MSR_IA32_MC3_CTL 0x0000040C -#define MSR_IA32_MC4_CTL 0x00000410 -#define MSR_IA32_MC5_CTL 0x00000414 -#define MSR_IA32_MC6_CTL 0x00000418 -#define MSR_IA32_MC7_CTL 0x0000041C -#define MSR_IA32_MC8_CTL 0x00000420 -#define MSR_IA32_MC9_CTL 0x00000424 -#define MSR_IA32_MC10_CTL 0x00000428 -#define MSR_IA32_MC11_CTL 0x0000042C -#define MSR_IA32_MC12_CTL 0x00000430 -#define MSR_IA32_MC13_CTL 0x00000434 -#define MSR_IA32_MC14_CTL 0x00000438 -#define MSR_IA32_MC15_CTL 0x0000043C -#define MSR_IA32_MC16_CTL 0x00000440 -#define MSR_IA32_MC17_CTL 0x00000444 -#define MSR_IA32_MC18_CTL 0x00000448 -#define MSR_IA32_MC19_CTL 0x0000044C -#define MSR_IA32_MC20_CTL 0x00000450 -#define MSR_IA32_MC21_CTL 0x00000454 -#define MSR_IA32_MC22_CTL 0x00000458 -#define MSR_IA32_MC23_CTL 0x0000045C -#define MSR_IA32_MC24_CTL 0x00000460 -#define MSR_IA32_MC25_CTL 0x00000464 -#define MSR_IA32_MC26_CTL 0x00000468 -#define MSR_IA32_MC27_CTL 0x0000046C -#define MSR_IA32_MC28_CTL 0x00000470 -/// @} - - -/** - MCn_STATUS. If IA32_MCG_CAP.CNT > n. - - @param ECX MSR_IA32_MCn_STATUS - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MC0_STATUS); - AsmWriteMsr64 (MSR_IA32_MC0_STATUS, Msr); - @endcode - @note MSR_IA32_MC0_STATUS is defined as IA32_MC0_STATUS in SDM. - MSR_IA32_MC1_STATUS is defined as IA32_MC1_STATUS in SDM. - MSR_IA32_MC2_STATUS is defined as IA32_MC2_STATUS in SDM. - MSR_IA32_MC3_STATUS is defined as IA32_MC3_STATUS in SDM. - MSR_IA32_MC4_STATUS is defined as IA32_MC4_STATUS in SDM. - MSR_IA32_MC5_STATUS is defined as IA32_MC5_STATUS in SDM. - MSR_IA32_MC6_STATUS is defined as IA32_MC6_STATUS in SDM. - MSR_IA32_MC7_STATUS is defined as IA32_MC7_STATUS in SDM. - MSR_IA32_MC8_STATUS is defined as IA32_MC8_STATUS in SDM. - MSR_IA32_MC9_STATUS is defined as IA32_MC9_STATUS in SDM. - MSR_IA32_MC10_STATUS is defined as IA32_MC10_STATUS in SDM. - MSR_IA32_MC11_STATUS is defined as IA32_MC11_STATUS in SDM. - MSR_IA32_MC12_STATUS is defined as IA32_MC12_STATUS in SDM. - MSR_IA32_MC13_STATUS is defined as IA32_MC13_STATUS in SDM. - MSR_IA32_MC14_STATUS is defined as IA32_MC14_STATUS in SDM. - MSR_IA32_MC15_STATUS is defined as IA32_MC15_STATUS in SDM. - MSR_IA32_MC16_STATUS is defined as IA32_MC16_STATUS in SDM. - MSR_IA32_MC17_STATUS is defined as IA32_MC17_STATUS in SDM. - MSR_IA32_MC18_STATUS is defined as IA32_MC18_STATUS in SDM. - MSR_IA32_MC19_STATUS is defined as IA32_MC19_STATUS in SDM. - MSR_IA32_MC20_STATUS is defined as IA32_MC20_STATUS in SDM. - MSR_IA32_MC21_STATUS is defined as IA32_MC21_STATUS in SDM. - MSR_IA32_MC22_STATUS is defined as IA32_MC22_STATUS in SDM. - MSR_IA32_MC23_STATUS is defined as IA32_MC23_STATUS in SDM. - MSR_IA32_MC24_STATUS is defined as IA32_MC24_STATUS in SDM. - MSR_IA32_MC25_STATUS is defined as IA32_MC25_STATUS in SDM. - MSR_IA32_MC26_STATUS is defined as IA32_MC26_STATUS in SDM. - MSR_IA32_MC27_STATUS is defined as IA32_MC27_STATUS in SDM. - MSR_IA32_MC28_STATUS is defined as IA32_MC28_STATUS in SDM. - @{ -**/ -#define MSR_IA32_MC0_STATUS 0x00000401 -#define MSR_IA32_MC1_STATUS 0x00000405 -#define MSR_IA32_MC2_STATUS 0x00000409 -#define MSR_IA32_MC3_STATUS 0x0000040D -#define MSR_IA32_MC4_STATUS 0x00000411 -#define MSR_IA32_MC5_STATUS 0x00000415 -#define MSR_IA32_MC6_STATUS 0x00000419 -#define MSR_IA32_MC7_STATUS 0x0000041D -#define MSR_IA32_MC8_STATUS 0x00000421 -#define MSR_IA32_MC9_STATUS 0x00000425 -#define MSR_IA32_MC10_STATUS 0x00000429 -#define MSR_IA32_MC11_STATUS 0x0000042D -#define MSR_IA32_MC12_STATUS 0x00000431 -#define MSR_IA32_MC13_STATUS 0x00000435 -#define MSR_IA32_MC14_STATUS 0x00000439 -#define MSR_IA32_MC15_STATUS 0x0000043D -#define MSR_IA32_MC16_STATUS 0x00000441 -#define MSR_IA32_MC17_STATUS 0x00000445 -#define MSR_IA32_MC18_STATUS 0x00000449 -#define MSR_IA32_MC19_STATUS 0x0000044D -#define MSR_IA32_MC20_STATUS 0x00000451 -#define MSR_IA32_MC21_STATUS 0x00000455 -#define MSR_IA32_MC22_STATUS 0x00000459 -#define MSR_IA32_MC23_STATUS 0x0000045D -#define MSR_IA32_MC24_STATUS 0x00000461 -#define MSR_IA32_MC25_STATUS 0x00000465 -#define MSR_IA32_MC26_STATUS 0x00000469 -#define MSR_IA32_MC27_STATUS 0x0000046D -#define MSR_IA32_MC28_STATUS 0x00000471 -/// @} - - -/** - MCn_ADDR. If IA32_MCG_CAP.CNT > n. - - @param ECX MSR_IA32_MCn_ADDR - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MC0_ADDR); - AsmWriteMsr64 (MSR_IA32_MC0_ADDR, Msr); - @endcode - @note MSR_IA32_MC0_ADDR is defined as IA32_MC0_ADDR in SDM. - MSR_IA32_MC1_ADDR is defined as IA32_MC1_ADDR in SDM. - MSR_IA32_MC2_ADDR is defined as IA32_MC2_ADDR in SDM. - MSR_IA32_MC3_ADDR is defined as IA32_MC3_ADDR in SDM. - MSR_IA32_MC4_ADDR is defined as IA32_MC4_ADDR in SDM. - MSR_IA32_MC5_ADDR is defined as IA32_MC5_ADDR in SDM. - MSR_IA32_MC6_ADDR is defined as IA32_MC6_ADDR in SDM. - MSR_IA32_MC7_ADDR is defined as IA32_MC7_ADDR in SDM. - MSR_IA32_MC8_ADDR is defined as IA32_MC8_ADDR in SDM. - MSR_IA32_MC9_ADDR is defined as IA32_MC9_ADDR in SDM. - MSR_IA32_MC10_ADDR is defined as IA32_MC10_ADDR in SDM. - MSR_IA32_MC11_ADDR is defined as IA32_MC11_ADDR in SDM. - MSR_IA32_MC12_ADDR is defined as IA32_MC12_ADDR in SDM. - MSR_IA32_MC13_ADDR is defined as IA32_MC13_ADDR in SDM. - MSR_IA32_MC14_ADDR is defined as IA32_MC14_ADDR in SDM. - MSR_IA32_MC15_ADDR is defined as IA32_MC15_ADDR in SDM. - MSR_IA32_MC16_ADDR is defined as IA32_MC16_ADDR in SDM. - MSR_IA32_MC17_ADDR is defined as IA32_MC17_ADDR in SDM. - MSR_IA32_MC18_ADDR is defined as IA32_MC18_ADDR in SDM. - MSR_IA32_MC19_ADDR is defined as IA32_MC19_ADDR in SDM. - MSR_IA32_MC20_ADDR is defined as IA32_MC20_ADDR in SDM. - MSR_IA32_MC21_ADDR is defined as IA32_MC21_ADDR in SDM. - MSR_IA32_MC22_ADDR is defined as IA32_MC22_ADDR in SDM. - MSR_IA32_MC23_ADDR is defined as IA32_MC23_ADDR in SDM. - MSR_IA32_MC24_ADDR is defined as IA32_MC24_ADDR in SDM. - MSR_IA32_MC25_ADDR is defined as IA32_MC25_ADDR in SDM. - MSR_IA32_MC26_ADDR is defined as IA32_MC26_ADDR in SDM. - MSR_IA32_MC27_ADDR is defined as IA32_MC27_ADDR in SDM. - MSR_IA32_MC28_ADDR is defined as IA32_MC28_ADDR in SDM. - @{ -**/ -#define MSR_IA32_MC0_ADDR 0x00000402 -#define MSR_IA32_MC1_ADDR 0x00000406 -#define MSR_IA32_MC2_ADDR 0x0000040A -#define MSR_IA32_MC3_ADDR 0x0000040E -#define MSR_IA32_MC4_ADDR 0x00000412 -#define MSR_IA32_MC5_ADDR 0x00000416 -#define MSR_IA32_MC6_ADDR 0x0000041A -#define MSR_IA32_MC7_ADDR 0x0000041E -#define MSR_IA32_MC8_ADDR 0x00000422 -#define MSR_IA32_MC9_ADDR 0x00000426 -#define MSR_IA32_MC10_ADDR 0x0000042A -#define MSR_IA32_MC11_ADDR 0x0000042E -#define MSR_IA32_MC12_ADDR 0x00000432 -#define MSR_IA32_MC13_ADDR 0x00000436 -#define MSR_IA32_MC14_ADDR 0x0000043A -#define MSR_IA32_MC15_ADDR 0x0000043E -#define MSR_IA32_MC16_ADDR 0x00000442 -#define MSR_IA32_MC17_ADDR 0x00000446 -#define MSR_IA32_MC18_ADDR 0x0000044A -#define MSR_IA32_MC19_ADDR 0x0000044E -#define MSR_IA32_MC20_ADDR 0x00000452 -#define MSR_IA32_MC21_ADDR 0x00000456 -#define MSR_IA32_MC22_ADDR 0x0000045A -#define MSR_IA32_MC23_ADDR 0x0000045E -#define MSR_IA32_MC24_ADDR 0x00000462 -#define MSR_IA32_MC25_ADDR 0x00000466 -#define MSR_IA32_MC26_ADDR 0x0000046A -#define MSR_IA32_MC27_ADDR 0x0000046E -#define MSR_IA32_MC28_ADDR 0x00000472 -/// @} - - -/** - MCn_MISC. If IA32_MCG_CAP.CNT > n. - - @param ECX MSR_IA32_MCn_MISC - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_MC0_MISC); - AsmWriteMsr64 (MSR_IA32_MC0_MISC, Msr); - @endcode - @note MSR_IA32_MC0_MISC is defined as IA32_MC0_MISC in SDM. - MSR_IA32_MC1_MISC is defined as IA32_MC1_MISC in SDM. - MSR_IA32_MC2_MISC is defined as IA32_MC2_MISC in SDM. - MSR_IA32_MC3_MISC is defined as IA32_MC3_MISC in SDM. - MSR_IA32_MC4_MISC is defined as IA32_MC4_MISC in SDM. - MSR_IA32_MC5_MISC is defined as IA32_MC5_MISC in SDM. - MSR_IA32_MC6_MISC is defined as IA32_MC6_MISC in SDM. - MSR_IA32_MC7_MISC is defined as IA32_MC7_MISC in SDM. - MSR_IA32_MC8_MISC is defined as IA32_MC8_MISC in SDM. - MSR_IA32_MC9_MISC is defined as IA32_MC9_MISC in SDM. - MSR_IA32_MC10_MISC is defined as IA32_MC10_MISC in SDM. - MSR_IA32_MC11_MISC is defined as IA32_MC11_MISC in SDM. - MSR_IA32_MC12_MISC is defined as IA32_MC12_MISC in SDM. - MSR_IA32_MC13_MISC is defined as IA32_MC13_MISC in SDM. - MSR_IA32_MC14_MISC is defined as IA32_MC14_MISC in SDM. - MSR_IA32_MC15_MISC is defined as IA32_MC15_MISC in SDM. - MSR_IA32_MC16_MISC is defined as IA32_MC16_MISC in SDM. - MSR_IA32_MC17_MISC is defined as IA32_MC17_MISC in SDM. - MSR_IA32_MC18_MISC is defined as IA32_MC18_MISC in SDM. - MSR_IA32_MC19_MISC is defined as IA32_MC19_MISC in SDM. - MSR_IA32_MC20_MISC is defined as IA32_MC20_MISC in SDM. - MSR_IA32_MC21_MISC is defined as IA32_MC21_MISC in SDM. - MSR_IA32_MC22_MISC is defined as IA32_MC22_MISC in SDM. - MSR_IA32_MC23_MISC is defined as IA32_MC23_MISC in SDM. - MSR_IA32_MC24_MISC is defined as IA32_MC24_MISC in SDM. - MSR_IA32_MC25_MISC is defined as IA32_MC25_MISC in SDM. - MSR_IA32_MC26_MISC is defined as IA32_MC26_MISC in SDM. - MSR_IA32_MC27_MISC is defined as IA32_MC27_MISC in SDM. - MSR_IA32_MC28_MISC is defined as IA32_MC28_MISC in SDM. - @{ -**/ -#define MSR_IA32_MC0_MISC 0x00000403 -#define MSR_IA32_MC1_MISC 0x00000407 -#define MSR_IA32_MC2_MISC 0x0000040B -#define MSR_IA32_MC3_MISC 0x0000040F -#define MSR_IA32_MC4_MISC 0x00000413 -#define MSR_IA32_MC5_MISC 0x00000417 -#define MSR_IA32_MC6_MISC 0x0000041B -#define MSR_IA32_MC7_MISC 0x0000041F -#define MSR_IA32_MC8_MISC 0x00000423 -#define MSR_IA32_MC9_MISC 0x00000427 -#define MSR_IA32_MC10_MISC 0x0000042B -#define MSR_IA32_MC11_MISC 0x0000042F -#define MSR_IA32_MC12_MISC 0x00000433 -#define MSR_IA32_MC13_MISC 0x00000437 -#define MSR_IA32_MC14_MISC 0x0000043B -#define MSR_IA32_MC15_MISC 0x0000043F -#define MSR_IA32_MC16_MISC 0x00000443 -#define MSR_IA32_MC17_MISC 0x00000447 -#define MSR_IA32_MC18_MISC 0x0000044B -#define MSR_IA32_MC19_MISC 0x0000044F -#define MSR_IA32_MC20_MISC 0x00000453 -#define MSR_IA32_MC21_MISC 0x00000457 -#define MSR_IA32_MC22_MISC 0x0000045B -#define MSR_IA32_MC23_MISC 0x0000045F -#define MSR_IA32_MC24_MISC 0x00000463 -#define MSR_IA32_MC25_MISC 0x00000467 -#define MSR_IA32_MC26_MISC 0x0000046B -#define MSR_IA32_MC27_MISC 0x0000046F -#define MSR_IA32_MC28_MISC 0x00000473 -/// @} - - -/** - Reporting Register of Basic VMX Capabilities (R/O) See Appendix A.1, "Basic - VMX Information.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_BASIC (0x00000480) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - MSR_IA32_VMX_BASIC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_VMX_BASIC); - @endcode - @note MSR_IA32_VMX_BASIC is defined as IA32_VMX_BASIC in SDM. -**/ -#define MSR_IA32_VMX_BASIC 0x00000480 - -/** - MSR information returned for MSR index #MSR_IA32_VMX_BASIC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 30:0] VMCS revision identifier used by the processor. Processors - /// that use the same VMCS revision identifier use the same size for VMCS - /// regions (see subsequent item on bits 44:32). - /// - /// @note Earlier versions of this manual specified that the VMCS revision - /// identifier was a 32-bit field in bits 31:0 of this MSR. For all - /// processors produced prior to this change, bit 31 of this MSR was read - /// as 0. - /// - UINT32 VmcsRevisonId:31; - UINT32 MustBeZero:1; - /// - /// [Bit 44:32] Reports the number of bytes that software should allocate - /// for the VMXON region and any VMCS region. It is a value greater than - /// 0 and at most 4096(bit 44 is set if and only if bits 43:32 are clear). - /// - UINT32 VmcsSize:13; - UINT32 Reserved1:3; - /// - /// [Bit 48] Indicates the width of the physical addresses that may be used - /// for the VMXON region, each VMCS, and data structures referenced by - /// pointers in a VMCS (I/O bitmaps, virtual-APIC page, MSR areas for VMX - /// transitions). If the bit is 0, these addresses are limited to the - /// processor's physical-address width. If the bit is 1, these addresses - /// are limited to 32 bits. This bit is always 0 for processors that - /// support Intel 64 architecture. - /// - /// @note On processors that support Intel 64 architecture, the pointer - /// must not set bits beyond the processor's physical address width. - /// - UINT32 VmcsAddressWidth:1; - /// - /// [Bit 49] If bit 49 is read as 1, the logical processor supports the - /// dual-monitor treatment of system-management interrupts and - /// system-management mode. See Section 34.15 for details of this treatment. - /// - UINT32 DualMonitor:1; - /// - /// [Bit 53:50] report the memory type that should be used for the VMCS, - /// for data structures referenced by pointers in the VMCS (I/O bitmaps, - /// virtual-APIC page, MSR areas for VMX transitions), and for the MSEG - /// header. If software needs to access these data structures (e.g., to - /// modify the contents of the MSR bitmaps), it can configure the paging - /// structures to map them into the linear-address space. If it does so, - /// it should establish mappings that use the memory type reported bits - /// 53:50 in this MSR. - /// - /// As of this writing, all processors that support VMX operation indicate - /// the write-back type. - /// - /// If software needs to access these data structures (e.g., to modify - /// the contents of the MSR bitmaps), it can configure the paging - /// structures to map them into the linear-address space. If it does so, - /// it should establish mappings that use the memory type reported in this - /// MSR. - /// - /// @note Alternatively, software may map any of these regions or - /// structures with the UC memory type. (This may be necessary for the MSEG - /// header.) Doing so is discouraged unless necessary as it will cause the - /// performance of software accesses to those structures to suffer. - /// - /// - UINT32 MemoryType:4; - /// - /// [Bit 54] If bit 54 is read as 1, the processor reports information in - /// the VM-exit instruction-information field on VM exitsdue to execution - /// of the INS and OUTS instructions (see Section 27.2.4). This reporting - /// is done only if this bit is read as 1. - /// - UINT32 InsOutsReporting:1; - /// - /// [Bit 55] Bit 55 is read as 1 if any VMX controls that default to 1 may - /// be cleared to 0. See Appendix A.2 for details. It also reports support - /// for the VMX capability MSRs IA32_VMX_TRUE_PINBASED_CTLS, - /// IA32_VMX_TRUE_PROCBASED_CTLS, IA32_VMX_TRUE_EXIT_CTLS, and - /// IA32_VMX_TRUE_ENTRY_CTLS. See Appendix A.3.1, Appendix A.3.2, - /// Appendix A.4, and Appendix A.5 for details. - /// - UINT32 VmxControls:1; - UINT32 Reserved2:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_VMX_BASIC_REGISTER; - -/// -/// @{ Define value for bit field MSR_IA32_VMX_BASIC_REGISTER.MemoryType -/// -#define MSR_IA32_VMX_BASIC_REGISTER_MEMORY_TYPE_UNCACHEABLE 0x00 -#define MSR_IA32_VMX_BASIC_REGISTER_MEMORY_TYPE_WRITE_BACK 0x06 -/// -/// @} -/// - - -/** - Capability Reporting Register of Pinbased VM-execution Controls (R/O) See - Appendix A.3.1, "Pin-Based VMExecution Controls.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_PINBASED_CTLS (0x00000481) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_PINBASED_CTLS); - @endcode - @note MSR_IA32_VMX_PINBASED_CTLS is defined as IA32_VMX_PINBASED_CTLS in SDM. -**/ -#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 - - -/** - Capability Reporting Register of Primary Processor-based VM-execution - Controls (R/O) See Appendix A.3.2, "Primary Processor- Based VM-Execution - Controls.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_PROCBASED_CTLS (0x00000482) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_PROCBASED_CTLS); - @endcode - @note MSR_IA32_VMX_PROCBASED_CTLS is defined as IA32_VMX_PROCBASED_CTLS in SDM. -**/ -#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 - - -/** - Capability Reporting Register of VM-exit Controls (R/O) See Appendix A.4, - "VM-Exit Controls.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_EXIT_CTLS (0x00000483) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_EXIT_CTLS); - @endcode - @note MSR_IA32_VMX_EXIT_CTLS is defined as IA32_VMX_EXIT_CTLS in SDM. -**/ -#define MSR_IA32_VMX_EXIT_CTLS 0x00000483 - - -/** - Capability Reporting Register of VMentry Controls (R/O) See Appendix A.5, - "VM-Entry Controls.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_ENTRY_CTLS (0x00000484) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_ENTRY_CTLS); - @endcode - @note MSR_IA32_VMX_ENTRY_CTLS is defined as IA32_VMX_ENTRY_CTLS in SDM. -**/ -#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 - - -/** - Reporting Register of Miscellaneous VMX Capabilities (R/O) See Appendix A.6, - "Miscellaneous Data.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_MISC (0x00000485) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - IA32_VMX_MISC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_VMX_MISC); - @endcode - @note MSR_IA32_VMX_MISC is defined as IA32_VMX_MISC in SDM. -**/ -#define MSR_IA32_VMX_MISC 0x00000485 - -/** - MSR information returned for MSR index #IA32_VMX_MISC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Reports a value X that specifies the relationship between the - /// rate of the VMX-preemption timer and that of the timestamp counter (TSC). - /// Specifically, the VMX-preemption timer (if it is active) counts down by - /// 1 every time bit X in the TSC changes due to a TSC increment. - /// - UINT32 VmxTimerRatio:5; - /// - /// [Bit 5] If bit 5 is read as 1, VM exits store the value of IA32_EFER.LMA - /// into the "IA-32e mode guest" VM-entry control;see Section 27.2 for more - /// details. This bit is read as 1 on any logical processor that supports - /// the 1-setting of the "unrestricted guest" VM-execution control. - /// - UINT32 VmExitEferLma:1; - /// - /// [Bit 6] reports (if set) the support for activity state 1 (HLT). - /// - UINT32 HltActivityStateSupported:1; - /// - /// [Bit 7] reports (if set) the support for activity state 2 (shutdown). - /// - UINT32 ShutdownActivityStateSupported:1; - /// - /// [Bit 8] reports (if set) the support for activity state 3 (wait-for-SIPI). - /// - UINT32 WaitForSipiActivityStateSupported:1; - UINT32 Reserved1:5; - /// - /// [Bit 14] If read as 1, Intel(R) Processor Trace (Intel PT) can be used - /// in VMX operation. If the processor supports Intel PT but does not allow - /// it to be used in VMX operation, execution of VMXON clears - /// IA32_RTIT_CTL.TraceEn (see "VMXON-Enter VMX Operation" in Chapter 30); - /// any attempt to set that bit while in VMX operation (including VMX root - /// operation) using the WRMSR instruction causes a general-protection - /// exception. - /// - UINT32 ProcessorTraceSupported:1; - /// - /// [Bit 15] If read as 1, the RDMSR instruction can be used in system- - /// management mode (SMM) to read the IA32_SMBASE MSR (MSR address 9EH). - /// See Section 34.15.6.3. - /// - UINT32 SmBaseMsrSupported:1; - /// - /// [Bits 24:16] Indicate the number of CR3-target values supported by the - /// processor. This number is a value between 0 and 256, inclusive (bit 24 - /// is set if and only if bits 23:16 are clear). - /// - UINT32 NumberOfCr3TargetValues:9; - /// - /// [Bit 27:25] Bits 27:25 is used to compute the recommended maximum - /// number of MSRs that should appear in the VM-exit MSR-store list, the - /// VM-exit MSR-load list, or the VM-entry MSR-load list. Specifically, if - /// the value bits 27:25 of IA32_VMX_MISC is N, then 512 * (N + 1) is the - /// recommended maximum number of MSRs to be included in each list. If the - /// limit is exceeded, undefined processor behavior may result (including a - /// machine check during the VMX transition). - /// - UINT32 MsrStoreListMaximum:3; - /// - /// [Bit 28] If read as 1, bit 2 of the IA32_SMM_MONITOR_CTL can be set - /// to 1. VMXOFF unblocks SMIs unless IA32_SMM_MONITOR_CTL[bit 2] is 1 - /// (see Section 34.14.4). - /// - UINT32 BlockSmiSupported:1; - /// - /// [Bit 29] read as 1, software can use VMWRITE to write to any supported - /// field in the VMCS; otherwise, VMWRITE cannot be used to modify VM-exit - /// information fields. - /// - UINT32 VmWriteSupported:1; - /// - /// [Bit 30] If read as 1, VM entry allows injection of a software - /// interrupt, software exception, or privileged software exception with an - /// instruction length of 0. - /// - UINT32 VmInjectSupported:1; - UINT32 Reserved2:1; - /// - /// [Bits 63:32] Reports the 32-bit MSEG revision identifier used by the - /// processor. - /// - UINT32 MsegRevisionIdentifier:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} IA32_VMX_MISC_REGISTER; - - -/** - Capability Reporting Register of CR0 Bits Fixed to 0 (R/O) See Appendix A.7, - "VMX-Fixed Bits in CR0.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_CR0_FIXED0 (0x00000486) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_CR0_FIXED0); - @endcode - @note MSR_IA32_VMX_CR0_FIXED0 is defined as IA32_VMX_CR0_FIXED0 in SDM. -**/ -#define MSR_IA32_VMX_CR0_FIXED0 0x00000486 - - -/** - Capability Reporting Register of CR0 Bits Fixed to 1 (R/O) See Appendix A.7, - "VMX-Fixed Bits in CR0.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_CR0_FIXED1 (0x00000487) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_CR0_FIXED1); - @endcode - @note MSR_IA32_VMX_CR0_FIXED1 is defined as IA32_VMX_CR0_FIXED1 in SDM. -**/ -#define MSR_IA32_VMX_CR0_FIXED1 0x00000487 - - -/** - Capability Reporting Register of CR4 Bits Fixed to 0 (R/O) See Appendix A.8, - "VMX-Fixed Bits in CR4.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_CR4_FIXED0 (0x00000488) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_CR4_FIXED0); - @endcode - @note MSR_IA32_VMX_CR4_FIXED0 is defined as IA32_VMX_CR4_FIXED0 in SDM. -**/ -#define MSR_IA32_VMX_CR4_FIXED0 0x00000488 - - -/** - Capability Reporting Register of CR4 Bits Fixed to 1 (R/O) See Appendix A.8, - "VMX-Fixed Bits in CR4.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_CR4_FIXED1 (0x00000489) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_CR4_FIXED1); - @endcode - @note MSR_IA32_VMX_CR4_FIXED1 is defined as IA32_VMX_CR4_FIXED1 in SDM. -**/ -#define MSR_IA32_VMX_CR4_FIXED1 0x00000489 - - -/** - Capability Reporting Register of VMCS Field Enumeration (R/O) See Appendix - A.9, "VMCS Enumeration.". If CPUID.01H:ECX.[5] = 1. - - @param ECX MSR_IA32_VMX_VMCS_ENUM (0x0000048A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_VMCS_ENUM); - @endcode - @note MSR_IA32_VMX_VMCS_ENUM is defined as IA32_VMX_VMCS_ENUM in SDM. -**/ -#define MSR_IA32_VMX_VMCS_ENUM 0x0000048A - - -/** - Capability Reporting Register of Secondary Processor-based VM-execution - Controls (R/O) See Appendix A.3.3, "Secondary Processor- Based VM-Execution - Controls.". If ( CPUID.01H:ECX.[5] && IA32_VMX_PROCBASED_C TLS[63]). - - @param ECX MSR_IA32_VMX_PROCBASED_CTLS2 (0x0000048B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_PROCBASED_CTLS2); - @endcode - @note MSR_IA32_VMX_PROCBASED_CTLS2 is defined as IA32_VMX_PROCBASED_CTLS2 in SDM. -**/ -#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048B - - -/** - Capability Reporting Register of EPT and VPID (R/O) See Appendix A.10, - "VPID and EPT Capabilities.". If ( CPUID.01H:ECX.[5] && IA32_VMX_PROCBASED_C - TLS[63] && ( IA32_VMX_PROCBASED_C TLS2[33] IA32_VMX_PROCBASED_C TLS2[37]) ). - - @param ECX MSR_IA32_VMX_EPT_VPID_CAP (0x0000048C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_EPT_VPID_CAP); - @endcode - @note MSR_IA32_VMX_EPT_VPID_CAP is defined as IA32_VMX_EPT_VPID_CAP in SDM. -**/ -#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048C - - -/** - Capability Reporting Register of Pinbased VM-execution Flex Controls (R/O) - See Appendix A.3.1, "Pin-Based VMExecution Controls.". If ( - CPUID.01H:ECX.[5] = 1 && IA32_VMX_BASIC[55] ). - - @param ECX MSR_IA32_VMX_TRUE_PINBASED_CTLS (0x0000048D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_PINBASED_CTLS); - @endcode - @note MSR_IA32_VMX_TRUE_PINBASED_CTLS is defined as IA32_VMX_TRUE_PINBASED_CTLS in SDM. -**/ -#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048D - - -/** - Capability Reporting Register of Primary Processor-based VM-execution Flex - Controls (R/O) See Appendix A.3.2, "Primary Processor- Based VM-Execution - Controls.". If( CPUID.01H:ECX.[5] = 1 && IA32_VMX_BASIC[55] ). - - @param ECX MSR_IA32_VMX_TRUE_PROCBASED_CTLS (0x0000048E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_PROCBASED_CTLS); - @endcode - @note MSR_IA32_VMX_TRUE_PROCBASED_CTLS is defined as IA32_VMX_TRUE_PROCBASED_CTLS in SDM. -**/ -#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048E - - -/** - Capability Reporting Register of VM-exit Flex Controls (R/O) See Appendix - A.4, "VM-Exit Controls.". If( CPUID.01H:ECX.[5] = 1 && IA32_VMX_BASIC[55] ). - - @param ECX MSR_IA32_VMX_TRUE_EXIT_CTLS (0x0000048F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_EXIT_CTLS); - @endcode - @note MSR_IA32_VMX_TRUE_EXIT_CTLS is defined as IA32_VMX_TRUE_EXIT_CTLS in SDM. -**/ -#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048F - - -/** - Capability Reporting Register of VMentry Flex Controls (R/O) See Appendix - A.5, "VM-Entry Controls.". If( CPUID.01H:ECX.[5] = 1 && IA32_VMX_BASIC[55] ). - - @param ECX MSR_IA32_VMX_TRUE_ENTRY_CTLS (0x00000490) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_ENTRY_CTLS); - @endcode - @note MSR_IA32_VMX_TRUE_ENTRY_CTLS is defined as IA32_VMX_TRUE_ENTRY_CTLS in SDM. -**/ -#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 - - -/** - Capability Reporting Register of VMfunction Controls (R/O). If( - CPUID.01H:ECX.[5] = 1 && IA32_VMX_BASIC[55] ). - - @param ECX MSR_IA32_VMX_VMFUNC (0x00000491) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_VMX_VMFUNC); - @endcode - @note MSR_IA32_VMX_VMFUNC is defined as IA32_VMX_VMFUNC in SDM. -**/ -#define MSR_IA32_VMX_VMFUNC 0x00000491 - - -/** - Full Width Writable IA32_PMCn Alias (R/W). (If CPUID.0AH: EAX[15:8] > n) && - IA32_PERF_CAPABILITIES[ 13] = 1. - - @param ECX MSR_IA32_A_PMCn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_A_PMC0); - AsmWriteMsr64 (MSR_IA32_A_PMC0, Msr); - @endcode - @note MSR_IA32_A_PMC0 is defined as IA32_A_PMC0 in SDM. - MSR_IA32_A_PMC1 is defined as IA32_A_PMC1 in SDM. - MSR_IA32_A_PMC2 is defined as IA32_A_PMC2 in SDM. - MSR_IA32_A_PMC3 is defined as IA32_A_PMC3 in SDM. - MSR_IA32_A_PMC4 is defined as IA32_A_PMC4 in SDM. - MSR_IA32_A_PMC5 is defined as IA32_A_PMC5 in SDM. - MSR_IA32_A_PMC6 is defined as IA32_A_PMC6 in SDM. - MSR_IA32_A_PMC7 is defined as IA32_A_PMC7 in SDM. - @{ -**/ -#define MSR_IA32_A_PMC0 0x000004C1 -#define MSR_IA32_A_PMC1 0x000004C2 -#define MSR_IA32_A_PMC2 0x000004C3 -#define MSR_IA32_A_PMC3 0x000004C4 -#define MSR_IA32_A_PMC4 0x000004C5 -#define MSR_IA32_A_PMC5 0x000004C6 -#define MSR_IA32_A_PMC6 0x000004C7 -#define MSR_IA32_A_PMC7 0x000004C8 -/// @} - - -/** - (R/W). If IA32_MCG_CAP.LMCE_P =1. - - @param ECX MSR_IA32_MCG_EXT_CTL (0x000004D0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_MCG_EXT_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_MCG_EXT_CTL_REGISTER. - - Example usage - @code - MSR_IA32_MCG_EXT_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_EXT_CTL); - AsmWriteMsr64 (MSR_IA32_MCG_EXT_CTL, Msr.Uint64); - @endcode - @note MSR_IA32_MCG_EXT_CTL is defined as IA32_MCG_EXT_CTL in SDM. -**/ -#define MSR_IA32_MCG_EXT_CTL 0x000004D0 - -/** - MSR information returned for MSR index #MSR_IA32_MCG_EXT_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LMCE_EN. - /// - UINT32 LMCE_EN:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_MCG_EXT_CTL_REGISTER; - - -/** - Status and SVN Threshold of SGX Support for ACM (RO). If CPUID.(EAX=07H, - ECX=0H): EBX[2] = 1. - - @param ECX MSR_IA32_SGX_SVN_STATUS (0x00000500) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_SGX_SVN_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_SGX_SVN_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_SGX_SVN_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SGX_SVN_STATUS); - @endcode - @note MSR_IA32_SGX_SVN_STATUS is defined as IA32_SGX_SVN_STATUS in SDM. -**/ -#define MSR_IA32_SGX_SVN_STATUS 0x00000500 - -/** - MSR information returned for MSR index #MSR_IA32_SGX_SVN_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock. See Section 42.11.3, "Interactions with Authenticated - /// Code Modules (ACMs)". - /// - UINT32 Lock:1; - UINT32 Reserved1:15; - /// - /// [Bits 23:16] SGX_SVN_SINIT. See Section 42.11.3, "Interactions with - /// Authenticated Code Modules (ACMs)". - /// - UINT32 SGX_SVN_SINIT:8; - UINT32 Reserved2:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_SGX_SVN_STATUS_REGISTER; - - -/** - Trace Output Base Register (R/W). If ((CPUID.(EAX=07H, ECX=0):EBX[25] = 1) - && ( (CPUID.(EAX=14H,ECX=0): ECX[0] = 1) (CPUID.(EAX=14H,ECX=0): ECX[2] = 1) - ) ). - - @param ECX MSR_IA32_RTIT_OUTPUT_BASE (0x00000560) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_OUTPUT_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_OUTPUT_BASE_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_OUTPUT_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_BASE); - AsmWriteMsr64 (MSR_IA32_RTIT_OUTPUT_BASE, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_OUTPUT_BASE is defined as IA32_RTIT_OUTPUT_BASE in SDM. -**/ -#define MSR_IA32_RTIT_OUTPUT_BASE 0x00000560 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_OUTPUT_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:7; - /// - /// [Bits 31:7] Base physical address. - /// - UINT32 Base:25; - /// - /// [Bits 63:32] Base physical address. - /// - UINT32 BaseHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_OUTPUT_BASE_REGISTER; - - -/** - Trace Output Mask Pointers Register (R/W). If ((CPUID.(EAX=07H, - ECX=0):EBX[25] = 1) && ( (CPUID.(EAX=14H,ECX=0): ECX[0] = 1) - (CPUID.(EAX=14H,ECX=0): ECX[2] = 1) ) ). - - @param ECX MSR_IA32_RTIT_OUTPUT_MASK_PTRS (0x00000561) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_MASK_PTRS); - AsmWriteMsr64 (MSR_IA32_RTIT_OUTPUT_MASK_PTRS, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_OUTPUT_MASK_PTRS is defined as IA32_RTIT_OUTPUT_MASK_PTRS in SDM. -**/ -#define MSR_IA32_RTIT_OUTPUT_MASK_PTRS 0x00000561 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_OUTPUT_MASK_PTRS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:7; - /// - /// [Bits 31:7] MaskOrTableOffset. - /// - UINT32 MaskOrTableOffset:25; - /// - /// [Bits 63:32] Output Offset. - /// - UINT32 OutputOffset:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER; - -/** - Format of ToPA table entries. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] END. See Section 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 END:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] INT. See Section 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 INT:1; - UINT32 Reserved2:1; - /// - /// [Bit 4] STOP. See Section 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 STOP:1; - UINT32 Reserved3:1; - /// - /// [Bit 6:9] Indicates the size of the associated output region. See Section - /// 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 Size:4; - UINT32 Reserved4:2; - /// - /// [Bit 12:31] Output Region Base Physical Address low part. - /// [Bit 12:31] Output Region Base Physical Address [12:63] value to match. - /// ATTENTION: The size of the address field is determined by the processor's - /// physical-address width (MAXPHYADDR) in bits, as reported in - /// CPUID.80000008H:EAX[7:0]. the above part of address reserved. - /// True address field is [12:MAXPHYADDR-1], [MAXPHYADDR:63] is reserved part. - /// Detail see Section 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 Base:20; - /// - /// [Bit 32:63] Output Region Base Physical Address high part. - /// [Bit 32:63] Output Region Base Physical Address [12:63] value to match. - /// ATTENTION: The size of the address field is determined by the processor's - /// physical-address width (MAXPHYADDR) in bits, as reported in - /// CPUID.80000008H:EAX[7:0]. the above part of address reserved. - /// True address field is [12:MAXPHYADDR-1], [MAXPHYADDR:63] is reserved part. - /// Detail see Section 35.2.6.2, "Table of Physical Addresses (ToPA)". - /// - UINT32 BaseHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} RTIT_TOPA_TABLE_ENTRY; - -/// -/// The size of the associated output region usd by Topa. -/// -typedef enum { - RtitTopaMemorySize4K = 0, - RtitTopaMemorySize8K, - RtitTopaMemorySize16K, - RtitTopaMemorySize32K, - RtitTopaMemorySize64K, - RtitTopaMemorySize128K, - RtitTopaMemorySize256K, - RtitTopaMemorySize512K, - RtitTopaMemorySize1M, - RtitTopaMemorySize2M, - RtitTopaMemorySize4M, - RtitTopaMemorySize8M, - RtitTopaMemorySize16M, - RtitTopaMemorySize32M, - RtitTopaMemorySize64M, - RtitTopaMemorySize128M -} RTIT_TOPA_MEMORY_SIZE; - -/** - Trace Control Register (R/W). If (CPUID.(EAX=07H, ECX=0):EBX[25] = 1). - - @param ECX MSR_IA32_RTIT_CTL (0x00000570) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_CTL_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CTL); - AsmWriteMsr64 (MSR_IA32_RTIT_CTL, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_CTL is defined as IA32_RTIT_CTL in SDM. -**/ -#define MSR_IA32_RTIT_CTL 0x00000570 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] TraceEn. - /// - UINT32 TraceEn:1; - /// - /// [Bit 1] CYCEn. If (CPUID.(EAX=07H, ECX=0):EBX[1] = 1). - /// - UINT32 CYCEn:1; - /// - /// [Bit 2] OS. - /// - UINT32 OS:1; - /// - /// [Bit 3] User. - /// - UINT32 User:1; - UINT32 Reserved1:2; - /// - /// [Bit 6] FabricEn. If (CPUID.(EAX=07H, ECX=0):ECX[3] = 1). - /// - UINT32 FabricEn:1; - /// - /// [Bit 7] CR3 filter. - /// - UINT32 CR3:1; - /// - /// [Bit 8] ToPA. - /// - UINT32 ToPA:1; - /// - /// [Bit 9] MTCEn. If (CPUID.(EAX=07H, ECX=0):EBX[3] = 1). - /// - UINT32 MTCEn:1; - /// - /// [Bit 10] TSCEn. - /// - UINT32 TSCEn:1; - /// - /// [Bit 11] DisRETC. - /// - UINT32 DisRETC:1; - UINT32 Reserved2:1; - /// - /// [Bit 13] BranchEn. - /// - UINT32 BranchEn:1; - /// - /// [Bits 17:14] MTCFreq. If (CPUID.(EAX=07H, ECX=0):EBX[3] = 1). - /// - UINT32 MTCFreq:4; - UINT32 Reserved3:1; - /// - /// [Bits 22:19] CYCThresh. If (CPUID.(EAX=07H, ECX=0):EBX[1] = 1). - /// - UINT32 CYCThresh:4; - UINT32 Reserved4:1; - /// - /// [Bits 27:24] PSBFreq. If (CPUID.(EAX=07H, ECX=0):EBX[1] = 1). - /// - UINT32 PSBFreq:4; - UINT32 Reserved5:4; - /// - /// [Bits 35:32] ADDR0_CFG. If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > 0). - /// - UINT32 ADDR0_CFG:4; - /// - /// [Bits 39:36] ADDR1_CFG. If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > 1). - /// - UINT32 ADDR1_CFG:4; - /// - /// [Bits 43:40] ADDR2_CFG. If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > 2). - /// - UINT32 ADDR2_CFG:4; - /// - /// [Bits 47:44] ADDR3_CFG. If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > 3). - /// - UINT32 ADDR3_CFG:4; - UINT32 Reserved6:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_CTL_REGISTER; - - -/** - Tracing Status Register (R/W). If (CPUID.(EAX=07H, ECX=0):EBX[25] = 1). - - @param ECX MSR_IA32_RTIT_STATUS (0x00000571) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_STATUS); - AsmWriteMsr64 (MSR_IA32_RTIT_STATUS, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_STATUS is defined as IA32_RTIT_STATUS in SDM. -**/ -#define MSR_IA32_RTIT_STATUS 0x00000571 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] FilterEn, (writes ignored). - /// If (CPUID.(EAX=07H, ECX=0):EBX[2] = 1). - /// - UINT32 FilterEn:1; - /// - /// [Bit 1] ContexEn, (writes ignored). - /// - UINT32 ContexEn:1; - /// - /// [Bit 2] TriggerEn, (writes ignored). - /// - UINT32 TriggerEn:1; - UINT32 Reserved1:1; - /// - /// [Bit 4] Error. - /// - UINT32 Error:1; - /// - /// [Bit 5] Stopped. - /// - UINT32 Stopped:1; - UINT32 Reserved2:26; - /// - /// [Bits 48:32] PacketByteCnt. If (CPUID.(EAX=07H, ECX=0):EBX[1] > 3). - /// - UINT32 PacketByteCnt:17; - UINT32 Reserved3:15; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_STATUS_REGISTER; - - -/** - Trace Filter CR3 Match Register (R/W). - If (CPUID.(EAX=07H, ECX=0):EBX[25] = 1). - - @param ECX MSR_IA32_RTIT_CR3_MATCH (0x00000572) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_CR3_MATCH_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_CR3_MATCH_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_CR3_MATCH_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CR3_MATCH); - AsmWriteMsr64 (MSR_IA32_RTIT_CR3_MATCH, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_CR3_MATCH is defined as IA32_RTIT_CR3_MATCH in SDM. -**/ -#define MSR_IA32_RTIT_CR3_MATCH 0x00000572 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_CR3_MATCH -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:5; - /// - /// [Bits 31:5] CR3[63:5] value to match. - /// - UINT32 Cr3:27; - /// - /// [Bits 63:32] CR3[63:5] value to match. - /// - UINT32 Cr3Hi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_CR3_MATCH_REGISTER; - - -/** - Region n Start Address (R/W). If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > n). - - @param ECX MSR_IA32_RTIT_ADDRn_A - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_ADDR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_ADDR_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_ADDR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_ADDR0_A); - AsmWriteMsr64 (MSR_IA32_RTIT_ADDR0_A, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_ADDR0_A is defined as IA32_RTIT_ADDR0_A in SDM. - MSR_IA32_RTIT_ADDR1_A is defined as IA32_RTIT_ADDR1_A in SDM. - MSR_IA32_RTIT_ADDR2_A is defined as IA32_RTIT_ADDR2_A in SDM. - MSR_IA32_RTIT_ADDR3_A is defined as IA32_RTIT_ADDR3_A in SDM. - @{ -**/ -#define MSR_IA32_RTIT_ADDR0_A 0x00000580 -#define MSR_IA32_RTIT_ADDR1_A 0x00000582 -#define MSR_IA32_RTIT_ADDR2_A 0x00000584 -#define MSR_IA32_RTIT_ADDR3_A 0x00000586 -/// @} - - -/** - Region n End Address (R/W). If (CPUID.(EAX=07H, ECX=1):EAX[2:0] > n). - - @param ECX MSR_IA32_RTIT_ADDRn_B - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_ADDR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_RTIT_ADDR_REGISTER. - - Example usage - @code - MSR_IA32_RTIT_ADDR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_ADDR0_B); - AsmWriteMsr64 (MSR_IA32_RTIT_ADDR0_B, Msr.Uint64); - @endcode - @note MSR_IA32_RTIT_ADDR0_B is defined as IA32_RTIT_ADDR0_B in SDM. - MSR_IA32_RTIT_ADDR1_B is defined as IA32_RTIT_ADDR1_B in SDM. - MSR_IA32_RTIT_ADDR2_B is defined as IA32_RTIT_ADDR2_B in SDM. - MSR_IA32_RTIT_ADDR3_B is defined as IA32_RTIT_ADDR3_B in SDM. - @{ -**/ -#define MSR_IA32_RTIT_ADDR0_B 0x00000581 -#define MSR_IA32_RTIT_ADDR1_B 0x00000583 -#define MSR_IA32_RTIT_ADDR2_B 0x00000585 -#define MSR_IA32_RTIT_ADDR3_B 0x00000587 -/// @} - - -/** - MSR information returned for MSR indexes - #MSR_IA32_RTIT_ADDR0_A to #MSR_IA32_RTIT_ADDR3_A and - #MSR_IA32_RTIT_ADDR0_B to #MSR_IA32_RTIT_ADDR3_B -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Virtual Address. - /// - UINT32 VirtualAddress:32; - /// - /// [Bits 47:32] Virtual Address. - /// - UINT32 VirtualAddressHi:16; - /// - /// [Bits 63:48] SignExt_VA. - /// - UINT32 SignExt_VA:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_RTIT_ADDR_REGISTER; - - -/** - DS Save Area (R/W) Points to the linear address of the first byte of the DS - buffer management area, which is used to manage the BTS and PEBS buffers. - See Section 18.15.4, "Debug Store (DS) Mechanism.". If( CPUID.01H:EDX.DS[21] - = 1. - - [Bits 31..0] The linear address of the first byte of the DS buffer - management area, if not in IA-32e mode. - - [Bits 63..0] The linear address of the first byte of the DS buffer - management area, if IA-32e mode is active. - - @param ECX MSR_IA32_DS_AREA (0x00000600) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_DS_AREA_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_DS_AREA_REGISTER. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_DS_AREA); - AsmWriteMsr64 (MSR_IA32_DS_AREA, Msr); - @endcode - @note MSR_IA32_DS_AREA is defined as IA32_DS_AREA in SDM. -**/ -#define MSR_IA32_DS_AREA 0x00000600 - - -/** - TSC Target of Local APIC's TSC Deadline Mode (R/W). If CPUID.01H:ECX.[24] = - 1. - - @param ECX MSR_IA32_TSC_DEADLINE (0x000006E0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_TSC_DEADLINE); - AsmWriteMsr64 (MSR_IA32_TSC_DEADLINE, Msr); - @endcode - @note MSR_IA32_TSC_DEADLINE is defined as IA32_TSC_DEADLINE in SDM. -**/ -#define MSR_IA32_TSC_DEADLINE 0x000006E0 - - -/** - Enable/disable HWP (R/W). If CPUID.06H:EAX.[7] = 1. - - @param ECX MSR_IA32_PM_ENABLE (0x00000770) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PM_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PM_ENABLE_REGISTER. - - Example usage - @code - MSR_IA32_PM_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PM_ENABLE); - AsmWriteMsr64 (MSR_IA32_PM_ENABLE, Msr.Uint64); - @endcode - @note MSR_IA32_PM_ENABLE is defined as IA32_PM_ENABLE in SDM. -**/ -#define MSR_IA32_PM_ENABLE 0x00000770 - -/** - MSR information returned for MSR index #MSR_IA32_PM_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] HWP_ENABLE (R/W1-Once). See Section 14.4.2, "Enabling HWP". If - /// CPUID.06H:EAX.[7] = 1. - /// - UINT32 HWP_ENABLE:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PM_ENABLE_REGISTER; - - -/** - HWP Performance Range Enumeration (RO). If CPUID.06H:EAX.[7] = 1. - - @param ECX MSR_IA32_HWP_CAPABILITIES (0x00000771) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_HWP_CAPABILITIES_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_HWP_CAPABILITIES_REGISTER. - - Example usage - @code - MSR_IA32_HWP_CAPABILITIES_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_CAPABILITIES); - @endcode - @note MSR_IA32_HWP_CAPABILITIES is defined as IA32_HWP_CAPABILITIES in SDM. -**/ -#define MSR_IA32_HWP_CAPABILITIES 0x00000771 - -/** - MSR information returned for MSR index #MSR_IA32_HWP_CAPABILITIES -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Highest_Performance See Section 14.4.3, "HWP Performance - /// Range and Dynamic Capabilities". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Highest_Performance:8; - /// - /// [Bits 15:8] Guaranteed_Performance See Section 14.4.3, "HWP - /// Performance Range and Dynamic Capabilities". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Guaranteed_Performance:8; - /// - /// [Bits 23:16] Most_Efficient_Performance See Section 14.4.3, "HWP - /// Performance Range and Dynamic Capabilities". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Most_Efficient_Performance:8; - /// - /// [Bits 31:24] Lowest_Performance See Section 14.4.3, "HWP Performance - /// Range and Dynamic Capabilities". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Lowest_Performance:8; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_HWP_CAPABILITIES_REGISTER; - - -/** - Power Management Control Hints for All Logical Processors in a Package - (R/W). If CPUID.06H:EAX.[11] = 1. - - @param ECX MSR_IA32_HWP_REQUEST_PKG (0x00000772) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_HWP_REQUEST_PKG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_HWP_REQUEST_PKG_REGISTER. - - Example usage - @code - MSR_IA32_HWP_REQUEST_PKG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_REQUEST_PKG); - AsmWriteMsr64 (MSR_IA32_HWP_REQUEST_PKG, Msr.Uint64); - @endcode - @note MSR_IA32_HWP_REQUEST_PKG is defined as IA32_HWP_REQUEST_PKG in SDM. -**/ -#define MSR_IA32_HWP_REQUEST_PKG 0x00000772 - -/** - MSR information returned for MSR index #MSR_IA32_HWP_REQUEST_PKG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Minimum_Performance See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[11] = 1. - /// - UINT32 Minimum_Performance:8; - /// - /// [Bits 15:8] Maximum_Performance See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[11] = 1. - /// - UINT32 Maximum_Performance:8; - /// - /// [Bits 23:16] Desired_Performance See Section 14.4.4, "Managing HWP". - /// If CPUID.06H:EAX.[11] = 1. - /// - UINT32 Desired_Performance:8; - /// - /// [Bits 31:24] Energy_Performance_Preference See Section 14.4.4, - /// "Managing HWP". If CPUID.06H:EAX.[11] = 1 && CPUID.06H:EAX.[10] = 1. - /// - UINT32 Energy_Performance_Preference:8; - /// - /// [Bits 41:32] Activity_Window See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[11] = 1 && CPUID.06H:EAX.[9] = 1. - /// - UINT32 Activity_Window:10; - UINT32 Reserved:22; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_HWP_REQUEST_PKG_REGISTER; - - -/** - Control HWP Native Interrupts (R/W). If CPUID.06H:EAX.[8] = 1. - - @param ECX MSR_IA32_HWP_INTERRUPT (0x00000773) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_HWP_INTERRUPT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_HWP_INTERRUPT_REGISTER. - - Example usage - @code - MSR_IA32_HWP_INTERRUPT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_INTERRUPT); - AsmWriteMsr64 (MSR_IA32_HWP_INTERRUPT, Msr.Uint64); - @endcode - @note MSR_IA32_HWP_INTERRUPT is defined as IA32_HWP_INTERRUPT in SDM. -**/ -#define MSR_IA32_HWP_INTERRUPT 0x00000773 - -/** - MSR information returned for MSR index #MSR_IA32_HWP_INTERRUPT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] EN_Guaranteed_Performance_Change. See Section 14.4.6, "HWP - /// Notifications". If CPUID.06H:EAX.[8] = 1. - /// - UINT32 EN_Guaranteed_Performance_Change:1; - /// - /// [Bit 1] EN_Excursion_Minimum. See Section 14.4.6, "HWP Notifications". - /// If CPUID.06H:EAX.[8] = 1. - /// - UINT32 EN_Excursion_Minimum:1; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_HWP_INTERRUPT_REGISTER; - - -/** - Power Management Control Hints to a Logical Processor (R/W). If - CPUID.06H:EAX.[7] = 1. - - @param ECX MSR_IA32_HWP_REQUEST (0x00000774) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_HWP_REQUEST_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_HWP_REQUEST_REGISTER. - - Example usage - @code - MSR_IA32_HWP_REQUEST_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_REQUEST); - AsmWriteMsr64 (MSR_IA32_HWP_REQUEST, Msr.Uint64); - @endcode - @note MSR_IA32_HWP_REQUEST is defined as IA32_HWP_REQUEST in SDM. -**/ -#define MSR_IA32_HWP_REQUEST 0x00000774 - -/** - MSR information returned for MSR index #MSR_IA32_HWP_REQUEST -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Minimum_Performance See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[7] = 1. - /// - UINT32 Minimum_Performance:8; - /// - /// [Bits 15:8] Maximum_Performance See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[7] = 1. - /// - UINT32 Maximum_Performance:8; - /// - /// [Bits 23:16] Desired_Performance See Section 14.4.4, "Managing HWP". - /// If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Desired_Performance:8; - /// - /// [Bits 31:24] Energy_Performance_Preference See Section 14.4.4, - /// "Managing HWP". If CPUID.06H:EAX.[7] = 1 && CPUID.06H:EAX.[10] = 1. - /// - UINT32 Energy_Performance_Preference:8; - /// - /// [Bits 41:32] Activity_Window See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[7] = 1 && CPUID.06H:EAX.[9] = 1. - /// - UINT32 Activity_Window:10; - /// - /// [Bit 42] Package_Control See Section 14.4.4, "Managing HWP". If - /// CPUID.06H:EAX.[7] = 1 && CPUID.06H:EAX.[11] = 1. - /// - UINT32 Package_Control:1; - UINT32 Reserved:21; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_HWP_REQUEST_REGISTER; - - -/** - Log bits indicating changes to Guaranteed & excursions to Minimum (R/W). If - CPUID.06H:EAX.[7] = 1. - - @param ECX MSR_IA32_HWP_STATUS (0x00000777) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_HWP_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_HWP_STATUS_REGISTER. - - Example usage - @code - MSR_IA32_HWP_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_STATUS); - AsmWriteMsr64 (MSR_IA32_HWP_STATUS, Msr.Uint64); - @endcode - @note MSR_IA32_HWP_STATUS is defined as IA32_HWP_STATUS in SDM. -**/ -#define MSR_IA32_HWP_STATUS 0x00000777 - -/** - MSR information returned for MSR index #MSR_IA32_HWP_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Guaranteed_Performance_Change (R/WC0). See Section 14.4.5, - /// "HWP Feedback". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Guaranteed_Performance_Change:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Excursion_To_Minimum (R/WC0). See Section 14.4.5, "HWP - /// Feedback". If CPUID.06H:EAX.[7] = 1. - /// - UINT32 Excursion_To_Minimum:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_HWP_STATUS_REGISTER; - - -/** - x2APIC ID Register (R/O) See x2APIC Specification. If CPUID.01H:ECX[21] = 1 - && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_APICID (0x00000802) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_APICID); - @endcode - @note MSR_IA32_X2APIC_APICID is defined as IA32_X2APIC_APICID in SDM. -**/ -#define MSR_IA32_X2APIC_APICID 0x00000802 - - -/** - x2APIC Version Register (R/O). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_VERSION (0x00000803) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_VERSION); - @endcode - @note MSR_IA32_X2APIC_VERSION is defined as IA32_X2APIC_VERSION in SDM. -**/ -#define MSR_IA32_X2APIC_VERSION 0x00000803 - - -/** - x2APIC Task Priority Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_TPR (0x00000808) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_TPR); - AsmWriteMsr64 (MSR_IA32_X2APIC_TPR, Msr); - @endcode - @note MSR_IA32_X2APIC_TPR is defined as IA32_X2APIC_TPR in SDM. -**/ -#define MSR_IA32_X2APIC_TPR 0x00000808 - - -/** - x2APIC Processor Priority Register (R/O). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_PPR (0x0000080A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_PPR); - @endcode - @note MSR_IA32_X2APIC_PPR is defined as IA32_X2APIC_PPR in SDM. -**/ -#define MSR_IA32_X2APIC_PPR 0x0000080A - - -/** - x2APIC EOI Register (W/O). If CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] - = 1. - - @param ECX MSR_IA32_X2APIC_EOI (0x0000080B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = 0; - AsmWriteMsr64 (MSR_IA32_X2APIC_EOI, Msr); - @endcode - @note MSR_IA32_X2APIC_EOI is defined as IA32_X2APIC_EOI in SDM. -**/ -#define MSR_IA32_X2APIC_EOI 0x0000080B - - -/** - x2APIC Logical Destination Register (R/O). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LDR (0x0000080D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LDR); - @endcode - @note MSR_IA32_X2APIC_LDR is defined as IA32_X2APIC_LDR in SDM. -**/ -#define MSR_IA32_X2APIC_LDR 0x0000080D - - -/** - x2APIC Spurious Interrupt Vector Register (R/W). If CPUID.01H:ECX.[21] = 1 - && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_SIVR (0x0000080F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_SIVR); - AsmWriteMsr64 (MSR_IA32_X2APIC_SIVR, Msr); - @endcode - @note MSR_IA32_X2APIC_SIVR is defined as IA32_X2APIC_SIVR in SDM. -**/ -#define MSR_IA32_X2APIC_SIVR 0x0000080F - - -/** - x2APIC In-Service Register Bits (n * 32 + 31):(n * 32) (R/O). - If CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_ISRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ISR0); - @endcode - @note MSR_IA32_X2APIC_ISR0 is defined as IA32_X2APIC_ISR0 in SDM. - MSR_IA32_X2APIC_ISR1 is defined as IA32_X2APIC_ISR1 in SDM. - MSR_IA32_X2APIC_ISR2 is defined as IA32_X2APIC_ISR2 in SDM. - MSR_IA32_X2APIC_ISR3 is defined as IA32_X2APIC_ISR3 in SDM. - MSR_IA32_X2APIC_ISR4 is defined as IA32_X2APIC_ISR4 in SDM. - MSR_IA32_X2APIC_ISR5 is defined as IA32_X2APIC_ISR5 in SDM. - MSR_IA32_X2APIC_ISR6 is defined as IA32_X2APIC_ISR6 in SDM. - MSR_IA32_X2APIC_ISR7 is defined as IA32_X2APIC_ISR7 in SDM. - @{ -**/ -#define MSR_IA32_X2APIC_ISR0 0x00000810 -#define MSR_IA32_X2APIC_ISR1 0x00000811 -#define MSR_IA32_X2APIC_ISR2 0x00000812 -#define MSR_IA32_X2APIC_ISR3 0x00000813 -#define MSR_IA32_X2APIC_ISR4 0x00000814 -#define MSR_IA32_X2APIC_ISR5 0x00000815 -#define MSR_IA32_X2APIC_ISR6 0x00000816 -#define MSR_IA32_X2APIC_ISR7 0x00000817 -/// @} - - -/** - x2APIC Trigger Mode Register Bits (n * 32 + ):(n * 32) (R/O). - If CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_TMRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_TMR0); - @endcode - @note MSR_IA32_X2APIC_TMR0 is defined as IA32_X2APIC_TMR0 in SDM. - MSR_IA32_X2APIC_TMR1 is defined as IA32_X2APIC_TMR1 in SDM. - MSR_IA32_X2APIC_TMR2 is defined as IA32_X2APIC_TMR2 in SDM. - MSR_IA32_X2APIC_TMR3 is defined as IA32_X2APIC_TMR3 in SDM. - MSR_IA32_X2APIC_TMR4 is defined as IA32_X2APIC_TMR4 in SDM. - MSR_IA32_X2APIC_TMR5 is defined as IA32_X2APIC_TMR5 in SDM. - MSR_IA32_X2APIC_TMR6 is defined as IA32_X2APIC_TMR6 in SDM. - MSR_IA32_X2APIC_TMR7 is defined as IA32_X2APIC_TMR7 in SDM. - @{ -**/ -#define MSR_IA32_X2APIC_TMR0 0x00000818 -#define MSR_IA32_X2APIC_TMR1 0x00000819 -#define MSR_IA32_X2APIC_TMR2 0x0000081A -#define MSR_IA32_X2APIC_TMR3 0x0000081B -#define MSR_IA32_X2APIC_TMR4 0x0000081C -#define MSR_IA32_X2APIC_TMR5 0x0000081D -#define MSR_IA32_X2APIC_TMR6 0x0000081E -#define MSR_IA32_X2APIC_TMR7 0x0000081F -/// @} - - -/** - x2APIC Interrupt Request Register Bits (n* 32 + 31):(n * 32) (R/O). - If CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_IRRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_IRR0); - @endcode - @note MSR_IA32_X2APIC_IRR0 is defined as IA32_X2APIC_IRR0 in SDM. - MSR_IA32_X2APIC_IRR1 is defined as IA32_X2APIC_IRR1 in SDM. - MSR_IA32_X2APIC_IRR2 is defined as IA32_X2APIC_IRR2 in SDM. - MSR_IA32_X2APIC_IRR3 is defined as IA32_X2APIC_IRR3 in SDM. - MSR_IA32_X2APIC_IRR4 is defined as IA32_X2APIC_IRR4 in SDM. - MSR_IA32_X2APIC_IRR5 is defined as IA32_X2APIC_IRR5 in SDM. - MSR_IA32_X2APIC_IRR6 is defined as IA32_X2APIC_IRR6 in SDM. - MSR_IA32_X2APIC_IRR7 is defined as IA32_X2APIC_IRR7 in SDM. - @{ -**/ -#define MSR_IA32_X2APIC_IRR0 0x00000820 -#define MSR_IA32_X2APIC_IRR1 0x00000821 -#define MSR_IA32_X2APIC_IRR2 0x00000822 -#define MSR_IA32_X2APIC_IRR3 0x00000823 -#define MSR_IA32_X2APIC_IRR4 0x00000824 -#define MSR_IA32_X2APIC_IRR5 0x00000825 -#define MSR_IA32_X2APIC_IRR6 0x00000826 -#define MSR_IA32_X2APIC_IRR7 0x00000827 -/// @} - - -/** - x2APIC Error Status Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_ESR (0x00000828) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ESR); - AsmWriteMsr64 (MSR_IA32_X2APIC_ESR, Msr); - @endcode - @note MSR_IA32_X2APIC_ESR is defined as IA32_X2APIC_ESR in SDM. -**/ -#define MSR_IA32_X2APIC_ESR 0x00000828 - - -/** - x2APIC LVT Corrected Machine Check Interrupt Register (R/W). If - CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_CMCI (0x0000082F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_CMCI); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_CMCI, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_CMCI is defined as IA32_X2APIC_LVT_CMCI in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_CMCI 0x0000082F - - -/** - x2APIC Interrupt Command Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_ICR (0x00000830) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ICR); - AsmWriteMsr64 (MSR_IA32_X2APIC_ICR, Msr); - @endcode - @note MSR_IA32_X2APIC_ICR is defined as IA32_X2APIC_ICR in SDM. -**/ -#define MSR_IA32_X2APIC_ICR 0x00000830 - - -/** - x2APIC LVT Timer Interrupt Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_TIMER (0x00000832) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_TIMER); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_TIMER, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_TIMER is defined as IA32_X2APIC_LVT_TIMER in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_TIMER 0x00000832 - - -/** - x2APIC LVT Thermal Sensor Interrupt Register (R/W). If CPUID.01H:ECX.[21] = - 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_THERMAL (0x00000833) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_THERMAL); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_THERMAL, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_THERMAL is defined as IA32_X2APIC_LVT_THERMAL in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_THERMAL 0x00000833 - - -/** - x2APIC LVT Performance Monitor Interrupt Register (R/W). If - CPUID.01H:ECX.[21] = 1 && IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_PMI (0x00000834) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_PMI); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_PMI, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_PMI is defined as IA32_X2APIC_LVT_PMI in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_PMI 0x00000834 - - -/** - x2APIC LVT LINT0 Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_LINT0 (0x00000835) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_LINT0); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_LINT0, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_LINT0 is defined as IA32_X2APIC_LVT_LINT0 in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_LINT0 0x00000835 - - -/** - x2APIC LVT LINT1 Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_LINT1 (0x00000836) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_LINT1); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_LINT1, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_LINT1 is defined as IA32_X2APIC_LVT_LINT1 in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_LINT1 0x00000836 - - -/** - x2APIC LVT Error Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_LVT_ERROR (0x00000837) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_ERROR); - AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_ERROR, Msr); - @endcode - @note MSR_IA32_X2APIC_LVT_ERROR is defined as IA32_X2APIC_LVT_ERROR in SDM. -**/ -#define MSR_IA32_X2APIC_LVT_ERROR 0x00000837 - - -/** - x2APIC Initial Count Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_INIT_COUNT (0x00000838) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_INIT_COUNT); - AsmWriteMsr64 (MSR_IA32_X2APIC_INIT_COUNT, Msr); - @endcode - @note MSR_IA32_X2APIC_INIT_COUNT is defined as IA32_X2APIC_INIT_COUNT in SDM. -**/ -#define MSR_IA32_X2APIC_INIT_COUNT 0x00000838 - - -/** - x2APIC Current Count Register (R/O). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_CUR_COUNT (0x00000839) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_CUR_COUNT); - @endcode - @note MSR_IA32_X2APIC_CUR_COUNT is defined as IA32_X2APIC_CUR_COUNT in SDM. -**/ -#define MSR_IA32_X2APIC_CUR_COUNT 0x00000839 - - -/** - x2APIC Divide Configuration Register (R/W). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_DIV_CONF (0x0000083E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_X2APIC_DIV_CONF); - AsmWriteMsr64 (MSR_IA32_X2APIC_DIV_CONF, Msr); - @endcode - @note MSR_IA32_X2APIC_DIV_CONF is defined as IA32_X2APIC_DIV_CONF in SDM. -**/ -#define MSR_IA32_X2APIC_DIV_CONF 0x0000083E - - -/** - x2APIC Self IPI Register (W/O). If CPUID.01H:ECX.[21] = 1 && - IA32_APIC_BASE.[10] = 1. - - @param ECX MSR_IA32_X2APIC_SELF_IPI (0x0000083F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = 0; - AsmWriteMsr64 (MSR_IA32_X2APIC_SELF_IPI, Msr); - @endcode - @note MSR_IA32_X2APIC_SELF_IPI is defined as IA32_X2APIC_SELF_IPI in SDM. -**/ -#define MSR_IA32_X2APIC_SELF_IPI 0x0000083F - - -/** - Silicon Debug Feature Control (R/W). If CPUID.01H:ECX.[11] = 1. - - @param ECX MSR_IA32_DEBUG_INTERFACE (0x00000C80) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_DEBUG_INTERFACE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_DEBUG_INTERFACE_REGISTER. - - Example usage - @code - MSR_IA32_DEBUG_INTERFACE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_DEBUG_INTERFACE); - AsmWriteMsr64 (MSR_IA32_DEBUG_INTERFACE, Msr.Uint64); - @endcode - @note MSR_IA32_DEBUG_INTERFACE is defined as IA32_DEBUG_INTERFACE in SDM. -**/ -#define MSR_IA32_DEBUG_INTERFACE 0x00000C80 - -/** - MSR information returned for MSR index #MSR_IA32_DEBUG_INTERFACE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable (R/W) BIOS set 1 to enable Silicon debug features. - /// Default is 0. If CPUID.01H:ECX.[11] = 1. - /// - UINT32 Enable:1; - UINT32 Reserved1:29; - /// - /// [Bit 30] Lock (R/W): If 1, locks any further change to the MSR. The - /// lock bit is set automatically on the first SMI assertion even if not - /// explicitly set by BIOS. Default is 0. If CPUID.01H:ECX.[11] = 1. - /// - UINT32 Lock:1; - /// - /// [Bit 31] Debug Occurred (R/O): This "sticky bit" is set by hardware to - /// indicate the status of bit 0. Default is 0. If CPUID.01H:ECX.[11] = 1. - /// - UINT32 DebugOccurred:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_DEBUG_INTERFACE_REGISTER; - - -/** - L3 QOS Configuration (R/W). If ( CPUID.(EAX=10H, ECX=1):ECX.[2] = 1 ). - - @param ECX MSR_IA32_L3_QOS_CFG (0x00000C81) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_L3_QOS_CFG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_L3_QOS_CFG_REGISTER. - - Example usage - @code - MSR_IA32_L3_QOS_CFG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_L3_QOS_CFG); - AsmWriteMsr64 (MSR_IA32_L3_QOS_CFG, Msr.Uint64); - @endcode - @note MSR_IA32_L3_QOS_CFG is defined as IA32_L3_QOS_CFG in SDM. -**/ -#define MSR_IA32_L3_QOS_CFG 0x00000C81 - -/** - MSR information returned for MSR index #MSR_IA32_L3_QOS_CFG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable (R/W) Set 1 to enable L3 CAT masks and COS to operate - /// in Code and Data Prioritization (CDP) mode. - /// - UINT32 Enable:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_L3_QOS_CFG_REGISTER; - - -/** - Monitoring Event Select Register (R/W). If ( CPUID.(EAX=07H, ECX=0):EBX.[12] - = 1 ). - - @param ECX MSR_IA32_QM_EVTSEL (0x00000C8D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_QM_EVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_QM_EVTSEL_REGISTER. - - Example usage - @code - MSR_IA32_QM_EVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_QM_EVTSEL); - AsmWriteMsr64 (MSR_IA32_QM_EVTSEL, Msr.Uint64); - @endcode - @note MSR_IA32_QM_EVTSEL is defined as IA32_QM_EVTSEL in SDM. -**/ -#define MSR_IA32_QM_EVTSEL 0x00000C8D - -/** - MSR information returned for MSR index #MSR_IA32_QM_EVTSEL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Event ID: ID of a supported monitoring event to report via - /// IA32_QM_CTR. - /// - UINT32 EventID:8; - UINT32 Reserved:24; - /// - /// [Bits 63:32] Resource Monitoring ID: ID for monitoring hardware to - /// report monitored data via IA32_QM_CTR. N = Ceil (Log:sub:`2` ( - /// CPUID.(EAX= 0FH, ECX=0H).EBX[31:0] +1)). - /// - UINT32 ResourceMonitoringID:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_QM_EVTSEL_REGISTER; - - -/** - Monitoring Counter Register (R/O). If ( CPUID.(EAX=07H, ECX=0):EBX.[12] = 1 - ). - - @param ECX MSR_IA32_QM_CTR (0x00000C8E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_QM_CTR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_QM_CTR_REGISTER. - - Example usage - @code - MSR_IA32_QM_CTR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_QM_CTR); - @endcode - @note MSR_IA32_QM_CTR is defined as IA32_QM_CTR in SDM. -**/ -#define MSR_IA32_QM_CTR 0x00000C8E - -/** - MSR information returned for MSR index #MSR_IA32_QM_CTR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Resource Monitored Data. - /// - UINT32 ResourceMonitoredData:32; - /// - /// [Bits 61:32] Resource Monitored Data. - /// - UINT32 ResourceMonitoredDataHi:30; - /// - /// [Bit 62] Unavailable: If 1, indicates data for this RMID is not - /// available or not monitored for this resource or RMID. - /// - UINT32 Unavailable:1; - /// - /// [Bit 63] Error: If 1, indicates and unsupported RMID or event type was - /// written to IA32_PQR_QM_EVTSEL. - /// - UINT32 Error:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_QM_CTR_REGISTER; - - -/** - Resource Association Register (R/W). If ( (CPUID.(EAX=07H, ECX=0):EBX[12] - =1) or (CPUID.(EAX=07H, ECX=0):EBX[15] =1 ) ). - - @param ECX MSR_IA32_PQR_ASSOC (0x00000C8F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PQR_ASSOC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PQR_ASSOC_REGISTER. - - Example usage - @code - MSR_IA32_PQR_ASSOC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PQR_ASSOC); - AsmWriteMsr64 (MSR_IA32_PQR_ASSOC, Msr.Uint64); - @endcode - @note MSR_IA32_PQR_ASSOC is defined as IA32_PQR_ASSOC in SDM. -**/ -#define MSR_IA32_PQR_ASSOC 0x00000C8F - -/** - MSR information returned for MSR index #MSR_IA32_PQR_ASSOC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Resource Monitoring ID (R/W): ID for monitoring hardware - /// to track internal operation, e.g. memory access. N = Ceil (Log:sub:`2` - /// ( CPUID.(EAX= 0FH, ECX=0H).EBX[31:0] +1)). - /// - UINT32 ResourceMonitoringID:32; - /// - /// [Bits 63:32] COS (R/W). The class of service (COS) to enforce (on - /// writes); returns the current COS when read. If ( CPUID.(EAX=07H, - /// ECX=0):EBX.[15] = 1 ). - /// - UINT32 COS:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PQR_ASSOC_REGISTER; - - -/** - Supervisor State of MPX Configuration. (R/W). If (CPUID.(EAX=07H, - ECX=0H):EBX[14] = 1). - - @param ECX MSR_IA32_BNDCFGS (0x00000D90) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_BNDCFGS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_BNDCFGS_REGISTER. - - Example usage - @code - MSR_IA32_BNDCFGS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_BNDCFGS); - AsmWriteMsr64 (MSR_IA32_BNDCFGS, Msr.Uint64); - @endcode - @note MSR_IA32_BNDCFGS is defined as IA32_BNDCFGS in SDM. -**/ -#define MSR_IA32_BNDCFGS 0x00000D90 - -/** - MSR information returned for MSR index #MSR_IA32_BNDCFGS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] EN: Enable Intel MPX in supervisor mode. - /// - UINT32 EN:1; - /// - /// [Bit 1] BNDPRESERVE: Preserve the bounds registers for near branch - /// instructions in the absence of the BND prefix. - /// - UINT32 BNDPRESERVE:1; - UINT32 Reserved:10; - /// - /// [Bits 31:12] Base Address of Bound Directory. - /// - UINT32 Base:20; - /// - /// [Bits 63:32] Base Address of Bound Directory. - /// - UINT32 BaseHi:32; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_BNDCFGS_REGISTER; - - -/** - Extended Supervisor State Mask (R/W). If( CPUID.(0DH, 1):EAX.[3] = 1. - - @param ECX MSR_IA32_XSS (0x00000DA0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_XSS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_XSS_REGISTER. - - Example usage - @code - MSR_IA32_XSS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_XSS); - AsmWriteMsr64 (MSR_IA32_XSS, Msr.Uint64); - @endcode - @note MSR_IA32_XSS is defined as IA32_XSS in SDM. -**/ -#define MSR_IA32_XSS 0x00000DA0 - -/** - MSR information returned for MSR index #MSR_IA32_XSS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bit 8] Trace Packet Configuration State (R/W). - /// - UINT32 TracePacketConfigurationState:1; - UINT32 Reserved2:23; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_XSS_REGISTER; - - -/** - Package Level Enable/disable HDC (R/W). If CPUID.06H:EAX.[13] = 1. - - @param ECX MSR_IA32_PKG_HDC_CTL (0x00000DB0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PKG_HDC_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PKG_HDC_CTL_REGISTER. - - Example usage - @code - MSR_IA32_PKG_HDC_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PKG_HDC_CTL); - AsmWriteMsr64 (MSR_IA32_PKG_HDC_CTL, Msr.Uint64); - @endcode - @note MSR_IA32_PKG_HDC_CTL is defined as IA32_PKG_HDC_CTL in SDM. -**/ -#define MSR_IA32_PKG_HDC_CTL 0x00000DB0 - -/** - MSR information returned for MSR index #MSR_IA32_PKG_HDC_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] HDC_Pkg_Enable (R/W) Force HDC idling or wake up HDC-idled - /// logical processors in the package. See Section 14.5.2, "Package level - /// Enabling HDC". If CPUID.06H:EAX.[13] = 1. - /// - UINT32 HDC_Pkg_Enable:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PKG_HDC_CTL_REGISTER; - - -/** - Enable/disable HWP (R/W). If CPUID.06H:EAX.[13] = 1. - - @param ECX MSR_IA32_PM_CTL1 (0x00000DB1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_PM_CTL1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_PM_CTL1_REGISTER. - - Example usage - @code - MSR_IA32_PM_CTL1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PM_CTL1); - AsmWriteMsr64 (MSR_IA32_PM_CTL1, Msr.Uint64); - @endcode - @note MSR_IA32_PM_CTL1 is defined as IA32_PM_CTL1 in SDM. -**/ -#define MSR_IA32_PM_CTL1 0x00000DB1 - -/** - MSR information returned for MSR index #MSR_IA32_PM_CTL1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] HDC_Allow_Block (R/W) Allow/Block this logical processor for - /// package level HDC control. See Section 14.5.3. - /// If CPUID.06H:EAX.[13] = 1. - /// - UINT32 HDC_Allow_Block:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_PM_CTL1_REGISTER; - - -/** - Per-Logical_Processor HDC Idle Residency (R/0). If CPUID.06H:EAX.[13] = 1. - Stall_Cycle_Cnt (R/W) Stalled cycles due to HDC forced idle on this logical - processor. See Section 14.5.4.1. If CPUID.06H:EAX.[13] = 1. - - @param ECX MSR_IA32_THREAD_STALL (0x00000DB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_THREAD_STALL); - @endcode - @note MSR_IA32_THREAD_STALL is defined as IA32_THREAD_STALL in SDM. -**/ -#define MSR_IA32_THREAD_STALL 0x00000DB2 - - -/** - Extended Feature Enables. If ( CPUID.80000001H:EDX.[2 0] - CPUID.80000001H:EDX.[2 9]). - - @param ECX MSR_IA32_EFER (0xC0000080) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_EFER_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_EFER_REGISTER. - - Example usage - @code - MSR_IA32_EFER_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - AsmWriteMsr64 (MSR_IA32_EFER, Msr.Uint64); - @endcode - @note MSR_IA32_EFER is defined as IA32_EFER in SDM. -**/ -#define MSR_IA32_EFER 0xC0000080 - -/** - MSR information returned for MSR index #MSR_IA32_EFER -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] SYSCALL Enable: IA32_EFER.SCE (R/W) Enables SYSCALL/SYSRET - /// instructions in 64-bit mode. - /// - UINT32 SCE:1; - UINT32 Reserved1:7; - /// - /// [Bit 8] IA-32e Mode Enable: IA32_EFER.LME (R/W) Enables IA-32e mode - /// operation. - /// - UINT32 LME:1; - UINT32 Reserved2:1; - /// - /// [Bit 10] IA-32e Mode Active: IA32_EFER.LMA (R) Indicates IA-32e mode - /// is active when set. - /// - UINT32 LMA:1; - /// - /// [Bit 11] Execute Disable Bit Enable: IA32_EFER.NXE (R/W). - /// - UINT32 NXE:1; - UINT32 Reserved3:20; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_EFER_REGISTER; - - -/** - System Call Target Address (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_STAR (0xC0000081) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_STAR); - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - @endcode - @note MSR_IA32_STAR is defined as IA32_STAR in SDM. -**/ -#define MSR_IA32_STAR 0xC0000081 - - -/** - IA-32e Mode System Call Target Address (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_LSTAR (0xC0000082) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_LSTAR); - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - @endcode - @note MSR_IA32_LSTAR is defined as IA32_LSTAR in SDM. -**/ -#define MSR_IA32_LSTAR 0xC0000082 - - -/** - System Call Flag Mask (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_FMASK (0xC0000084) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_FMASK); - AsmWriteMsr64 (MSR_IA32_FMASK, Msr); - @endcode - @note MSR_IA32_FMASK is defined as IA32_FMASK in SDM. -**/ -#define MSR_IA32_FMASK 0xC0000084 - - -/** - Map of BASE Address of FS (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_FS_BASE (0xC0000100) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_FS_BASE); - AsmWriteMsr64 (MSR_IA32_FS_BASE, Msr); - @endcode - @note MSR_IA32_FS_BASE is defined as IA32_FS_BASE in SDM. -**/ -#define MSR_IA32_FS_BASE 0xC0000100 - - -/** - Map of BASE Address of GS (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_GS_BASE (0xC0000101) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_GS_BASE); - AsmWriteMsr64 (MSR_IA32_GS_BASE, Msr); - @endcode - @note MSR_IA32_GS_BASE is defined as IA32_GS_BASE in SDM. -**/ -#define MSR_IA32_GS_BASE 0xC0000101 - - -/** - Swap Target of BASE Address of GS (R/W). If CPUID.80000001:EDX.[29] = 1. - - @param ECX MSR_IA32_KERNEL_GS_BASE (0xC0000102) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IA32_KERNEL_GS_BASE); - AsmWriteMsr64 (MSR_IA32_KERNEL_GS_BASE, Msr); - @endcode - @note MSR_IA32_KERNEL_GS_BASE is defined as IA32_KERNEL_GS_BASE in SDM. -**/ -#define MSR_IA32_KERNEL_GS_BASE 0xC0000102 - - -/** - Auxiliary TSC (RW). If CPUID.80000001H: EDX[27] = 1. - - @param ECX MSR_IA32_TSC_AUX (0xC0000103) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IA32_TSC_AUX_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IA32_TSC_AUX_REGISTER. - - Example usage - @code - MSR_IA32_TSC_AUX_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IA32_TSC_AUX); - AsmWriteMsr64 (MSR_IA32_TSC_AUX, Msr.Uint64); - @endcode - @note MSR_IA32_TSC_AUX is defined as IA32_TSC_AUX in SDM. -**/ -#define MSR_IA32_TSC_AUX 0xC0000103 - -/** - MSR information returned for MSR index #MSR_IA32_TSC_AUX -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] AUX: Auxiliary signature of TSC. - /// - UINT32 AUX:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IA32_TSC_AUX_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Cpuid.h b/CloverEFI/UefiCpuPkg/Include/Register/Cpuid.h deleted file mode 100644 index 5eb965055..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Cpuid.h +++ /dev/null @@ -1,3536 +0,0 @@ -/** @file - CPUID leaf definitions. - - Provides defines for CPUID leaf indexes. Data structures are provided for - registers returned by a CPUID leaf that contain one or more bit fields. - If a register returned is a single 32-bit value, then a data structure is - not provided for that register. - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials are licensed and made available under - the terms and conditions of the BSD License which accompanies this distribution. - The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 2A, - September 2016, CPUID instruction. - -**/ - -#ifndef __CPUID_H__ -#define __CPUID_H__ - -/** - CPUID Signature Information - - @param EAX CPUID_SIGNATURE (0x00) - - @retval EAX Returns the highest value the CPUID instruction recognizes for - returning basic processor information. The value is returned is - processor specific. - @retval EBX First 4 characters of a vendor identification string. - @retval ECX Last 4 characters of a vendor identification string. - @retval EDX Middle 4 characters of a vendor identification string. - - Example usage - @code - UINT32 Eax; - UINT32 Ebx; - UINT32 Ecx; - UINT32 Edx; - - AsmCpuid (CPUID_SIGNATURE, &Eax, &Ebx, &Ecx, &Edx); - @endcode -**/ -#define CPUID_SIGNATURE 0x00 - -/// -/// @{ CPUID signature values returned by Intel processors -/// -#define CPUID_SIGNATURE_GENUINE_INTEL_EBX SIGNATURE_32 ('G', 'e', 'n', 'u') -#define CPUID_SIGNATURE_GENUINE_INTEL_EDX SIGNATURE_32 ('i', 'n', 'e', 'I') -#define CPUID_SIGNATURE_GENUINE_INTEL_ECX SIGNATURE_32 ('n', 't', 'e', 'l') -/// -/// @} -/// - - -/** - CPUID Version Information - - @param EAX CPUID_VERSION_INFO (0x01) - - @retval EAX Returns Model, Family, Stepping Information described by the - type CPUID_VERSION_INFO_EAX. - @retval EBX Returns Brand, Cache Line Size, and Initial APIC ID described by - the type CPUID_VERSION_INFO_EBX. - @retval ECX CPU Feature Information described by the type - CPUID_VERSION_INFO_ECX. - @retval EDX CPU Feature Information described by the type - CPUID_VERSION_INFO_EDX. - - Example usage - @code - CPUID_VERSION_INFO_EAX Eax; - CPUID_VERSION_INFO_EBX Ebx; - CPUID_VERSION_INFO_ECX Ecx; - CPUID_VERSION_INFO_EDX Edx; - - AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_VERSION_INFO 0x01 - -/** - CPUID Version Information returned in EAX for CPUID leaf - #CPUID_VERSION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 SteppingId:4; ///< [Bits 3:0] Stepping ID - UINT32 Model:4; ///< [Bits 7:4] Model - UINT32 FamilyId:4; ///< [Bits 11:8] Family - UINT32 ProcessorType:2; ///< [Bits 13:12] Processor Type - UINT32 Reserved1:2; ///< [Bits 15:14] Reserved - UINT32 ExtendedModelId:4; ///< [Bits 19:16] Extended Model ID - UINT32 ExtendedFamilyId:8; ///< [Bits 27:20] Extended Family ID - UINT32 Reserved2:4; ///< Reserved - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_VERSION_INFO_EAX; - -/// -/// @{ Define value for bit field CPUID_VERSION_INFO_EAX.ProcessorType -/// -#define CPUID_VERSION_INFO_EAX_PROCESSOR_TYPE_ORIGINAL_OEM_PROCESSOR 0x00 -#define CPUID_VERSION_INFO_EAX_PROCESSOR_TYPE_INTEL_OVERDRIVE_PROCESSOR 0x01 -#define CPUID_VERSION_INFO_EAX_PROCESSOR_TYPE_DUAL_PROCESSOR 0x02 -/// -/// @} -/// - -/** - CPUID Version Information returned in EBX for CPUID leaf - #CPUID_VERSION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Provides an entry into a brand string table that contains - /// brand strings for IA-32 processors. - /// - UINT32 BrandIndex:8; - /// - /// [Bits 15:8] Indicates the size of the cache line flushed by the CLFLUSH - /// and CLFLUSHOPT instructions in 8-byte increments. This field was - /// introduced in the Pentium 4 processor. - /// - UINT32 CacheLineSize:8; - /// - /// [Bits 23:16] Maximum number of addressable IDs for logical processors - /// in this physical package. - /// - /// @note - /// The nearest power-of-2 integer that is not smaller than EBX[23:16] is - /// the number of unique initial APICIDs reserved for addressing different - /// logical processors in a physical package. This field is only valid if - /// CPUID.1.EDX.HTT[bit 28]= 1. - /// - UINT32 MaximumAddressableIdsForLogicalProcessors:8; - /// - /// [Bits 31:24] The 8-bit ID that is assigned to the local APIC on the - /// processor during power up. This field was introduced in the Pentium 4 - /// processor. - /// - UINT32 InitialLocalApicId:8; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_VERSION_INFO_EBX; - -/** - CPUID Version Information returned in ECX for CPUID leaf - #CPUID_VERSION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Streaming SIMD Extensions 3 (SSE3). A value of 1 indicates the - /// processor supports this technology - /// - UINT32 SSE3:1; - /// - /// [Bit 1] A value of 1 indicates the processor supports the PCLMULQDQ - /// instruction. Carryless Multiplication - /// - UINT32 PCLMULQDQ:1; - /// - /// [Bit 2] 64-bit DS Area. A value of 1 indicates the processor supports - /// DS area using 64-bit layout. - /// - UINT32 DTES64:1; - /// - /// [Bit 3] MONITOR/MWAIT. A value of 1 indicates the processor supports - /// this feature. - /// - UINT32 MONITOR:1; - /// - /// [Bit 4] CPL Qualified Debug Store. A value of 1 indicates the processor - /// supports the extensions to the Debug Store feature to allow for branch - /// message storage qualified by CPL - /// - UINT32 DS_CPL:1; - /// - /// [Bit 5] Virtual Machine Extensions. A value of 1 indicates that the - /// processor supports this technology. - /// - UINT32 VMX:1; - /// - /// [Bit 6] Safer Mode Extensions. A value of 1 indicates that the processor - /// supports this technology - /// - UINT32 SMX:1; - /// - /// [Bit 7] Enhanced Intel SpeedStep(R) technology. A value of 1 indicates - /// that the processor supports this technology - /// - UINT32 EIST:1; - /// - /// [Bit 8] Thermal Monitor 2. A value of 1 indicates whether the processor - /// supports this technology - /// - UINT32 TM2:1; - /// - /// [Bit 9] A value of 1 indicates the presence of the Supplemental Streaming - /// SIMD Extensions 3 (SSSE3). A value of 0 indicates the instruction - /// extensions are not present in the processor. - /// - UINT32 SSSE3:1; - /// - /// [Bit 10] L1 Context ID. A value of 1 indicates the L1 data cache mode - /// can be set to either adaptive mode or shared mode. A value of 0 indicates - /// this feature is not supported. See definition of the IA32_MISC_ENABLE MSR - /// Bit 24 (L1 Data Cache Context Mode) for details - /// - UINT32 CNXT_ID:1; - /// - /// [Bit 11] A value of 1 indicates the processor supports IA32_DEBUG_INTERFACE - /// MSR for silicon debug - /// - UINT32 SDBG:1; - /// - /// [Bit 12] A value of 1 indicates the processor supports FMA (Fused Multiple - /// Add) extensions using YMM state. - /// - UINT32 FMA:1; - /// - /// [Bit 13] CMPXCHG16B Available. A value of 1 indicates that the feature - /// is available. - /// - UINT32 CMPXCHG16B:1; - /// - /// [Bit 14] xTPR Update Control. A value of 1 indicates that the processor - /// supports changing IA32_MISC_ENABLE[Bit 23]. - /// - UINT32 xTPR_Update_Control:1; - /// - /// [Bit 15] Perfmon and Debug Capability: A value of 1 indicates the - /// processor supports the performance and debug feature indication MSR - /// IA32_PERF_CAPABILITIES. - /// - UINT32 PDCM:1; - UINT32 Reserved:1; - /// - /// [Bit 17] Process-context identifiers. A value of 1 indicates that the - /// processor supports PCIDs and that software may set CR4.PCIDE to 1. - /// - UINT32 PCID:1; - /// - /// [Bit 18] A value of 1 indicates the processor supports the ability to - /// prefetch data from a memory mapped device. Direct Cache Access. - /// - UINT32 DCA:1; - /// - /// [Bit 19] A value of 1 indicates that the processor supports SSE4.1. - /// - UINT32 SSE4_1:1; - /// - /// [Bit 20] A value of 1 indicates that the processor supports SSE4.2. - /// - UINT32 SSE4_2:1; - /// - /// [Bit 21] A value of 1 indicates that the processor supports x2APIC - /// feature. - /// - UINT32 x2APIC:1; - /// - /// [Bit 22] A value of 1 indicates that the processor supports MOVBE - /// instruction. - /// - UINT32 MOVBE:1; - /// - /// [Bit 23] A value of 1 indicates that the processor supports the POPCNT - /// instruction. - /// - UINT32 POPCNT:1; - /// - /// [Bit 24] A value of 1 indicates that the processor's local APIC timer - /// supports one-shot operation using a TSC deadline value. - /// - UINT32 TSC_Deadline:1; - /// - /// [Bit 25] A value of 1 indicates that the processor supports the AESNI - /// instruction extensions. - /// - UINT32 AESNI:1; - /// - /// [Bit 26] A value of 1 indicates that the processor supports the - /// XSAVE/XRSTOR processor extended states feature, the XSETBV/XGETBV - /// instructions, and XCR0. - /// - UINT32 XSAVE:1; - /// - /// [Bit 27] A value of 1 indicates that the OS has set CR4.OSXSAVE[Bit 18] - /// to enable XSETBV/XGETBV instructions to access XCR0 and to support - /// processor extended state management using XSAVE/XRSTOR. - /// - UINT32 OSXSAVE:1; - /// - /// [Bit 28] A value of 1 indicates the processor supports the AVX instruction - /// extensions. - /// - UINT32 AVX:1; - /// - /// [Bit 29] A value of 1 indicates that processor supports 16-bit - /// floating-point conversion instructions. - /// - UINT32 F16C:1; - /// - /// [Bit 30] A value of 1 indicates that processor supports RDRAND instruction. - /// - UINT32 RDRAND:1; - /// - /// [Bit 31] Always returns 0. - /// - UINT32 NotUsed:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_VERSION_INFO_ECX; - -/** - CPUID Version Information returned in EDX for CPUID leaf - #CPUID_VERSION_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Floating Point Unit On-Chip. The processor contains an x87 FPU. - /// - UINT32 FPU:1; - /// - /// [Bit 1] Virtual 8086 Mode Enhancements. Virtual 8086 mode enhancements, - /// including CR4.VME for controlling the feature, CR4.PVI for protected - /// mode virtual interrupts, software interrupt indirection, expansion of - /// the TSS with the software indirection bitmap, and EFLAGS.VIF and - /// EFLAGS.VIP flags. - /// - UINT32 VME:1; - /// - /// [Bit 2] Debugging Extensions. Support for I/O breakpoints, including - /// CR4.DE for controlling the feature, and optional trapping of accesses to - /// DR4 and DR5. - /// - UINT32 DE:1; - /// - /// [Bit 3] Page Size Extension. Large pages of size 4 MByte are supported, - /// including CR4.PSE for controlling the feature, the defined dirty bit in - /// PDE (Page Directory Entries), optional reserved bit trapping in CR3, - /// PDEs, and PTEs. - /// - UINT32 PSE:1; - /// - /// [Bit 4] Time Stamp Counter. The RDTSC instruction is supported, - /// including CR4.TSD for controlling privilege. - /// - UINT32 TSC:1; - /// - /// [Bit 5] Model Specific Registers RDMSR and WRMSR Instructions. The - /// RDMSR and WRMSR instructions are supported. Some of the MSRs are - /// implementation dependent. - /// - UINT32 MSR:1; - /// - /// [Bit 6] Physical Address Extension. Physical addresses greater than 32 - /// bits are supported: extended page table entry formats, an extra level in - /// the page translation tables is defined, 2-MByte pages are supported - /// instead of 4 Mbyte pages if PAE bit is 1. - /// - UINT32 PAE:1; - /// - /// [Bit 7] Machine Check Exception. Exception 18 is defined for Machine - /// Checks, including CR4.MCE for controlling the feature. This feature does - /// not define the model-specific implementations of machine-check error - /// logging, reporting, and processor shutdowns. Machine Check exception - /// handlers may have to depend on processor version to do model specific - /// processing of the exception, or test for the presence of the Machine - /// Check feature. - /// - UINT32 MCE:1; - /// - /// [Bit 8] CMPXCHG8B Instruction. The compare-and-exchange 8 bytes(64 bits) - /// instruction is supported (implicitly locked and atomic). - /// - UINT32 CX8:1; - /// - /// [Bit 9] APIC On-Chip. The processor contains an Advanced Programmable - /// Interrupt Controller (APIC), responding to memory mapped commands in the - /// physical address range FFFE0000H to FFFE0FFFH (by default - some - /// processors permit the APIC to be relocated). - /// - UINT32 APIC:1; - UINT32 Reserved1:1; - /// - /// [Bit 11] SYSENTER and SYSEXIT Instructions. The SYSENTER and SYSEXIT - /// and associated MSRs are supported. - /// - UINT32 SEP:1; - /// - /// [Bit 12] Memory Type Range Registers. MTRRs are supported. The MTRRcap - /// MSR contains feature bits that describe what memory types are supported, - /// how many variable MTRRs are supported, and whether fixed MTRRs are - /// supported. - /// - UINT32 MTRR:1; - /// - /// [Bit 13] Page Global Bit. The global bit is supported in paging-structure - /// entries that map a page, indicating TLB entries that are common to - /// different processes and need not be flushed. The CR4.PGE bit controls - /// this feature. - /// - UINT32 PGE:1; - /// - /// [Bit 14] Machine Check Architecture. A value of 1 indicates the Machine - /// Check Architecture of reporting machine errors is supported. The MCG_CAP - /// MSR contains feature bits describing how many banks of error reporting - /// MSRs are supported. - /// - UINT32 MCA:1; - /// - /// [Bit 15] Conditional Move Instructions. The conditional move instruction - /// CMOV is supported. In addition, if x87 FPU is present as indicated by the - /// CPUID.FPU feature bit, then the FCOMI and FCMOV instructions are supported. - /// - UINT32 CMOV:1; - /// - /// [Bit 16] Page Attribute Table. Page Attribute Table is supported. This - /// feature augments the Memory Type Range Registers (MTRRs), allowing an - /// operating system to specify attributes of memory accessed through a - /// linear address on a 4KB granularity. - /// - UINT32 PAT:1; - /// - /// [Bit 17] 36-Bit Page Size Extension. 4-MByte pages addressing physical - /// memory beyond 4 GBytes are supported with 32-bit paging. This feature - /// indicates that upper bits of the physical address of a 4-MByte page are - /// encoded in bits 20:13 of the page-directory entry. Such physical - /// addresses are limited by MAXPHYADDR and may be up to 40 bits in size. - /// - UINT32 PSE_36:1; - /// - /// [Bit 18] Processor Serial Number. The processor supports the 96-bit - /// processor identification number feature and the feature is enabled. - /// - UINT32 PSN:1; - /// - /// [Bit 19] CLFLUSH Instruction. CLFLUSH Instruction is supported. - /// - UINT32 CLFSH:1; - UINT32 Reserved2:1; - /// - /// [Bit 21] Debug Store. The processor supports the ability to write debug - /// information into a memory resident buffer. This feature is used by the - /// branch trace store (BTS) and precise event-based sampling (PEBS) - /// facilities. - /// - UINT32 DS:1; - /// - /// [Bit 22] Thermal Monitor and Software Controlled Clock Facilities. The - /// processor implements internal MSRs that allow processor temperature to - /// be monitored and processor performance to be modulated in predefined - /// duty cycles under software control. - /// - UINT32 ACPI:1; - /// - /// [Bit 23] Intel MMX Technology. The processor supports the Intel MMX - /// technology. - /// - UINT32 MMX:1; - /// - /// [Bit 24] FXSAVE and FXRSTOR Instructions. The FXSAVE and FXRSTOR - /// instructions are supported for fast save and restore of the floating - /// point context. Presence of this bit also indicates that CR4.OSFXSR is - /// available for an operating system to indicate that it supports the - /// FXSAVE and FXRSTOR instructions. - /// - UINT32 FXSR:1; - /// - /// [Bit 25] SSE. The processor supports the SSE extensions. - /// - UINT32 SSE:1; - /// - /// [Bit 26] SSE2. The processor supports the SSE2 extensions. - /// - UINT32 SSE2:1; - /// - /// [Bit 27] Self Snoop. The processor supports the management of - /// conflicting memory types by performing a snoop of its own cache - /// structure for transactions issued to the bus. - /// - UINT32 SS:1; - /// - /// [Bit 28] Max APIC IDs reserved field is Valid. A value of 0 for HTT - /// indicates there is only a single logical processor in the package and - /// software should assume only a single APIC ID is reserved. A value of 1 - /// for HTT indicates the value in CPUID.1.EBX[23:16] (the Maximum number of - /// addressable IDs for logical processors in this package) is valid for the - /// package. - /// - UINT32 HTT:1; - /// - /// [Bit 29] Thermal Monitor. The processor implements the thermal monitor - /// automatic thermal control circuitry (TCC). - /// - UINT32 TM:1; - UINT32 Reserved3:1; - /// - /// [Bit 31] Pending Break Enable. The processor supports the use of the - /// FERR#/PBE# pin when the processor is in the stop-clock state (STPCLK# is - /// asserted) to signal the processor that an interrupt is pending and that - /// the processor should return to normal operation to handle the interrupt. - /// Bit 10 (PBE enable) in the IA32_MISC_ENABLE MSR enables this capability. - /// - UINT32 PBE:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_VERSION_INFO_EDX; - - -/** - CPUID Cache and TLB Information - - @param EAX CPUID_CACHE_INFO (0x02) - - @retval EAX Cache and TLB Information described by the type - CPUID_CACHE_INFO_CACHE_TLB. - CPUID_CACHE_INFO_CACHE_TLB.CacheDescriptor[0] always returns - 0x01 and must be ignored. Only valid if - CPUID_CACHE_INFO_CACHE_TLB.Bits.NotValid is clear. - @retval EBX Cache and TLB Information described by the type - CPUID_CACHE_INFO_CACHE_TLB. Only valid if - CPUID_CACHE_INFO_CACHE_TLB.Bits.NotValid is clear. - @retval ECX Cache and TLB Information described by the type - CPUID_CACHE_INFO_CACHE_TLB. Only valid if - CPUID_CACHE_INFO_CACHE_TLB.Bits.NotValid is clear. - @retval EDX Cache and TLB Information described by the type - CPUID_CACHE_INFO_CACHE_TLB. Only valid if - CPUID_CACHE_INFO_CACHE_TLB.Bits.NotValid is clear. - - Example usage - @code - CPUID_CACHE_INFO_CACHE_TLB Eax; - CPUID_CACHE_INFO_CACHE_TLB Ebx; - CPUID_CACHE_INFO_CACHE_TLB Ecx; - CPUID_CACHE_INFO_CACHE_TLB Edx; - - AsmCpuid (CPUID_CACHE_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode - - Cache Descriptor values - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Value Type Description
0x00 General Null descriptor, this byte contains no information
0x01 TLB Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries
0x02 TLB Instruction TLB: 4 MByte pages, fully associative, 2 entries
0x03 TLB Data TLB: 4 KByte pages, 4-way set associative, 64 entries
0x04 TLB Data TLB: 4 MByte pages, 4-way set associative, 8 entries
0x05 TLB Data TLB1: 4 MByte pages, 4-way set associative, 32 entries
0x06 Cache 1st-level instruction cache: 8 KBytes, 4-way set associative, - 32 byte line size
0x08 Cache 1st-level instruction cache: 16 KBytes, 4-way set associative, - 32 byte line size
0x09 Cache 1st-level instruction cache: 32KBytes, 4-way set associative, - 64 byte line size
0x0A Cache 1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size
0x0B TLB Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries
0x0C Cache 1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size
0x0D Cache 1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size
0x0E Cache 1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size
0x1D Cache 2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size
0x21 Cache 2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size
0x22 Cache 3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, - 2 lines per sector
0x23 Cache 3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, - 2 lines per sector
0x24 Cache 2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size
0x25 Cache 3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, - 2 lines per sector
0x29 Cache 3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, - 2 lines per sector
0x2C Cache 1st-level data cache: 32 KBytes, 8-way set associative, - 64 byte line size
0x30 Cache 1st-level instruction cache: 32 KBytes, 8-way set associative, - 64 byte line size
0x40 Cache No 2nd-level cache or, if processor contains a valid 2nd-level cache, - no 3rd-level cache
0x41 Cache 2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size
0x42 Cache 2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size
0x43 Cache 2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size
0x44 Cache 2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size
0x45 Cache 2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size
0x46 Cache 3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size
0x47 Cache 3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size
0x48 Cache 2nd-level cache: 3MByte, 12-way set associative, 64 byte line size
0x49 Cache 3rd-level cache: 4MB, 16-way set associative, 64-byte line size - (Intel Xeon processor MP, Family 0FH, Model 06H)
- 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size
0x4A Cache 3rd-level cache: 6MByte, 12-way set associative, 64 byte line size
0x4B Cache 3rd-level cache: 8MByte, 16-way set associative, 64 byte line size
0x4C Cache 3rd-level cache: 12MByte, 12-way set associative, 64 byte line size
0x4D Cache 3rd-level cache: 16MByte, 16-way set associative, 64 byte line size
0x4E Cache 2nd-level cache: 6MByte, 24-way set associative, 64 byte line size
0x4F TLB Instruction TLB: 4 KByte pages, 32 entries
0x50 TLB Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries
0x51 TLB Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries
0x52 TLB Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries
0x55 TLB Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries
0x56 TLB Data TLB0: 4 MByte pages, 4-way set associative, 16 entries
0x57 TLB Data TLB0: 4 KByte pages, 4-way associative, 16 entries
0x59 TLB Data TLB0: 4 KByte pages, fully associative, 16 entries
0x5A TLB Data TLB0: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries
0x5B TLB Data TLB: 4 KByte and 4 MByte pages, 64 entries
0x5C TLB Data TLB: 4 KByte and 4 MByte pages,128 entries
0x5D TLB Data TLB: 4 KByte and 4 MByte pages,256 entries
0x60 Cache 1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size
0x61 TLB Instruction TLB: 4 KByte pages, fully associative, 48 entries
0x63 TLB Data TLB: 2 MByte or 4 MByte pages, 4-way set associative, - 32 entries and a separate array with 1 GByte pages, 4-way set associative, - 4 entries
0x64 TLB Data TLB: 4 KByte pages, 4-way set associative, 512 entries
0x66 Cache 1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size
0x67 Cache 1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size
0x68 Cache 1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size
0x6A Cache uTLB: 4 KByte pages, 8-way set associative, 64 entries
0x6B Cache DTLB: 4 KByte pages, 8-way set associative, 256 entries
0x6C Cache DTLB: 2M/4M pages, 8-way set associative, 128 entries
0x6D Cache DTLB: 1 GByte pages, fully associative, 16 entries
0x70 Cache Trace cache: 12 K-uop, 8-way set associative
0x71 Cache Trace cache: 16 K-uop, 8-way set associative
0x72 Cache Trace cache: 32 K-uop, 8-way set associative
0x76 TLB Instruction TLB: 2M/4M pages, fully associative, 8 entries
0x78 Cache 2nd-level cache: 1 MByte, 4-way set associative, 64byte line size
0x79 Cache 2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, - 2 lines per sector
0x7A Cache 2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, - 2 lines per sector
0x7B Cache 2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, - 2 lines per sector
0x7C Cache 2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, - 2 lines per sector
0x7D Cache 2nd-level cache: 2 MByte, 8-way set associative, 64byte line size
0x7F Cache 2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size
0x80 Cache 2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size
0x82 Cache 2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size
0x83 Cache 2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size
0x84 Cache 2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size
0x85 Cache 2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size
0x86 Cache 2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size
0x87 Cache 2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size
0xA0 DTLB DTLB: 4k pages, fully associative, 32 entries
0xB0 TLB Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries
0xB1 TLB Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries
0xB2 TLB Instruction TLB: 4KByte pages, 4-way set associative, 64 entries
0xB3 TLB Data TLB: 4 KByte pages, 4-way set associative, 128 entries
0xB4 TLB Data TLB1: 4 KByte pages, 4-way associative, 256 entries
0xB5 TLB Instruction TLB: 4KByte pages, 8-way set associative, 64 entries
0xB6 TLB Instruction TLB: 4KByte pages, 8-way set associative, - 128 entries
0xBA TLB Data TLB1: 4 KByte pages, 4-way associative, 64 entries
0xC0 TLB Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries
0xC1 STLB Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, - 1024 entries
0xC2 DTLB DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries
0xC3 STLB Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, - 1536 entries. Also 1GBbyte pages, 4-way, 16 entries.
0xC4 DTLB DTLB: 2M/4M Byte pages, 4-way associative, 32 entries
0xCA STLB Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries
0xD0 Cache 3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size
0xD1 Cache 3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size
0xD2 Cache 3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size
0xD6 Cache 3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size
0xD7 Cache 3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size
0xD8 Cache 3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size
0xDC Cache 3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size
0xDD Cache 3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size
0xDE Cache 3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size
0xE2 Cache 3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size
0xE3 Cache 3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size
0xE4 Cache 3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size
0xEA Cache 3rd-level cache: 12MByte, 24-way set associative, 64 byte line size
0xEB Cache 3rd-level cache: 18MByte, 24-way set associative, 64 byte line size
0xEC Cache 3rd-level cache: 24MByte, 24-way set associative, 64 byte line size
0xF0 Prefetch 64-Byte prefetching
0xF1 Prefetch 128-Byte prefetching
0xFF General CPUID leaf 2 does not report cache descriptor information, - use CPUID leaf 4 to query cache parameters
-**/ -#define CPUID_CACHE_INFO 0x02 - -/** - CPUID Cache and TLB Information returned in EAX, EBX, ECX, and EDX for CPUID - leaf #CPUID_CACHE_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:31; - /// - /// [Bit 31] If 0, then the cache descriptor bytes in the register are valid. - /// if 1, then none of the cache descriptor bytes in the register are valid. - /// - UINT32 NotValid:1; - } Bits; - /// - /// Array of Cache and TLB descriptor bytes - /// - UINT8 CacheDescriptor[4]; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_CACHE_INFO_CACHE_TLB; - - -/** - CPUID Processor Serial Number - - Processor serial number (PSN) is not supported in the Pentium 4 processor - or later. On all models, use the PSN flag (returned using CPUID) to check - for PSN support before accessing the feature. - - @param EAX CPUID_SERIAL_NUMBER (0x03) - - @retval EAX Reserved. - @retval EBX Reserved. - @retval ECX Bits 31:0 of 96 bit processor serial number. (Available in - Pentium III processor only; otherwise, the value in this - register is reserved.) - @retval EDX Bits 63:32 of 96 bit processor serial number. (Available in - Pentium III processor only; otherwise, the value in this - register is reserved.) - - Example usage - @code - UINT32 Ecx; - UINT32 Edx; - - AsmCpuid (CPUID_SERIAL_NUMBER, NULL, NULL, &Ecx, &Edx); - @endcode -**/ -#define CPUID_SERIAL_NUMBER 0x03 - - -/** - CPUID Cache Parameters - - @param EAX CPUID_CACHE_PARAMS (0x04) - @param ECX Cache Level. Valid values start at 0. Software can enumerate - the deterministic cache parameters for each level of the cache - hierarchy starting with an index value of 0, until the - parameters report the value associated with the CacheType - field in CPUID_CACHE_PARAMS_EAX is 0. - - @retval EAX Returns cache type information described by the type - CPUID_CACHE_PARAMS_EAX. - @retval EBX Returns cache line and associativity information described by - the type CPUID_CACHE_PARAMS_EBX. - @retval ECX Returns the number of sets in the cache. - @retval EDX Returns cache WINVD/INVD behavior described by the type - CPUID_CACHE_PARAMS_EDX. - - Example usage - @code - UINT32 CacheLevel; - CPUID_CACHE_PARAMS_EAX Eax; - CPUID_CACHE_PARAMS_EBX Ebx; - UINT32 Ecx; - CPUID_CACHE_PARAMS_EDX Edx; - - CacheLevel = 0; - do { - AsmCpuidEx ( - CPUID_CACHE_PARAMS, CacheLevel, - &Eax.Uint32, &Ebx.Uint32, &Ecx, &Edx.Uint32 - ); - CacheLevel++; - } while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL); - @endcode -**/ -#define CPUID_CACHE_PARAMS 0x04 - -/** - CPUID Cache Parameters Information returned in EAX for CPUID leaf - #CPUID_CACHE_PARAMS. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Cache type field. If #CPUID_CACHE_PARAMS_CACHE_TYPE_NULL, - /// then there is no information for the requested cache level. - /// - UINT32 CacheType:5; - /// - /// [Bits 7:5] Cache level (Starts at 1). - /// - UINT32 CacheLevel:3; - /// - /// [Bit 8] Self Initializing cache level (does not need SW initialization). - /// - UINT32 SelfInitializingCache:1; - /// - /// [Bit 9] Fully Associative cache. - /// - UINT32 FullyAssociativeCache:1; - /// - /// [Bits 13:10] Reserved. - /// - UINT32 Reserved:4; - /// - /// [Bits 25:14] Maximum number of addressable IDs for logical processors - /// sharing this cache. - /// - /// Add one to the return value to get the result. - /// The nearest power-of-2 integer that is not smaller than (1 + EAX[25:14]) - /// is the number of unique initial APIC IDs reserved for addressing - /// different logical processors sharing this cache. - /// - UINT32 MaximumAddressableIdsForLogicalProcessors:12; - /// - /// [Bits 31:26] Maximum number of addressable IDs for processor cores in - /// the physical package. - /// - /// The nearest power-of-2 integer that is not smaller than (1 + EAX[31:26]) - /// is the number of unique Core_IDs reserved for addressing different - /// processor cores in a physical package. Core ID is a subset of bits of - /// the initial APIC ID. - /// The returned value is constant for valid initial values in ECX. Valid - /// ECX values start from 0. - /// - UINT32 MaximumAddressableIdsForProcessorCores:6; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_CACHE_PARAMS_EAX; - -/// -/// @{ Define value for bit field CPUID_CACHE_PARAMS_EAX.CacheType -/// -#define CPUID_CACHE_PARAMS_CACHE_TYPE_NULL 0x00 -#define CPUID_CACHE_PARAMS_CACHE_TYPE_DATA 0x01 -#define CPUID_CACHE_PARAMS_CACHE_TYPE_INSTRUCTION 0x02 -#define CPUID_CACHE_PARAMS_CACHE_TYPE_UNIFIED 0x03 -/// -/// @} -/// - -/** - CPUID Cache Parameters Information returned in EBX for CPUID leaf - #CPUID_CACHE_PARAMS. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 11:0] System Coherency Line Size. Add one to the return value to - /// get the result. - /// - UINT32 LineSize:12; - /// - /// [Bits 21:12] Physical Line Partitions. Add one to the return value to - /// get the result. - /// - UINT32 LinePartitions:10; - /// - /// [Bits 31:22] Ways of associativity. Add one to the return value to get - /// the result. - /// - UINT32 Ways:10; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_CACHE_PARAMS_EBX; - -/** - CPUID Cache Parameters Information returned in EDX for CPUID leaf - #CPUID_CACHE_PARAMS. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Write-Back Invalidate/Invalidate. - /// 0 = WBINVD/INVD from threads sharing this cache acts upon lower level - /// caches for threads sharing this cache. - /// 1 = WBINVD/INVD is not guaranteed to act upon lower level caches of - /// non-originating threads sharing this cache. - /// - UINT32 Invalidate:1; - /// - /// [Bit 1] Cache Inclusiveness. - /// 0 = Cache is not inclusive of lower cache levels. - /// 1 = Cache is inclusive of lower cache levels. - /// - UINT32 CacheInclusiveness:1; - /// - /// [Bit 2] Complex Cache Indexing. - /// 0 = Direct mapped cache. - /// 1 = A complex function is used to index the cache, potentially using all - /// address bits. - /// - UINT32 ComplexCacheIndexing:1; - UINT32 Reserved:29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_CACHE_PARAMS_EDX; - - -/** - CPUID MONITOR/MWAIT Information - - @param EAX CPUID_MONITOR_MWAIT (0x05) - - @retval EAX Smallest monitor-line size in bytes described by the type - CPUID_MONITOR_MWAIT_EAX. - @retval EBX Largest monitor-line size in bytes described by the type - CPUID_MONITOR_MWAIT_EBX. - @retval ECX Enumeration of Monitor-Mwait extensions support described by - the type CPUID_MONITOR_MWAIT_ECX. - @retval EDX Sub C-states supported described by the type - CPUID_MONITOR_MWAIT_EDX. - - Example usage - @code - CPUID_MONITOR_MWAIT_EAX Eax; - CPUID_MONITOR_MWAIT_EBX Ebx; - CPUID_MONITOR_MWAIT_ECX Ecx; - CPUID_MONITOR_MWAIT_EDX Edx; - - AsmCpuid (CPUID_MONITOR_MWAIT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_MONITOR_MWAIT 0x05 - -/** - CPUID MONITOR/MWAIT Information returned in EAX for CPUID leaf - #CPUID_MONITOR_MWAIT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Smallest monitor-line size in bytes (default is processor's - /// monitor granularity). - /// - UINT32 SmallestMonitorLineSize:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MONITOR_MWAIT_EAX; - -/** - CPUID MONITOR/MWAIT Information returned in EBX for CPUID leaf - #CPUID_MONITOR_MWAIT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Largest monitor-line size in bytes (default is processor's - /// monitor granularity). - /// - UINT32 LargestMonitorLineSize:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MONITOR_MWAIT_EBX; - -/** - CPUID MONITOR/MWAIT Information returned in ECX for CPUID leaf - #CPUID_MONITOR_MWAIT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] If 0, then only EAX and EBX are valid. If 1, then EAX, EBX, ECX, - /// and EDX are valid. - /// - UINT32 ExtensionsSupported:1; - /// - /// [Bit 1] Supports treating interrupts as break-event for MWAIT, even when - /// interrupts disabled. - /// - UINT32 InterruptAsBreak:1; - UINT32 Reserved:30; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MONITOR_MWAIT_ECX; - -/** - CPUID MONITOR/MWAIT Information returned in EDX for CPUID leaf - #CPUID_MONITOR_MWAIT. - - @note - The definition of C0 through C7 states for MWAIT extension are - processor-specific C-states, not ACPI C-states. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Number of C0 sub C-states supported using MWAIT. - /// - UINT32 C0States:4; - /// - /// [Bits 7:4] Number of C1 sub C-states supported using MWAIT. - /// - UINT32 C1States:4; - /// - /// [Bits 11:8] Number of C2 sub C-states supported using MWAIT. - /// - UINT32 C2States:4; - /// - /// [Bits 15:12] Number of C3 sub C-states supported using MWAIT. - /// - UINT32 C3States:4; - /// - /// [Bits 19:16] Number of C4 sub C-states supported using MWAIT. - /// - UINT32 C4States:4; - /// - /// [Bits 23:20] Number of C5 sub C-states supported using MWAIT. - /// - UINT32 C5States:4; - /// - /// [Bits 27:24] Number of C6 sub C-states supported using MWAIT. - /// - UINT32 C6States:4; - /// - /// [Bits 31:28] Number of C7 sub C-states supported using MWAIT. - /// - UINT32 C7States:4; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_MONITOR_MWAIT_EDX; - - -/** - CPUID Thermal and Power Management - - @param EAX CPUID_THERMAL_POWER_MANAGEMENT (0x06) - - @retval EAX Thermal and power management features described by the type - CPUID_THERMAL_POWER_MANAGEMENT_EAX. - @retval EBX Number of Interrupt Thresholds in Digital Thermal Sensor - described by the type CPUID_THERMAL_POWER_MANAGEMENT_EBX. - @retval ECX Performance features described by the type - CPUID_THERMAL_POWER_MANAGEMENT_ECX. - @retval EDX Reserved. - - Example usage - @code - CPUID_THERMAL_POWER_MANAGEMENT_EAX Eax; - CPUID_THERMAL_POWER_MANAGEMENT_EBX Ebx; - CPUID_THERMAL_POWER_MANAGEMENT_ECX Ecx; - - AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); - @endcode -**/ -#define CPUID_THERMAL_POWER_MANAGEMENT 0x06 - -/** - CPUID Thermal and Power Management Information returned in EAX for CPUID leaf - #CPUID_THERMAL_POWER_MANAGEMENT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Digital temperature sensor is supported if set. - /// - UINT32 DigitalTemperatureSensor:1; - /// - /// [Bit 1] Intel Turbo Boost Technology Available (see IA32_MISC_ENABLE[38]). - /// - UINT32 TurboBoostTechnology:1; - /// - /// [Bit 2] APIC-Timer-always-running feature is supported if set. - /// - UINT32 ARAT:1; - UINT32 Reserved1:1; - /// - /// [Bit 4] Power limit notification controls are supported if set. - /// - UINT32 PLN:1; - /// - /// [Bit 5] Clock modulation duty cycle extension is supported if set. - /// - UINT32 ECMD:1; - /// - /// [Bit 6] Package thermal management is supported if set. - /// - UINT32 PTM:1; - /// - /// [Bit 7] HWP base registers (IA32_PM_ENABLE[Bit 0], IA32_HWP_CAPABILITIES, - /// IA32_HWP_REQUEST, IA32_HWP_STATUS) are supported if set. - /// - UINT32 HWP:1; - /// - /// [Bit 8] IA32_HWP_INTERRUPT MSR is supported if set. - /// - UINT32 HWP_Notification:1; - /// - /// [Bit 9] IA32_HWP_REQUEST[Bits 41:32] is supported if set. - /// - UINT32 HWP_Activity_Window:1; - /// - /// [Bit 10] IA32_HWP_REQUEST[Bits 31:24] is supported if set. - /// - UINT32 HWP_Energy_Performance_Preference:1; - /// - /// [Bit 11] IA32_HWP_REQUEST_PKG MSR is supported if set. - /// - UINT32 HWP_Package_Level_Request:1; - UINT32 Reserved2:1; - /// - /// [Bit 13] HDC base registers IA32_PKG_HDC_CTL, IA32_PM_CTL1, - /// IA32_THREAD_STALL MSRs are supported if set. - /// - UINT32 HDC:1; - UINT32 Reserved3:18; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_THERMAL_POWER_MANAGEMENT_EAX; - -/** - CPUID Thermal and Power Management Information returned in EBX for CPUID leaf - #CPUID_THERMAL_POWER_MANAGEMENT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// {Bits 3:0] Number of Interrupt Thresholds in Digital Thermal Sensor. - /// - UINT32 InterruptThresholds:4; - UINT32 Reserved:28; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_THERMAL_POWER_MANAGEMENT_EBX; - -/** - CPUID Thermal and Power Management Information returned in ECX for CPUID leaf - #CPUID_THERMAL_POWER_MANAGEMENT. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Hardware Coordination Feedback Capability (Presence of IA32_MPERF - /// and IA32_APERF). The capability to provide a measure of delivered - /// processor performance (since last reset of the counters), as a percentage - /// of the expected processor performance when running at the TSC frequency. - /// - UINT32 HardwareCoordinationFeedback:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] If this bit is set, then the processor supports performance-energy - /// bias preference and the architectural MSR called IA32_ENERGY_PERF_BIAS - /// (1B0H). - /// - UINT32 PerformanceEnergyBias:1; - UINT32 Reserved2:28; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_THERMAL_POWER_MANAGEMENT_ECX; - - -/** - CPUID Structured Extended Feature Flags Enumeration - - @param EAX CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (0x07) - @param ECX CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO (0x00). - - @note - If ECX contains an invalid sub-leaf index, EAX/EBX/ECX/EDX return 0. Sub-leaf - index n is invalid if n exceeds the value that sub-leaf 0 returns in EAX. - - @retval EAX The maximum input value for ECX to retrieve sub-leaf information. - @retval EBX Structured Extended Feature Flags described by the type - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX. - @retval EBX Structured Extended Feature Flags described by the type - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX. - @retval EDX Reserved. - - Example usage - @code - UINT32 Eax; - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx; - UINT32 SubLeaf; - - AsmCpuidEx ( - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, - &Eax, NULL, NULL, NULL - ); - for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) { - AsmCpuidEx ( - CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, - SubLeaf, - NULL, &Ebx.Uint32, &Ecx.Uint32, NULL - ); - } - @endcode -**/ -#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS 0x07 - -/// -/// CPUID Structured Extended Feature Flags Enumeration sub-leaf -/// -#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO 0x00 - -/** - CPUID Structured Extended Feature Flags Enumeration in EBX for CPUID leaf - #CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS sub leaf - #CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE if 1. - /// - UINT32 FSGSBASE:1; - /// - /// [Bit 1] IA32_TSC_ADJUST MSR is supported if 1. - /// - UINT32 IA32_TSC_ADJUST:1; - /// - /// [Bit 2] Intel SGX is supported if 1. See section 37.7 "DISCOVERING SUPPORT - /// FOR INTEL(R) SGX AND ENABLING ENCLAVE INSTRUCTIONS". - /// - UINT32 SGX:1; - /// - /// [Bit 3] If 1 indicates the processor supports the first group of advanced - /// bit manipulation extensions (ANDN, BEXTR, BLSI, BLSMSK, BLSR, TZCNT) - /// - UINT32 BMI1:1; - /// - /// [Bit 4] Hardware Lock Elision - /// - UINT32 HLE:1; - /// - /// [Bit 5] If 1 indicates the processor supports AVX2 instruction extensions. - /// - UINT32 AVX2:1; - /// - /// [Bit 6] x87 FPU Data Pointer updated only on x87 exceptions if 1. - /// - UINT32 FDP_EXCPTN_ONLY:1; - /// - /// [Bit 7] Supports Supervisor-Mode Execution Prevention if 1. - /// - UINT32 SMEP:1; - /// - /// [Bit 8] If 1 indicates the processor supports the second group of - /// advanced bit manipulation extensions (BZHI, MULX, PDEP, PEXT, RORX, - /// SARX, SHLX, SHRX) - /// - UINT32 BMI2:1; - /// - /// [Bit 9] Supports Enhanced REP MOVSB/STOSB if 1. - /// - UINT32 EnhancedRepMovsbStosb:1; - /// - /// [Bit 10] If 1, supports INVPCID instruction for system software that - /// manages process-context identifiers. - /// - UINT32 INVPCID:1; - /// - /// [Bit 11] Restricted Transactional Memory - /// - UINT32 RTM:1; - /// - /// [Bit 12] Supports Intel(R) Resource Director Technology (Intel(R) RDT) - /// Monitoring capability if 1. - /// - UINT32 RDT_M:1; - /// - /// [Bit 13] Deprecates FPU CS and FPU DS values if 1. - /// - UINT32 DeprecateFpuCsDs:1; - /// - /// [Bit 14] Supports Intel(R) Memory Protection Extensions if 1. - /// - UINT32 MPX:1; - /// - /// [Bit 15] Supports Intel(R) Resource Director Technology (Intel(R) RDT) - /// Allocation capability if 1. - /// - UINT32 RDT_A:1; - UINT32 Reserved2:2; - /// - /// [Bit 18] If 1 indicates the processor supports the RDSEED instruction. - /// - UINT32 RDSEED:1; - /// - /// [Bit 19] If 1 indicates the processor supports the ADCX and ADOX - /// instructions. - /// - UINT32 ADX:1; - /// - /// [Bit 20] Supports Supervisor-Mode Access Prevention (and the CLAC/STAC - /// instructions) if 1. - /// - UINT32 SMAP:1; - UINT32 Reserved3:2; - /// - /// [Bit 23] If 1 indicates the processor supports the CLFLUSHOPT instruction. - /// - UINT32 CLFLUSHOPT:1; - /// - /// [Bit 24] If 1 indicates the processor supports the CLWB instruction. - /// - UINT32 CLWB:1; - /// - /// [Bit 25] If 1 indicates the processor supports the Intel Processor Trace - /// extensions. - /// - UINT32 IntelProcessorTrace:1; - UINT32 Reserved4:3; - /// - /// [Bit 29] Supports Intel(R) Secure Hash Algorithm Extensions (Intel(R) - /// SHA Extensions) if 1. - /// - UINT32 SHA:1; - UINT32 Reserved5:2; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX; - -/** - CPUID Structured Extended Feature Flags Enumeration in ECX for CPUID leaf - #CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS sub leaf - #CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] If 1 indicates the processor supports the PREFETCHWT1 instruction. - /// - UINT32 PREFETCHWT1:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Supports user-mode instruction prevention if 1. - /// - UINT32 UMIP:1; - /// - /// [Bit 3] Supports protection keys for user-mode pages if 1. - /// - UINT32 PKU:1; - /// - /// [Bit 4] If 1, OS has set CR4.PKE to enable protection keys (and the - /// RDPKRU/WRPKRU instructions). - /// - UINT32 OSPKE:1; - UINT32 Reserved2:12; - /// - /// [Bits 21:17] The value of MAWAU used by the BNDLDX and BNDSTX instructions - /// in 64-bit mode. - /// - UINT32 MAWAU:5; - /// - /// [Bit 22] Supports Read Processor ID if 1. - /// - UINT32 RDPID:1; - UINT32 Reserved3:7; - /// - /// [Bit 30] Supports SGX Launch Configuration if 1. - /// - UINT32 SGX_LC:1; - UINT32 Reserved4:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX; - - -/** - CPUID Direct Cache Access Information - - @param EAX CPUID_DIRECT_CACHE_ACCESS_INFO (0x09) - - @retval EAX Value of bits [31:0] of IA32_PLATFORM_DCA_CAP MSR (address 1F8H). - @retval EBX Reserved. - @retval ECX Reserved. - @retval EDX Reserved. - - Example usage - @code - UINT32 Eax; - - AsmCpuid (CPUID_DIRECT_CACHE_ACCESS_INFO, &Eax, NULL, NULL, NULL); - @endcode -**/ -#define CPUID_DIRECT_CACHE_ACCESS_INFO 0x09 - - -/** - CPUID Architectural Performance Monitoring - - @param EAX CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING (0x0A) - - @retval EAX Architectural Performance Monitoring information described by - the type CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX. - @retval EBX Architectural Performance Monitoring information described by - the type CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX. - @retval ECX Reserved. - @retval EDX Architectural Performance Monitoring information described by - the type CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX. - - Example usage - @code - CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX Eax; - CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX Ebx; - CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX Edx; - - AsmCpuid (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING, &Eax.Uint32, &Ebx.Uint32, NULL, &Edx.Uint32); - @endcode -**/ -#define CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING 0x0A - -/** - CPUID Architectural Performance Monitoring EAX for CPUID leaf - #CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 7:0] Version ID of architectural performance monitoring. - /// - UINT32 ArchPerfMonVerID:8; - /// - /// [Bits 15:8] Number of general-purpose performance monitoring counter - /// per logical processor. - /// - /// IA32_PERFEVTSELx MSRs start at address 186H and occupy a contiguous - /// block of MSR address space. Each performance event select register is - /// paired with a corresponding performance counter in the 0C1H address - /// block. - /// - UINT32 PerformanceMonitorCounters:8; - /// - /// [Bits 23:16] Bit width of general-purpose, performance monitoring counter. - /// - /// The bit width of an IA32_PMCx MSR. This the number of valid bits for - /// read operation. On write operations, the lower-order 32 bits of the MSR - /// may be written with any value, and the high-order bits are sign-extended - /// from the value of bit 31. - /// - UINT32 PerformanceMonitorCounterWidth:8; - /// - /// [Bits 31:24] Length of EBX bit vector to enumerate architectural - /// performance monitoring events. - /// - UINT32 EbxBitVectorLength:8; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX; - -/** - CPUID Architectural Performance Monitoring EBX for CPUID leaf - #CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core cycle event not available if 1. - /// - UINT32 UnhaltedCoreCycles:1; - /// - /// [Bit 1] Instruction retired event not available if 1. - /// - UINT32 InstructionsRetired:1; - /// - /// [Bit 2] Reference cycles event not available if 1. - /// - UINT32 UnhaltedReferenceCycles:1; - /// - /// [Bit 3] Last-level cache reference event not available if 1. - /// - UINT32 LastLevelCacheReferences:1; - /// - /// [Bit 4] Last-level cache misses event not available if 1. - /// - UINT32 LastLevelCacheMisses:1; - /// - /// [Bit 5] Branch instruction retired event not available if 1. - /// - UINT32 BranchInstructionsRetired:1; - /// - /// [Bit 6] Branch mispredict retired event not available if 1. - /// - UINT32 AllBranchMispredictRetired:1; - UINT32 Reserved:25; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX; - -/** - CPUID Architectural Performance Monitoring EDX for CPUID leaf - #CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Number of fixed-function performance counters - /// (if Version ID > 1). - /// - UINT32 FixedFunctionPerformanceCounters:5; - /// - /// [Bits 12:5] Bit width of fixed-function performance counters - /// (if Version ID > 1). - /// - UINT32 FixedFunctionPerformanceCounterWidth:8; - UINT32 Reserved:19; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX; - - -/** - CPUID Extended Topology Information - - @note - Most of Leaf 0BH output depends on the initial value in ECX. The EDX output - of leaf 0BH is always valid and does not vary with input value in ECX. Output - value in ECX[7:0] always equals input value in ECX[7:0]. For sub-leaves that - return an invalid level-type of 0 in ECX[15:8]; EAX and EBX will return 0. If - an input value n in ECX returns the invalid level-type of 0 in ECX[15:8], - other input values with ECX > n also return 0 in ECX[15:8]. - - @param EAX CPUID_EXTENDED_TOPOLOGY (0x0B) - @param ECX Level number - - @retval EAX Extended topology information described by the type - CPUID_EXTENDED_TOPOLOGY_EAX. - @retval EBX Extended topology information described by the type - CPUID_EXTENDED_TOPOLOGY_EBX. - @retval ECX Extended topology information described by the type - CPUID_EXTENDED_TOPOLOGY_ECX. - @retval EDX x2APIC ID the current logical processor. - - Example usage - @code - CPUID_EXTENDED_TOPOLOGY_EAX Eax; - CPUID_EXTENDED_TOPOLOGY_EBX Ebx; - CPUID_EXTENDED_TOPOLOGY_ECX Ecx; - UINT32 Edx; - UINT32 LevelNumber; - - LevelNumber = 0; - do { - AsmCpuidEx ( - CPUID_EXTENDED_TOPOLOGY, LevelNumber, - &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx - ); - LevelNumber++; - } while (Eax.Bits.ApicIdShift != 0); - @endcode -**/ -#define CPUID_EXTENDED_TOPOLOGY 0x0B - -/** - CPUID Extended Topology Information EAX for CPUID leaf #CPUID_EXTENDED_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Number of bits to shift right on x2APIC ID to get a unique - /// topology ID of the next level type. All logical processors with the - /// same next level ID share current level. - /// - /// @note - /// Software should use this field (EAX[4:0]) to enumerate processor - /// topology of the system. - /// - UINT32 ApicIdShift:5; - UINT32 Reserved:27; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_TOPOLOGY_EAX; - -/** - CPUID Extended Topology Information EBX for CPUID leaf #CPUID_EXTENDED_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Number of logical processors at this level type. The number - /// reflects configuration as shipped by Intel. - /// - /// @note - /// Software must not use EBX[15:0] to enumerate processor topology of the - /// system. This value in this field (EBX[15:0]) is only intended for - /// display/diagnostic purposes. The actual number of logical processors - /// available to BIOS/OS/Applications may be different from the value of - /// EBX[15:0], depending on software and platform hardware configurations. - /// - UINT32 LogicalProcessors:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_TOPOLOGY_EBX; - -/** - CPUID Extended Topology Information ECX for CPUID leaf #CPUID_EXTENDED_TOPOLOGY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Level number. Same value in ECX input. - /// - UINT32 LevelNumber:8; - /// - /// [Bits 15:8] Level type. - /// - /// @note - /// The value of the "level type" field is not related to level numbers in - /// any way, higher "level type" values do not mean higher levels. - /// - UINT32 LevelType:8; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_TOPOLOGY_ECX; - -/// -/// @{ Define value for CPUID_EXTENDED_TOPOLOGY_ECX.LevelType -/// -#define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID 0x00 -#define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT 0x01 -#define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE 0x02 -/// -/// @} -/// - - -/** - CPUID Extended State Information - - @param EAX CPUID_EXTENDED_STATE (0x0D) - @param ECX CPUID_EXTENDED_STATE_MAIN_LEAF (0x00). - CPUID_EXTENDED_STATE_SUB_LEAF (0x01). - CPUID_EXTENDED_STATE_SIZE_OFFSET (0x02). - Sub leafs 2..n based on supported bits in XCR0 or IA32_XSS_MSR. -**/ -#define CPUID_EXTENDED_STATE 0x0D - -/** - CPUID Extended State Information Main Leaf - - @param EAX CPUID_EXTENDED_STATE (0x0D) - @param ECX CPUID_EXTENDED_STATE_MAIN_LEAF (0x00) - - @retval EAX Reports the supported bits of the lower 32 bits of XCR0. XCR0[n] - can be set to 1 only if EAX[n] is 1. The format of the extended - state main leaf is described by the type - CPUID_EXTENDED_STATE_MAIN_LEAF_EAX. - @retval EBX Maximum size (bytes, from the beginning of the XSAVE/XRSTOR save - area) required by enabled features in XCR0. May be different than - ECX if some features at the end of the XSAVE save area are not - enabled. - @retval ECX Maximum size (bytes, from the beginning of the XSAVE/XRSTOR save - area) of the XSAVE/XRSTOR save area required by all supported - features in the processor, i.e., all the valid bit fields in XCR0. - @retval EDX Reports the supported bits of the upper 32 bits of XCR0. - XCR0[n+32] can be set to 1 only if EDX[n] is 1. - - Example usage - @code - CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax; - UINT32 Ebx; - UINT32 Ecx; - UINT32 Edx; - - AsmCpuidEx ( - CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF, - &Eax.Uint32, &Ebx, &Ecx, &Edx - ); - @endcode -**/ -#define CPUID_EXTENDED_STATE_MAIN_LEAF 0x00 - -/** - CPUID Extended State Information EAX for CPUID leaf #CPUID_EXTENDED_STATE, - sub-leaf #CPUID_EXTENDED_STATE_MAIN_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] x87 state. - /// - UINT32 x87:1; - /// - /// [Bit 1] SSE state. - /// - UINT32 SSE:1; - /// - /// [Bit 2] AVX state. - /// - UINT32 AVX:1; - /// - /// [Bits 4:3] MPX state. - /// - UINT32 MPX:2; - /// - /// [Bits 7:5] AVX-512 state. - /// - UINT32 AVX_512:3; - /// - /// [Bit 8] Used for IA32_XSS. - /// - UINT32 IA32_XSS:1; - /// - /// [Bit 9] PKRU state. - /// - UINT32 PKRU:1; - UINT32 Reserved:22; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_STATE_MAIN_LEAF_EAX; - -/** - CPUID Extended State Information Sub Leaf - - @param EAX CPUID_EXTENDED_STATE (0x0D) - @param ECX CPUID_EXTENDED_STATE_SUB_LEAF (0x01) - - @retval EAX The format of the extended state sub-leaf is described by the - type CPUID_EXTENDED_STATE_SUB_LEAF_EAX. - @retval EBX The size in bytes of the XSAVE area containing all states - enabled by XCRO | IA32_XSS. - @retval ECX The format of the extended state sub-leaf is described by the - type CPUID_EXTENDED_STATE_SUB_LEAF_ECX. - @retval EDX Reports the supported bits of the upper 32 bits of the - IA32_XSS MSR. IA32_XSS[n+32] can be set to 1 only if EDX[n] is 1. - - Example usage - @code - CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax; - UINT32 Ebx; - CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; - UINT32 Edx; - - AsmCpuidEx ( - CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, - &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx - ); - @endcode -**/ -#define CPUID_EXTENDED_STATE_SUB_LEAF 0x01 - -/** - CPUID Extended State Information EAX for CPUID leaf #CPUID_EXTENDED_STATE, - sub-leaf #CPUID_EXTENDED_STATE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] XSAVEOPT is available. - /// - UINT32 XSAVEOPT:1; - /// - /// [Bit 1] Supports XSAVEC and the compacted form of XRSTOR if set. - /// - UINT32 XSAVEC:1; - /// - /// [Bit 2] Supports XGETBV with ECX = 1 if set. - /// - UINT32 XGETBV:1; - /// - /// [Bit 3] Supports XSAVES/XRSTORS and IA32_XSS if set. - /// - UINT32 XSAVES:1; - UINT32 Reserved:28; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_STATE_SUB_LEAF_EAX; - -/** - CPUID Extended State Information ECX for CPUID leaf #CPUID_EXTENDED_STATE, - sub-leaf #CPUID_EXTENDED_STATE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Used for XCR0. - /// - UINT32 XCR0:1; - /// - /// [Bit 8] PT STate. - /// - UINT32 PT:1; - /// - /// [Bit 9] Used for XCR0. - /// - UINT32 XCR0_1:1; - UINT32 Reserved:22; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_STATE_SUB_LEAF_ECX; - -/** - CPUID Extended State Information Size and Offset Sub Leaf - - @note - Leaf 0DH output depends on the initial value in ECX. - Each sub-leaf index (starting at position 2) is supported if it corresponds to - a supported bit in either the XCR0 register or the IA32_XSS MSR. - If ECX contains an invalid sub-leaf index, EAX/EBX/ECX/EDX return 0. Sub-leaf - n (0 <= n <= 31) is invalid if sub-leaf 0 returns 0 in EAX[n] and sub-leaf 1 - returns 0 in ECX[n]. Sub-leaf n (32 <= n <= 63) is invalid if sub-leaf 0 - returns 0 in EDX[n-32] and sub-leaf 1 returns 0 in EDX[n-32]. - - @param EAX CPUID_EXTENDED_STATE (0x0D) - @param ECX CPUID_EXTENDED_STATE_SIZE_OFFSET (0x02). Sub leafs 2..n based - on supported bits in XCR0 or IA32_XSS_MSR. - - @retval EAX The size in bytes (from the offset specified in EBX) of the save - area for an extended state feature associated with a valid - sub-leaf index, n. - @retval EBX The offset in bytes of this extended state component's save area - from the beginning of the XSAVE/XRSTOR area. This field reports - 0 if the sub-leaf index, n, does not map to a valid bit in the - XCR0 register. - @retval ECX The format of the extended state components's save area as - described by the type CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX. - This field reports 0 if the sub-leaf index, n, is invalid. - @retval EDX This field reports 0 if the sub-leaf index, n, is invalid; - otherwise it is reserved. - - Example usage - @code - UINT32 Eax; - UINT32 Ebx; - CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx; - UINT32 Edx; - UINTN SubLeaf; - - for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) { - AsmCpuidEx ( - CPUID_EXTENDED_STATE, SubLeaf, - &Eax, &Ebx, &Ecx.Uint32, &Edx - ); - } - @endcode -**/ -#define CPUID_EXTENDED_STATE_SIZE_OFFSET 0x02 - -/** - CPUID Extended State Information ECX for CPUID leaf #CPUID_EXTENDED_STATE, - sub-leaf #CPUID_EXTENDED_STATE_SIZE_OFFSET. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Is set if the bit n (corresponding to the sub-leaf index) is - /// supported in the IA32_XSS MSR; it is clear if bit n is instead supported - /// in XCR0. - /// - UINT32 XSS:1; - /// - /// [Bit 1] is set if, when the compacted format of an XSAVE area is used, - /// this extended state component located on the next 64-byte boundary - /// following the preceding state component (otherwise, it is located - /// immediately following the preceding state component). - /// - UINT32 Compacted:1; - UINT32 Reserved:30; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX; - - -/** - CPUID Intel Resource Director Technology (Intel RDT) Monitoring Information - - @param EAX CPUID_INTEL_RDT_MONITORING (0x0F) - @param ECX CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF (0x00). - CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF (0x01). - -**/ -#define CPUID_INTEL_RDT_MONITORING 0x0F - -/** - CPUID Intel Resource Director Technology (Intel RDT) Monitoring Information - Enumeration Sub-leaf - - @param EAX CPUID_INTEL_RDT_MONITORING (0x0F) - @param ECX CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF (0x00) - - @retval EAX Reserved. - @retval EBX Maximum range (zero-based) of RMID within this physical - processor of all types. - @retval ECX Reserved. - @retval EDX L3 Cache Intel RDT Monitoring Information Enumeration described by - the type CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX. - - Example usage - @code - UINT32 Ebx; - CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF, - NULL, &Ebx, NULL, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF 0x00 - -/** - CPUID Intel RDT Monitoring Information EDX for CPUID leaf - #CPUID_INTEL_RDT_MONITORING, sub-leaf - #CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Supports L3 Cache Intel RDT Monitoring if 1. - /// - UINT32 L3CacheRDT_M:1; - UINT32 Reserved2:30; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX; - -/** - CPUID L3 Cache Intel RDT Monitoring Capability Enumeration Sub-leaf - - @param EAX CPUID_INTEL_RDT_MONITORING (0x0F) - @param ECX CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF (0x01) - - @retval EAX Reserved. - @retval EBX Conversion factor from reported IA32_QM_CTR value to occupancy metric (bytes). - @retval ECX Maximum range (zero-based) of RMID of this resource type. - @retval EDX L3 Cache Intel RDT Monitoring Capability information described by the - type CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX. - - Example usage - @code - UINT32 Ebx; - UINT32 Ecx; - CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF, - NULL, &Ebx, &Ecx, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF 0x01 - -/** - CPUID L3 Cache Intel RDT Monitoring Capability Information EDX for CPUID leaf - #CPUID_INTEL_RDT_MONITORING, sub-leaf - #CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Supports L3 occupancy monitoring if 1. - /// - UINT32 L3CacheOccupancyMonitoring:1; - /// - /// [Bit 1] Supports L3 Total Bandwidth monitoring if 1. - /// - UINT32 L3CacheTotalBandwidthMonitoring:1; - /// - /// [Bit 2] Supports L3 Local Bandwidth monitoring if 1. - /// - UINT32 L3CacheLocalBandwidthMonitoring:1; - UINT32 Reserved:29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX; - - -/** - CPUID Intel Resource Director Technology (Intel RDT) Allocation Information - - @param EAX CPUID_INTEL_RDT_ALLOCATION (0x10). - @param ECX CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF (0x00). - CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF (0x01). - CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF (0x02). -**/ -#define CPUID_INTEL_RDT_ALLOCATION 0x10 - -/** - Intel Resource Director Technology (Intel RDT) Allocation Enumeration Sub-leaf - - @param EAX CPUID_INTEL_RDT_ALLOCATION (0x10) - @param ECX CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF (0x00). - - @retval EAX Reserved. - @retval EBX L3 and L2 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX. - @retval ECX Reserved. - @retval EDX Reserved. - - Example usage - @code - CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX Ebx; - - AsmCpuidEx ( - CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF, - NULL, &Ebx.Uint32, NULL, NULL - ); - @endcode -**/ -#define CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF 0x00 - -/** - CPUID L3 and L2 Cache Allocation Support Information EBX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Supports L3 Cache Allocation Technology if 1. - /// - UINT32 L3CacheAllocation:1; - /// - /// [Bit 2] Supports L2 Cache Allocation Technology if 1. - /// - UINT32 L2CacheAllocation:1; - UINT32 Reserved2:29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX; - - -/** - L3 Cache Allocation Technology Enumeration Sub-leaf - - @param EAX CPUID_INTEL_RDT_ALLOCATION (0x10) - @param ECX CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF (0x01) - - @retval EAX RESID L3 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX. - @retval EBX Bit-granular map of isolation/contention of allocation units. - @retval ECX RESID L3 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX. - @retval EDX RESID L3 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX. - - Example usage - @code - CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX Eax; - UINT32 Ebx; - CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX Ecx; - CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF, - &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF 0x01 - -/** - CPUID L3 Cache Allocation Technology Information EAX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Length of the capacity bit mask for the corresponding ResID - /// using minus-one notation. - /// - UINT32 CapacityLength:5; - UINT32 Reserved:27; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX; - -/** - CPUID L3 Cache Allocation Technology Information ECX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Updates of COS should be infrequent if 1. - /// - UINT32 CosUpdatesInfrequent:1; - /// - /// [Bit 2] Code and Data Prioritization Technology supported if 1. - /// - UINT32 CodeDataPrioritization:1; - UINT32 Reserved2:29; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX; - -/** - CPUID L3 Cache Allocation Technology Information EDX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Highest COS number supported for this ResID. - /// - UINT32 HighestCosNumber:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX; - -/** - L2 Cache Allocation Technology Enumeration Sub-leaf - - @param EAX CPUID_INTEL_RDT_ALLOCATION (0x10) - @param ECX CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF (0x02) - - @retval EAX RESID L2 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX. - @retval EBX Bit-granular map of isolation/contention of allocation units. - @retval ECX Reserved. - @retval EDX RESID L2 Cache Allocation Technology information described by - the type CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX. - - Example usage - @code - CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX Eax; - UINT32 Ebx; - CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF, - &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF 0x02 - -/** - CPUID L2 Cache Allocation Technology Information EAX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] Length of the capacity bit mask for the corresponding ResID - /// using minus-one notation. - /// - UINT32 CapacityLength:5; - UINT32 Reserved:27; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX; - -/** - CPUID L2 Cache Allocation Technology Information EDX for CPUID leaf - #CPUID_INTEL_RDT_ALLOCATION, sub-leaf - #CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Highest COS number supported for this ResID. - /// - UINT32 HighestCosNumber:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX; - - -/** - Intel SGX resource capability and configuration. - See Section 37.7.2 "Intel(R) SGX Resource Enumeration Leaves". - - If CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, the processor also supports querying - CPUID with EAX=12H on Intel SGX resource capability and configuration. - - @param EAX CPUID_INTEL_SGX (0x12) - @param ECX CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF (0x00). - CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF (0x01). - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF (0x02). - Sub leafs 2..n based on the sub-leaf-type encoding (returned in EAX[3:0]) - until the sub-leaf type is invalid. - -**/ -#define CPUID_INTEL_SGX 0x12 - -/** - Sub-Leaf 0 Enumeration of Intel SGX Capabilities. - Enumerates Intel SGX capability, including enclave instruction opcode support. - - @param EAX CPUID_INTEL_SGX (0x12) - @param ECX CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF (0x00) - - @retval EAX The format of Sub-Leaf 0 Enumeration of Intel SGX Capabilities is - described by the type CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX. - @retval EBX MISCSELECT: Reports the bit vector of supported extended features - that can be written to the MISC region of the SSA. - @retval ECX Reserved. - @retval EDX The format of Sub-Leaf 0 Enumeration of Intel SGX Capabilities is - described by the type CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX. - - Example usage - @code - CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX Eax; - UINT32 Ebx; - CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF, - &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF 0x00 - -/** - Sub-Leaf 0 Enumeration of Intel SGX Capabilities EAX for CPUID leaf #CPUID_INTEL_SGX, - sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] If 1, indicates leaf functions of SGX1 instruction are supported. - /// - UINT32 SGX1:1; - /// - /// [Bit 1] If 1, indicates leaf functions of SGX2 instruction are supported. - /// - UINT32 SGX2:1; - UINT32 Reserved:30; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX; - -/** - Sub-Leaf 0 Enumeration of Intel SGX Capabilities EDX for CPUID leaf #CPUID_INTEL_SGX, - sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 7:0] The maximum supported enclave size is 2^(EDX[7:0]) bytes - /// when not in 64-bit mode. - /// - UINT32 MaxEnclaveSize_Not64:8; - /// - /// [Bit 15:8] The maximum supported enclave size is 2^(EDX[15:8]) bytes - /// when operating in 64-bit mode. - /// - UINT32 MaxEnclaveSize_64:8; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX; - - -/** - Sub-Leaf 1 Enumeration of Intel SGX Capabilities. - Enumerates Intel SGX capability of processor state configuration and enclave - configuration in the SECS structure. - - @param EAX CPUID_INTEL_SGX (0x12) - @param ECX CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF (0x01) - - @retval EAX Report the valid bits of SECS.ATTRIBUTES[31:0] that software can - set with ECREATE. SECS.ATTRIBUTES[n] can be set to 1 using ECREATE - only if EAX[n] is 1, where n < 32. - @retval EBX Report the valid bits of SECS.ATTRIBUTES[63:32] that software can - set with ECREATE. SECS.ATTRIBUTES[n+32] can be set to 1 using ECREATE - only if EBX[n] is 1, where n < 32. - @retval ECX Report the valid bits of SECS.ATTRIBUTES[95:64] that software can - set with ECREATE. SECS.ATTRIBUTES[n+64] can be set to 1 using ECREATE - only if ECX[n] is 1, where n < 32. - @retval EDX Report the valid bits of SECS.ATTRIBUTES[127:96] that software can - set with ECREATE. SECS.ATTRIBUTES[n+96] can be set to 1 using ECREATE - only if EDX[n] is 1, where n < 32. - - Example usage - @code - UINT32 Eax; - UINT32 Ebx; - UINT32 Ecx; - UINT32 Edx; - - AsmCpuidEx ( - CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF, - &Eax, &Ebx, &Ecx, &Edx - ); - @endcode -**/ -#define CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF 0x01 - - -/** - Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources. - Enumerates available EPC resources. - - @param EAX CPUID_INTEL_SGX (0x12) - @param ECX CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF (0x02) - - @retval EAX The format of Sub-Leaf Index 2 or Higher Enumeration of Intel SGX - Resources is described by the type - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX. - @retval EBX The format of Sub-Leaf Index 2 or Higher Enumeration of Intel SGX - Resources is described by the type - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX. - @retval EDX The format of Sub-Leaf Index 2 or Higher Enumeration of Intel SGX - Resources is described by the type - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX. - @retval EDX The format of Sub-Leaf Index 2 or Higher Enumeration of Intel SGX - Resources is described by the type - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX. - - Example usage - @code - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX Eax; - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX Ebx; - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX Ecx; - CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX Edx; - - AsmCpuidEx ( - CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF, - &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF 0x02 - -/** - Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources EAX for CPUID - leaf #CPUID_INTEL_SGX, sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 3:0] Sub-leaf-type encoding. - /// 0000b: This sub-leaf is invalid, EBX:EAX and EDX:ECX report 0. - /// 0001b: This sub-leaf provides information on the Enclave Page Cache (EPC) - /// in EBX:EAX and EDX:ECX. - /// All other encoding are reserved. - /// - UINT32 SubLeafType:4; - UINT32 Reserved:8; - /// - /// [Bit 31:12] If EAX[3:0] = 0001b, these are bits 31:12 of the physical address of - /// the base of the EPC section. - /// - UINT32 LowAddressOfEpcSection:20; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX; - -/** - Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources EBX for CPUID - leaf #CPUID_INTEL_SGX, sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 19:0] If EAX[3:0] = 0001b, these are bits 51:32 of the physical address of - /// the base of the EPC section. - /// - UINT32 HighAddressOfEpcSection:20; - UINT32 Reserved:12; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX; - -/** - Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources ECX for CPUID - leaf #CPUID_INTEL_SGX, sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 3:0] The EPC section encoding. - /// 0000b: Not valid. - /// 0001b: The EPC section is confidentiality, integrity and replay protected. - /// All other encoding are reserved. - /// - UINT32 EpcSection:4; - UINT32 Reserved:8; - /// - /// [Bit 31:12] If EAX[3:0] = 0001b, these are bits 31:12 of the size of the - /// corresponding EPC section within the Processor Reserved Memory. - /// - UINT32 LowSizeOfEpcSection:20; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX; - -/** - Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources EDX for CPUID - leaf #CPUID_INTEL_SGX, sub-leaf #CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 19:0] If EAX[3:0] = 0001b, these are bits 51:32 of the size of the - /// corresponding EPC section within the Processor Reserved Memory. - /// - UINT32 HighSizeOfEpcSection:20; - UINT32 Reserved:12; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX; - - -/** - CPUID Intel Processor Trace Information - - @param EAX CPUID_INTEL_PROCESSOR_TRACE (0x14) - @param ECX CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF (0x00). - CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF (0x01). - -**/ -#define CPUID_INTEL_PROCESSOR_TRACE 0x14 - -/** - CPUID Intel Processor Trace Information Main Leaf - - @param EAX CPUID_INTEL_PROCEDSSOR_TRACE (0x14) - @param ECX CPUID_INTEL_PROCEDSSOR_TRACE_MAIN_LEAF (0x00) - - @retval EAX Reports the maximum sub-leaf supported in leaf 14H. - @retval EBX Returns Intel processor trace information described by the - type CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX. - @retval ECX Returns Intel processor trace information described by the - type CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX. - @retval EDX Reserved. - - Example usage - @code - UINT32 Eax; - CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx; - CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; - - AsmCpuidEx ( - CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, - &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL - ); - @endcode -**/ -#define CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF 0x00 - -/** - CPUID Intel Processor Trace EBX for CPUID leaf #CPUID_INTEL_PROCESSOR_TRACE, - sub-leaf #CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] If 1, indicates that IA32_RTIT_CTL.CR3Filter can be set to 1, - /// and that IA32_RTIT_CR3_MATCH MSR can be accessed. - /// - UINT32 Cr3Filter:1; - /// - /// [Bit 1] If 1, indicates support of Configurable PSB and Cycle-Accurate - /// Mode. - /// - UINT32 ConfigurablePsb:1; - /// - /// [Bit 2] If 1, indicates support of IP Filtering, TraceStop filtering, - /// and preservation of Intel PT MSRs across warm reset. - /// - UINT32 IpTraceStopFiltering:1; - /// - /// [Bit 3] If 1, indicates support of MTC timing packet and suppression of - /// COFI-based packets. - /// - UINT32 Mtc:1; - /// - /// [Bit 4] If 1, indicates support of PTWRITE. Writes can set - /// IA32_RTIT_CTL[12] (PTWEn) and IA32_RTIT_CTL[5] (FUPonPTW), and PTWRITE - /// can generate packets. - /// - UINT32 PTWrite:1; - /// - /// [Bit 5] If 1, indicates support of Power Event Trace. Writes can set - /// IA32_RTIT_CTL[4] (PwrEvtEn), enabling Power Event Trace packet - /// generation. - /// - UINT32 PowerEventTrace:1; - UINT32 Reserved:26; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX; - -/** - CPUID Intel Processor Trace ECX for CPUID leaf #CPUID_INTEL_PROCESSOR_TRACE, - sub-leaf #CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] If 1, Tracing can be enabled with IA32_RTIT_CTL.ToPA = 1, hence - /// utilizing the ToPA output scheme; IA32_RTIT_OUTPUT_BASE and - /// IA32_RTIT_OUTPUT_MASK_PTRS MSRs can be accessed. - /// - UINT32 RTIT:1; - /// - /// [Bit 1] If 1, ToPA tables can hold any number of output entries, up to - /// the maximum allowed by the MaskOrTableOffset field of - /// IA32_RTIT_OUTPUT_MASK_PTRS. - /// - UINT32 ToPA:1; - /// - /// [Bit 2] If 1, indicates support of Single-Range Output scheme. - /// - UINT32 SingleRangeOutput:1; - /// - /// [Bit 3] If 1, indicates support of output to Trace Transport subsystem. - /// - UINT32 TraceTransportSubsystem:1; - UINT32 Reserved:27; - /// - /// [Bit 31] If 1, generated packets which contain IP payloads have LIP - /// values, which include the CS base component. - /// - UINT32 LIP:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX; - - -/** - CPUID Intel Processor Trace Information Sub-leaf - - @param EAX CPUID_INTEL_PROCEDSSOR_TRACE (0x14) - @param ECX CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF (0x01) - - @retval EAX Returns Intel processor trace information described by the - type CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX. - @retval EBX Returns Intel processor trace information described by the - type CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX. - @retval ECX Reserved. - @retval EDX Reserved. - - Example usage - @code - UINT32 MaximumSubLeaf; - UINT32 SubLeaf; - CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax; - CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx; - - AsmCpuidEx ( - CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, - &MaximumSubLeaf, NULL, NULL, NULL - ); - - for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) { - AsmCpuidEx ( - CPUID_INTEL_PROCESSOR_TRACE, SubLeaf, - &Eax.Uint32, &Ebx.Uint32, NULL, NULL - ); - } - @endcode -**/ -#define CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF 0x01 - -/** - CPUID Intel Processor Trace EAX for CPUID leaf #CPUID_INTEL_PROCESSOR_TRACE, - sub-leaf #CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Number of configurable Address Ranges for filtering. - /// - UINT32 ConfigurableAddressRanges:3; - UINT32 Reserved:13; - /// - /// [Bits 31:16] Bitmap of supported MTC period encodings - /// - UINT32 MtcPeriodEncodings:16; - - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX; - -/** - CPUID Intel Processor Trace EBX for CPUID leaf #CPUID_INTEL_PROCESSOR_TRACE, - sub-leaf #CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Bitmap of supported Cycle Threshold value encodings. - /// - UINT32 CycleThresholdEncodings:16; - /// - /// [Bits 31:16] Bitmap of supported Configurable PSB frequency encodings. - /// - UINT32 PsbFrequencyEncodings:16; - - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX; - - -/** - CPUID Time Stamp Counter and Nominal Core Crystal Clock Information - - @note - If EBX[31:0] is 0, the TSC/"core crystal clock" ratio is not enumerated. - EBX[31:0]/EAX[31:0] indicates the ratio of the TSC frequency and the core - crystal clock frequency. - If ECX is 0, the nominal core crystal clock frequency is not enumerated. - "TSC frequency" = "core crystal clock frequency" * EBX/EAX. - The core crystal clock may differ from the reference clock, bus clock, or core - clock frequencies. - - @param EAX CPUID_TIME_STAMP_COUNTER (0x15) - - @retval EAX An unsigned integer which is the denominator of the - TSC/"core crystal clock" ratio - @retval EBX An unsigned integer which is the numerator of the - TSC/"core crystal clock" ratio. - @retval ECX An unsigned integer which is the nominal frequency - of the core crystal clock in Hz. - @retval EDX Reserved. - - Example usage - @code - UINT32 Eax; - UINT32 Ebx; - UINT32 Ecx; - - AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, &Ecx, NULL); - @endcode -**/ -#define CPUID_TIME_STAMP_COUNTER 0x15 - - -/** - CPUID Processor Frequency Information - - @note - Data is returned from this interface in accordance with the processor's - specification and does not reflect actual values. Suitable use of this data - includes the display of processor information in like manner to the processor - brand string and for determining the appropriate range to use when displaying - processor information e.g. frequency history graphs. The returned information - should not be used for any other purpose as the returned information does not - accurately correlate to information / counters returned by other processor - interfaces. While a processor may support the Processor Frequency Information - leaf, fields that return a value of zero are not supported. - - @param EAX CPUID_TIME_STAMP_COUNTER (0x16) - - @retval EAX Returns processor base frequency information described by the - type CPUID_PROCESSOR_FREQUENCY_EAX. - @retval EBX Returns maximum frequency information described by the type - CPUID_PROCESSOR_FREQUENCY_EBX. - @retval ECX Returns bus frequency information described by the type - CPUID_PROCESSOR_FREQUENCY_ECX. - @retval EDX Reserved. - - Example usage - @code - CPUID_PROCESSOR_FREQUENCY_EAX Eax; - CPUID_PROCESSOR_FREQUENCY_EBX Ebx; - CPUID_PROCESSOR_FREQUENCY_ECX Ecx; - - AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); - @endcode -**/ -#define CPUID_PROCESSOR_FREQUENCY 0x16 - -/** - CPUID Processor Frequency Information EAX for CPUID leaf - #CPUID_PROCESSOR_FREQUENCY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Processor Base Frequency (in MHz). - /// - UINT32 ProcessorBaseFrequency:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_PROCESSOR_FREQUENCY_EAX; - -/** - CPUID Processor Frequency Information EBX for CPUID leaf - #CPUID_PROCESSOR_FREQUENCY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Maximum Frequency (in MHz). - /// - UINT32 MaximumFrequency:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_PROCESSOR_FREQUENCY_EBX; - -/** - CPUID Processor Frequency Information ECX for CPUID leaf - #CPUID_PROCESSOR_FREQUENCY. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Bus (Reference) Frequency (in MHz). - /// - UINT32 BusFrequency:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_PROCESSOR_FREQUENCY_ECX; - - -/** - CPUID SoC Vendor Information - - @param EAX CPUID_SOC_VENDOR (0x17) - @param ECX CPUID_SOC_VENDOR_MAIN_LEAF (0x00) - CPUID_SOC_VENDOR_BRAND_STRING1 (0x01) - CPUID_SOC_VENDOR_BRAND_STRING1 (0x02) - CPUID_SOC_VENDOR_BRAND_STRING1 (0x03) - - @note - Leaf 17H output depends on the initial value in ECX. SOC Vendor Brand String - is a UTF-8 encoded string padded with trailing bytes of 00H. The complete SOC - Vendor Brand String is constructed by concatenating in ascending order of - EAX:EBX:ECX:EDX and from the sub-leaf 1 fragment towards sub-leaf 3. - -**/ -#define CPUID_SOC_VENDOR 0x17 - -/** - CPUID SoC Vendor Information - - @param EAX CPUID_SOC_VENDOR (0x17) - @param ECX CPUID_SOC_VENDOR_MAIN_LEAF (0x00) - - @retval EAX MaxSOCID_Index. Reports the maximum input value of supported - sub-leaf in leaf 17H. - @retval EBX Returns SoC Vendor information described by the type - CPUID_SOC_VENDOR_MAIN_LEAF_EBX. - @retval ECX Project ID. A unique number an SOC vendor assigns to its SOC - projects. - @retval EDX Stepping ID. A unique number within an SOC project that an SOC - vendor assigns. - - Example usage - @code - UINT32 Eax; - CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx; - UINT32 Ecx; - UINT32 Edx; - - AsmCpuidEx ( - CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF, - &Eax, &Ebx.Uint32, &Ecx, &Edx - ); - @endcode -**/ -#define CPUID_SOC_VENDOR_MAIN_LEAF 0x00 - -/** - CPUID SoC Vendor Information EBX for CPUID leaf #CPUID_SOC_VENDOR sub-leaf - #CPUID_SOC_VENDOR_MAIN_LEAF. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] SOC Vendor ID. - /// - UINT32 SocVendorId:16; - /// - /// [Bit 16] If 1, the SOC Vendor ID field is assigned via an industry - /// standard enumeration scheme. Otherwise, the SOC Vendor ID field is - /// assigned by Intel. - /// - UINT32 IsVendorScheme:1; - UINT32 Reserved:15; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_SOC_VENDOR_MAIN_LEAF_EBX; - -/** - CPUID SoC Vendor Information - - @param EAX CPUID_SOC_VENDOR (0x17) - @param ECX CPUID_SOC_VENDOR_BRAND_STRING1 (0x01) - - @retval EAX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EBX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval ECX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EDX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - - Example usage - @code - CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; - - AsmCpuidEx ( - CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1, - &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_SOC_VENDOR_BRAND_STRING1 0x01 - -/** - CPUID SoC Vendor Brand String for CPUID leafs #CPUID_SOC_VENDOR_BRAND_STRING1, - #CPUID_SOC_VENDOR_BRAND_STRING2, and #CPUID_SOC_VENDOR_BRAND_STRING3. -**/ -typedef union { - /// - /// 4 UTF-8 characters of Soc Vendor Brand String - /// - CHAR8 BrandString[4]; - /// - /// All fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_SOC_VENDOR_BRAND_STRING_DATA; - -/** - CPUID SoC Vendor Information - - @param EAX CPUID_SOC_VENDOR (0x17) - @param ECX CPUID_SOC_VENDOR_BRAND_STRING2 (0x02) - - @retval EAX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EBX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval ECX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EDX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - - Example usage - @code - CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; - - AsmCpuidEx ( - CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2, - &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_SOC_VENDOR_BRAND_STRING2 0x02 - -/** - CPUID SoC Vendor Information - - @param EAX CPUID_SOC_VENDOR (0x17) - @param ECX CPUID_SOC_VENDOR_BRAND_STRING3 (0x03) - - @retval EAX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EBX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval ECX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - @retval EDX SOC Vendor Brand String. UTF-8 encoded string of type - CPUID_SOC_VENDOR_BRAND_STRING_DATA. - - Example usage - @code - CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; - CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; - - AsmCpuidEx ( - CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3, - &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 - ); - @endcode -**/ -#define CPUID_SOC_VENDOR_BRAND_STRING3 0x03 - - -/** - CPUID Extended Function - - @param EAX CPUID_EXTENDED_FUNCTION (0x80000000) - - @retval EAX Maximum Input Value for Extended Function CPUID Information. - @retval EBX Reserved. - @retval ECX Reserved. - @retval EDX Reserved. - - Example usage - @code - UINT32 Eax; - - AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL); - @endcode -**/ -#define CPUID_EXTENDED_FUNCTION 0x80000000 - - -/** - CPUID Extended Processor Signature and Feature Bits - - @param EAX CPUID_EXTENDED_CPU_SIG (0x80000001) - - @retval EAX CPUID_EXTENDED_CPU_SIG. - @retval EBX Reserved. - @retval ECX Extended Processor Signature and Feature Bits information - described by the type CPUID_EXTENDED_CPU_SIG_ECX. - @retval EDX Extended Processor Signature and Feature Bits information - described by the type CPUID_EXTENDED_CPU_SIG_EDX. - - Example usage - @code - UINT32 Eax; - CPUID_EXTENDED_CPU_SIG_ECX Ecx; - CPUID_EXTENDED_CPU_SIG_EDX Edx; - - AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_EXTENDED_CPU_SIG 0x80000001 - -/** - CPUID Extended Processor Signature and Feature Bits ECX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LAHF/SAHF available in 64-bit mode. - /// - UINT32 LAHF_SAHF:1; - UINT32 Reserved1:4; - /// - /// [Bit 5] LZCNT. - /// - UINT32 LZCNT:1; - UINT32 Reserved2:2; - /// - /// [Bit 8] PREFETCHW. - /// - UINT32 PREFETCHW:1; - UINT32 Reserved3:23; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_CPU_SIG_ECX; - -/** - CPUID Extended Processor Signature and Feature Bits EDX for CPUID leaf - #CPUID_EXTENDED_CPU_SIG. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:11; - /// - /// [Bit 11] SYSCALL/SYSRET available in 64-bit mode. - /// - UINT32 SYSCALL_SYSRET:1; - UINT32 Reserved2:8; - /// - /// [Bit 20] Execute Disable Bit available. - /// - UINT32 NX:1; - UINT32 Reserved3:5; - /// - /// [Bit 26] 1-GByte pages are available if 1. - /// - UINT32 Page1GB:1; - /// - /// [Bit 27] RDTSCP and IA32_TSC_AUX are available if 1. - /// - UINT32 RDTSCP:1; - UINT32 Reserved4:1; - /// - /// [Bit 29] Intel(R) 64 Architecture available if 1. - /// - UINT32 LM:1; - UINT32 Reserved5:2; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_CPU_SIG_EDX; - - -/** - CPUID Processor Brand String - - @param EAX CPUID_BRAND_STRING1 (0x80000002) - - @retval EAX Processor Brand String in type CPUID_BRAND_STRING_DATA. - @retval EBX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval ECX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval EDX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - - Example usage - @code - CPUID_BRAND_STRING_DATA Eax; - CPUID_BRAND_STRING_DATA Ebx; - CPUID_BRAND_STRING_DATA Ecx; - CPUID_BRAND_STRING_DATA Edx; - - AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_BRAND_STRING1 0x80000002 - -/** - CPUID Processor Brand String for CPUID leafs #CPUID_BRAND_STRING1, - #CPUID_BRAND_STRING2, and #CPUID_BRAND_STRING3. -**/ -typedef union { - /// - /// 4 ASCII characters of Processor Brand String - /// - CHAR8 BrandString[4]; - /// - /// All fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_BRAND_STRING_DATA; - -/** - CPUID Processor Brand String - - @param EAX CPUID_BRAND_STRING2 (0x80000003) - - @retval EAX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval EBX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval ECX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval EDX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - - Example usage - @code - CPUID_BRAND_STRING_DATA Eax; - CPUID_BRAND_STRING_DATA Ebx; - CPUID_BRAND_STRING_DATA Ecx; - CPUID_BRAND_STRING_DATA Edx; - - AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_BRAND_STRING2 0x80000003 - -/** - CPUID Processor Brand String - - @param EAX CPUID_BRAND_STRING3 (0x80000004) - - @retval EAX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval EBX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval ECX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - @retval EDX Processor Brand String Continued in type CPUID_BRAND_STRING_DATA. - - Example usage - @code - CPUID_BRAND_STRING_DATA Eax; - CPUID_BRAND_STRING_DATA Ebx; - CPUID_BRAND_STRING_DATA Ecx; - CPUID_BRAND_STRING_DATA Edx; - - AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); - @endcode -**/ -#define CPUID_BRAND_STRING3 0x80000004 - - -/** - CPUID Extended Cache information - - @param EAX CPUID_EXTENDED_CACHE_INFO (0x80000006) - - @retval EAX Reserved. - @retval EBX Reserved. - @retval ECX Extended cache information described by the type - CPUID_EXTENDED_CACHE_INFO_ECX. - @retval EDX Reserved. - - Example usage - @code - CPUID_EXTENDED_CACHE_INFO_ECX Ecx; - - AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL); - @endcode -**/ -#define CPUID_EXTENDED_CACHE_INFO 0x80000006 - -/** - CPUID Extended Cache information ECX for CPUID leaf #CPUID_EXTENDED_CACHE_INFO. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Cache line size in bytes. - /// - UINT32 CacheLineSize:8; - UINT32 Reserved:4; - /// - /// [Bits 15:12] L2 Associativity field. Supported values are in the range - /// #CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_DISABLED to - /// #CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_FULL - /// - UINT32 L2Associativity:4; - /// - /// [Bits 31:16] Cache size in 1K units. - /// - UINT32 CacheSize:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_CACHE_INFO_ECX; - -/// -/// @{ Define value for bit field CPUID_EXTENDED_CACHE_INFO_ECX.L2Associativity -/// -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_DISABLED 0x00 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_DIRECT_MAPPED 0x01 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_2_WAY 0x02 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_4_WAY 0x04 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_8_WAY 0x06 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_16_WAY 0x08 -#define CPUID_EXTENDED_CACHE_INFO_ECX_L2_ASSOCIATIVITY_FULL 0x0F -/// -/// @} -/// - -/** - CPUID Extended Time Stamp Counter information - - @param EAX CPUID_EXTENDED_TIME_STAMP_COUNTER (0x80000007) - - @retval EAX Reserved. - @retval EBX Reserved. - @retval ECX Reserved. - @retval EDX Extended time stamp counter (TSC) information described by the - type CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX. - - Example usage - @code - CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx; - - AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32); - @endcode -**/ -#define CPUID_EXTENDED_TIME_STAMP_COUNTER 0x80000007 - -/** - CPUID Extended Time Stamp Counter information EDX for CPUID leaf - #CPUID_EXTENDED_TIME_STAMP_COUNTER. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bit 8] Invariant TSC available if 1. - /// - UINT32 InvariantTsc:1; - UINT32 Reserved2:23; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX; - - -/** - CPUID Linear Physical Address Size - - @param EAX CPUID_VIR_PHY_ADDRESS_SIZE (0x80000008) - - @retval EAX Linear/Physical Address Size described by the type - CPUID_VIR_PHY_ADDRESS_SIZE_EAX. - @retval EBX Reserved. - @retval ECX Reserved. - @retval EDX Reserved. - - Example usage - @code - CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax; - - AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL); - @endcode -**/ -#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008 - -/** - CPUID Linear Physical Address Size EAX for CPUID leaf - #CPUID_VIR_PHY_ADDRESS_SIZE. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Number of physical address bits. - /// - /// @note - /// If CPUID.80000008H:EAX[7:0] is supported, the maximum physical address - /// number supported should come from this field. - /// - UINT32 PhysicalAddressBits:8; - /// - /// [Bits 15:8] Number of linear address bits. - /// - UINT32 LinearAddressBits:8; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; -} CPUID_VIR_PHY_ADDRESS_SIZE_EAX; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/LocalApic.h b/CloverEFI/UefiCpuPkg/Include/Register/LocalApic.h deleted file mode 100644 index bb0e211dc..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/LocalApic.h +++ /dev/null @@ -1,214 +0,0 @@ -/** @file - IA32 Local APIC Definitions. - - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __LOCAL_APIC_H__ -#define __LOCAL_APIC_H__ - -// -// Definitions for IA32 architectural MSRs -// -#define MSR_IA32_APIC_BASE_ADDRESS 0x1B - -// -// Definitions for CPUID instruction -// -#define CPUID_VERSION_INFO 0x1 -#define CPUID_EXTENDED_FUNCTION 0x80000000 -#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008 - -// -// Definition for Local APIC registers and related values -// -#define XAPIC_ID_OFFSET 0x20 -#define XAPIC_VERSION_OFFSET 0x30 -#define XAPIC_EOI_OFFSET 0x0b0 -#define XAPIC_ICR_DFR_OFFSET 0x0e0 -#define XAPIC_SPURIOUS_VECTOR_OFFSET 0x0f0 -#define XAPIC_ICR_LOW_OFFSET 0x300 -#define XAPIC_ICR_HIGH_OFFSET 0x310 -#define XAPIC_LVT_TIMER_OFFSET 0x320 -#define XAPIC_LVT_LINT0_OFFSET 0x350 -#define XAPIC_LVT_LINT1_OFFSET 0x360 -#define XAPIC_TIMER_INIT_COUNT_OFFSET 0x380 -#define XAPIC_TIMER_CURRENT_COUNT_OFFSET 0x390 -#define XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET 0x3E0 - -#define X2APIC_MSR_BASE_ADDRESS 0x800 -#define X2APIC_MSR_ICR_ADDRESS 0x830 - -#define LOCAL_APIC_DELIVERY_MODE_FIXED 0 -#define LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY 1 -#define LOCAL_APIC_DELIVERY_MODE_SMI 2 -#define LOCAL_APIC_DELIVERY_MODE_NMI 4 -#define LOCAL_APIC_DELIVERY_MODE_INIT 5 -#define LOCAL_APIC_DELIVERY_MODE_STARTUP 6 -#define LOCAL_APIC_DELIVERY_MODE_EXTINT 7 - -#define LOCAL_APIC_DESTINATION_SHORTHAND_NO_SHORTHAND 0 -#define LOCAL_APIC_DESTINATION_SHORTHAND_SELF 1 -#define LOCAL_APIC_DESTINATION_SHORTHAND_ALL_INCLUDING_SELF 2 -#define LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF 3 - -typedef union { - struct { - UINT32 Reserved0:8; ///< Reserved. - UINT32 Bsp:1; ///< Processor is BSP. - UINT32 Reserved1:1; ///< Reserved. - UINT32 Extd:1; ///< Enable x2APIC mode. - UINT32 En:1; ///< xAPIC global enable/disable. - UINT32 ApicBaseLow:20; ///< APIC Base physical address. The actual field width depends on physical address width. - UINT32 ApicBaseHigh:32; - } Bits; - UINT64 Uint64; -} MSR_IA32_APIC_BASE; - -// -// Local APIC Version Register. -// -typedef union { - struct { - UINT32 Version:8; ///< The version numbers of the local APIC. - UINT32 Reserved0:8; ///< Reserved. - UINT32 MaxLvtEntry:8; ///< Number of LVT entries minus 1. - UINT32 EoiBroadcastSuppression:1; ///< 1 if EOI-broadcast suppression supported. - UINT32 Reserved1:7; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_VERSION; - -// -// Low half of Interrupt Command Register (ICR). -// -typedef union { - struct { - UINT32 Vector:8; ///< The vector number of the interrupt being sent. - UINT32 DeliveryMode:3; ///< Specifies the type of IPI to be sent. - UINT32 DestinationMode:1; ///< 0: physical destination mode, 1: logical destination mode. - UINT32 DeliveryStatus:1; ///< Indicates the IPI delivery status. This field is reserved in x2APIC mode. - UINT32 Reserved0:1; ///< Reserved. - UINT32 Level:1; ///< 0 for the INIT level de-assert delivery mode. Otherwise 1. - UINT32 TriggerMode:1; ///< 0: edge, 1: level when using the INIT level de-assert delivery mode. - UINT32 Reserved1:2; ///< Reserved. - UINT32 DestinationShorthand:2; ///< A shorthand notation to specify the destination of the interrupt. - UINT32 Reserved2:12; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_ICR_LOW; - -// -// High half of Interrupt Command Register (ICR) -// -typedef union { - struct { - UINT32 Reserved0:24; ///< Reserved. - UINT32 Destination:8; ///< Specifies the target processor or processors in xAPIC mode. - } Bits; - UINT32 Uint32; ///< Destination field expanded to 32-bit in x2APIC mode. -} LOCAL_APIC_ICR_HIGH; - -// -// Spurious-Interrupt Vector Register (SVR) -// -typedef union { - struct { - UINT32 SpuriousVector:8; ///< Spurious Vector. - UINT32 SoftwareEnable:1; ///< APIC Software Enable/Disable. - UINT32 FocusProcessorChecking:1; ///< Focus Processor Checking. - UINT32 Reserved0:2; ///< Reserved. - UINT32 EoiBroadcastSuppression:1; ///< EOI-Broadcast Suppression. - UINT32 Reserved1:19; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_SVR; - -// -// Divide Configuration Register (DCR) -// -typedef union { - struct { - UINT32 DivideValue1:2; ///< Low 2 bits of the divide value. - UINT32 Reserved0:1; ///< Always 0. - UINT32 DivideValue2:1; ///< Highest 1 bit of the divide value. - UINT32 Reserved1:28; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_DCR; - -// -// LVT Timer Register -// -typedef union { - struct { - UINT32 Vector:8; ///< The vector number of the interrupt being sent. - UINT32 Reserved0:4; ///< Reserved. - UINT32 DeliveryStatus:1; ///< 0: Idle, 1: send pending. - UINT32 Reserved1:3; ///< Reserved. - UINT32 Mask:1; ///< 0: Not masked, 1: Masked. - UINT32 TimerMode:1; ///< 0: One-shot, 1: Periodic. - UINT32 Reserved2:14; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_LVT_TIMER; - -// -// LVT LINT0/LINT1 Register -// -typedef union { - struct { - UINT32 Vector:8; ///< The vector number of the interrupt being sent. - UINT32 DeliveryMode:3; ///< Specifies the type of interrupt to be sent. - UINT32 Reserved0:1; ///< Reserved. - UINT32 DeliveryStatus:1; ///< 0: Idle, 1: send pending. - UINT32 InputPinPolarity:1; ///< Interrupt Input Pin Polarity. - UINT32 RemoteIrr:1; ///< RO. Set when the local APIC accepts the interrupt and reset when an EOI is received. - UINT32 TriggerMode:1; ///< 0:edge, 1:level. - UINT32 Mask:1; ///< 0: Not masked, 1: Masked. - UINT32 Reserved1:15; ///< Reserved. - } Bits; - UINT32 Uint32; -} LOCAL_APIC_LVT_LINT; - -// -// MSI Address Register -// -typedef union { - struct { - UINT32 Reserved0:2; ///< Reserved - UINT32 DestinationMode:1; ///< Specifies the Destination Mode. - UINT32 RedirectionHint:1; ///< Specifies the Redirection Hint. - UINT32 Reserved1:8; ///< Reserved. - UINT32 DestinationId:8; ///< Specifies the Destination ID. - UINT32 BaseAddress:12; ///< Must be 0FEEH - } Bits; - UINT32 Uint32; -} LOCAL_APIC_MSI_ADDRESS; - -// -// MSI Address Register -// -typedef union { - struct { - UINT32 Vector:8; ///< Interrupt vector in range 010h..0FEH - UINT32 DeliveryMode:3; ///< Specifies the type of interrupt to be sent. - UINT32 Reserved0:3; ///< Reserved. - UINT32 Level:1; ///< 0:Deassert, 1:Assert. Ignored for Edge triggered interrupts. - UINT32 TriggerMode:1; ///< 0:Edge, 1:Level. - UINT32 Reserved1:16; ///< Reserved. - UINT32 Reserved2:32; ///< Reserved. - } Bits; - UINT64 Uint64; -} LOCAL_APIC_MSI_DATA; - -#endif - diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Microcode.h b/CloverEFI/UefiCpuPkg/Include/Register/Microcode.h deleted file mode 100644 index 94529a1ca..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Microcode.h +++ /dev/null @@ -1,200 +0,0 @@ -/** @file - Microcode Definitions. - - Microcode Definitions based on contents of the - Intel(R) 64 and IA-32 Architectures Software Developer's Manual - Volume 3A, Section 9.11 Microcode Definitions - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, - June 2016, Chapter 9 Processor Management and Initialization, Section 9-11. - -**/ - -#ifndef __MICROCODE_H__ -#define __MICROCODE_H__ - -/// -/// CPU Microcode Date in BCD format -/// -typedef union { - struct { - UINT32 Year:16; - UINT32 Day:8; - UINT32 Month:8; - } Bits; - UINT32 Uint32; -} CPU_MICROCODE_DATE; - -/// -/// CPU Microcode Processor Signature format -/// -typedef union { - struct { - UINT32 Stepping:4; - UINT32 Model:4; - UINT32 Family:4; - UINT32 Type:2; - UINT32 Reserved1:2; - UINT32 ExtendedModel:4; - UINT32 ExtendedFamily:8; - UINT32 Reserved2:4; - } Bits; - UINT32 Uint32; -} CPU_MICROCODE_PROCESSOR_SIGNATURE; - -#pragma pack (1) - -/// -/// Microcode Update Format definition -/// -typedef struct { - /// - /// Version number of the update header - /// - UINT32 HeaderVersion; - /// - /// Unique version number for the update, the basis for the update - /// signature provided by the processor to indicate the current update - /// functioning within the processor. Used by the BIOS to authenticate - /// the update and verify that the processor loads successfully. The - /// value in this field cannot be used for processor stepping identification - /// alone. This is a signed 32-bit number. - /// - UINT32 UpdateRevision; - /// - /// Date of the update creation in binary format: mmddyyyy (e.g. - /// 07/18/98 is 07181998H). - /// - CPU_MICROCODE_DATE Date; - /// - /// Extended family, extended model, type, family, model, and stepping - /// of processor that requires this particular update revision (e.g., - /// 00000650H). Each microcode update is designed specifically for a - /// given extended family, extended model, type, family, model, and - /// stepping of the processor. - /// The BIOS uses the processor signature field in conjunction with the - /// CPUID instruction to determine whether or not an update is - /// appropriate to load on a processor. The information encoded within - /// this field exactly corresponds to the bit representations returned by - /// the CPUID instruction. - /// - CPU_MICROCODE_PROCESSOR_SIGNATURE ProcessorSignature; - /// - /// Checksum of Update Data and Header. Used to verify the integrity of - /// the update header and data. Checksum is correct when the - /// summation of all the DWORDs (including the extended Processor - /// Signature Table) that comprise the microcode update result in - /// 00000000H. - /// - UINT32 Checksum; - /// - /// Version number of the loader program needed to correctly load this - /// update. The initial version is 00000001H - /// - UINT32 LoaderRevision; - /// - /// Platform type information is encoded in the lower 8 bits of this 4- - /// byte field. Each bit represents a particular platform type for a given - /// CPUID. The BIOS uses the processor flags field in conjunction with - /// the platform Id bits in MSR (17H) to determine whether or not an - /// update is appropriate to load on a processor. Multiple bits may be set - /// representing support for multiple platform IDs. - /// - UINT32 ProcessorFlags; - /// - /// Specifies the size of the encrypted data in bytes, and must be a - /// multiple of DWORDs. If this value is 00000000H, then the microcode - /// update encrypted data is 2000 bytes (or 500 DWORDs). - /// - UINT32 DataSize; - /// - /// Specifies the total size of the microcode update in bytes. It is the - /// summation of the header size, the encrypted data size and the size of - /// the optional extended signature table. This value is always a multiple - /// of 1024. - /// - UINT32 TotalSize; - /// - /// Reserved fields for future expansion. - /// - UINT8 Reserved[12]; -} CPU_MICROCODE_HEADER; - -/// -/// Extended Signature Table Header Field Definitions -/// -typedef struct { - /// - /// Specifies the number of extended signature structures (Processor - /// Signature[n], processor flags[n] and checksum[n]) that exist in this - /// microcode update - /// - UINT32 ExtendedSignatureCount; - /// - /// Checksum of update extended processor signature table. Used to - /// verify the integrity of the extended processor signature table. - /// Checksum is correct when the summation of the DWORDs that - /// comprise the extended processor signature table results in - /// 00000000H. - /// - UINT32 ExtendedChecksum; - /// - /// Reserved fields. - /// - UINT8 Reserved[12]; -} CPU_MICROCODE_EXTENDED_TABLE_HEADER; - -/// -/// Extended Signature Table Field Definitions -/// -typedef struct { - /// - /// Extended family, extended model, type, family, model, and stepping - /// of processor that requires this particular update revision (e.g., - /// 00000650H). Each microcode update is designed specifically for a - /// given extended family, extended model, type, family, model, and - /// stepping of the processor. - /// The BIOS uses the processor signature field in conjunction with the - /// CPUID instruction to determine whether or not an update is - /// appropriate to load on a processor. The information encoded within - /// this field exactly corresponds to the bit representations returned by - /// the CPUID instruction. - /// - CPU_MICROCODE_PROCESSOR_SIGNATURE ProcessorSignature; - /// - /// Platform type information is encoded in the lower 8 bits of this 4- - /// byte field. Each bit represents a particular platform type for a given - /// CPUID. The BIOS uses the processor flags field in conjunction with - /// the platform Id bits in MSR (17H) to determine whether or not an - /// update is appropriate to load on a processor. Multiple bits may be set - /// representing support for multiple platform IDs. - /// - UINT32 ProcessorFlag; - /// - /// Used by utility software to decompose a microcode update into - /// multiple microcode updates where each of the new updates is - /// constructed without the optional Extended Processor Signature - /// Table. - /// To calculate the Checksum, substitute the Primary Processor - /// Signature entry and the Processor Flags entry with the - /// corresponding Extended Patch entry. Delete the Extended Processor - /// Signature Table entries. The Checksum is correct when the - /// summation of all DWORDs that comprise the created Extended - /// Processor Patch results in 00000000H. - /// - UINT32 Checksum; -} CPU_MICROCODE_EXTENDED_TABLE; - -#pragma pack () - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr.h deleted file mode 100644 index 0ac8d5bdf..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr.h +++ /dev/null @@ -1,49 +0,0 @@ -/** @file - MSR Definitions. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Chapter 35. - -**/ - -#ifndef __MSR_H__ -#define __MSR_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/AtomMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/AtomMsr.h deleted file mode 100644 index b2764690f..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/AtomMsr.h +++ /dev/null @@ -1,790 +0,0 @@ -/** @file - MSR Definitions for the Intel(R) Atom(TM) Processor Family. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.3. - -**/ - -#ifndef __ATOM_MSR_H__ -#define __ATOM_MSR_H__ - -#include - -/** - Is Intel(R) Atom(TM) Processor Family? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_ATOM_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x1C || \ - DisplayModel == 0x26 || \ - DisplayModel == 0x27 || \ - DisplayModel == 0x35 || \ - DisplayModel == 0x36 \ - ) \ - ) - -/** - Shared. Model Specific Platform ID (R). - - @param ECX MSR_ATOM_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_ATOM_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PLATFORM_ID); - @endcode - @note MSR_ATOM_PLATFORM_ID is defined as MSR_PLATFORM_ID in SDM. -**/ -#define MSR_ATOM_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_ATOM_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 12:8] Maximum Qualified Ratio (R) The maximum allowed bus ratio. - /// - UINT32 MaximumQualifiedRatio:5; - UINT32 Reserved2:19; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_PLATFORM_ID_REGISTER; - - -/** - Shared. Processor Hard Power-On Configuration (R/W) Enables and disables - processor features; (R) indicates current processor configuration. - - @param ECX MSR_ATOM_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_ATOM_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_ATOM_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_ATOM_EBL_CR_POWERON is defined as MSR_EBL_CR_POWERON in SDM. -**/ -#define MSR_ATOM_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_ATOM_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Data Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Always 0. - /// - UINT32 DataErrorCheckingEnable:1; - /// - /// [Bit 2] Response Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Always 0. - /// - UINT32 ResponseErrorCheckingEnable:1; - /// - /// [Bit 3] AERR# Drive Enable (R/W) 1 = Enabled; 0 = Disabled Always 0. - /// - UINT32 AERR_DriveEnable:1; - /// - /// [Bit 4] BERR# Enable for initiator bus requests (R/W) 1 = Enabled; 0 = - /// Disabled Always 0. - /// - UINT32 BERR_Enable:1; - UINT32 Reserved2:1; - UINT32 Reserved3:1; - /// - /// [Bit 7] BINIT# Driver Enable (R/W) 1 = Enabled; 0 = Disabled Always 0. - /// - UINT32 BINIT_DriverEnable:1; - UINT32 Reserved4:1; - /// - /// [Bit 9] Execute BIST (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 10] AERR# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled - /// Always 0. - /// - UINT32 AERR_ObservationEnabled:1; - UINT32 Reserved5:1; - /// - /// [Bit 12] BINIT# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled - /// Always 0. - /// - UINT32 BINIT_ObservationEnabled:1; - UINT32 Reserved6:1; - /// - /// [Bit 14] 1 MByte Power on Reset Vector (R/O) 1 = 1 MByte; 0 = 4 GBytes. - /// - UINT32 ResetVector:1; - UINT32 Reserved7:1; - /// - /// [Bits 17:16] APIC Cluster ID (R/O) Always 00B. - /// - UINT32 APICClusterID:2; - UINT32 Reserved8:2; - /// - /// [Bits 21:20] Symmetric Arbitration ID (R/O) Always 00B. - /// - UINT32 SymmetricArbitrationID:2; - /// - /// [Bits 26:22] Integer Bus Frequency Ratio (R/O). - /// - UINT32 IntegerBusFrequencyRatio:5; - UINT32 Reserved9:5; - UINT32 Reserved10:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_EBL_CR_POWERON_REGISTER; - - -/** - Unique. Last Branch Record n From IP (R/W) One of eight pairs of last branch - record registers on the last branch record stack. The From_IP part of the - stack contains pointers to the source instruction . See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.5. - - @param ECX MSR_ATOM_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_ATOM_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_ATOM_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - @{ -**/ -#define MSR_ATOM_LASTBRANCH_0_FROM_IP 0x00000040 -#define MSR_ATOM_LASTBRANCH_1_FROM_IP 0x00000041 -#define MSR_ATOM_LASTBRANCH_2_FROM_IP 0x00000042 -#define MSR_ATOM_LASTBRANCH_3_FROM_IP 0x00000043 -#define MSR_ATOM_LASTBRANCH_4_FROM_IP 0x00000044 -#define MSR_ATOM_LASTBRANCH_5_FROM_IP 0x00000045 -#define MSR_ATOM_LASTBRANCH_6_FROM_IP 0x00000046 -#define MSR_ATOM_LASTBRANCH_7_FROM_IP 0x00000047 -/// @} - - -/** - Unique. Last Branch Record n To IP (R/W) One of eight pairs of last branch - record registers on the last branch record stack. The To_IP part of the - stack contains pointers to the destination instruction. - - @param ECX MSR_ATOM_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_ATOM_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_ATOM_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - @{ -**/ -#define MSR_ATOM_LASTBRANCH_0_TO_IP 0x00000060 -#define MSR_ATOM_LASTBRANCH_1_TO_IP 0x00000061 -#define MSR_ATOM_LASTBRANCH_2_TO_IP 0x00000062 -#define MSR_ATOM_LASTBRANCH_3_TO_IP 0x00000063 -#define MSR_ATOM_LASTBRANCH_4_TO_IP 0x00000064 -#define MSR_ATOM_LASTBRANCH_5_TO_IP 0x00000065 -#define MSR_ATOM_LASTBRANCH_6_TO_IP 0x00000066 -#define MSR_ATOM_LASTBRANCH_7_TO_IP 0x00000067 -/// @} - - -/** - Shared. Scalable Bus Speed(RO) This field indicates the intended scalable - bus clock speed for processors based on Intel Atom microarchitecture:. - - @param ECX MSR_ATOM_FSB_FREQ (0x000000CD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_FSB_FREQ_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_FSB_FREQ_REGISTER. - - Example usage - @code - MSR_ATOM_FSB_FREQ_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_FSB_FREQ); - @endcode - @note MSR_ATOM_FSB_FREQ is defined as MSR_FSB_FREQ in SDM. -**/ -#define MSR_ATOM_FSB_FREQ 0x000000CD - -/** - MSR information returned for MSR index #MSR_ATOM_FSB_FREQ -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] - Scalable Bus Speed - /// - /// Atom Processor Family - /// --------------------- - /// 111B: 083 MHz (FSB 333) - /// 101B: 100 MHz (FSB 400) - /// 001B: 133 MHz (FSB 533) - /// 011B: 167 MHz (FSB 667) - /// - /// 133.33 MHz should be utilized if performing calculation with - /// System Bus Speed when encoding is 001B. - /// 166.67 MHz should be utilized if performing calculation with - /// System Bus Speed when - /// encoding is 011B. - /// - UINT32 ScalableBusSpeed:3; - UINT32 Reserved1:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_FSB_FREQ_REGISTER; - - -/** - Shared. - - @param ECX MSR_ATOM_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_ATOM_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_ATOM_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_ATOM_BBL_CR_CTL3 is defined as MSR_BBL_CR_CTL3 in SDM. -**/ -#define MSR_ATOM_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_ATOM_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Hardware Enabled (RO) 1 = If the L2 is hardware-enabled 0 = - /// Indicates if the L2 is hardware-disabled. - /// - UINT32 L2HardwareEnabled:1; - UINT32 Reserved1:7; - /// - /// [Bit 8] L2 Enabled. (R/W) 1 = L2 cache has been initialized 0 = - /// Disabled (default) Until this bit is set the processor will not - /// respond to the WBINVD instruction or the assertion of the FLUSH# input. - /// - UINT32 L2Enabled:1; - UINT32 Reserved2:14; - /// - /// [Bit 23] L2 Not Present (RO) 1. = L2 Present 2. = L2 Not Present. - /// - UINT32 L2NotPresent:1; - UINT32 Reserved3:8; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_BBL_CR_CTL3_REGISTER; - - -/** - Shared. - - @param ECX MSR_ATOM_PERF_STATUS (0x00000198) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_PERF_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_PERF_STATUS_REGISTER. - - Example usage - @code - MSR_ATOM_PERF_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PERF_STATUS); - AsmWriteMsr64 (MSR_ATOM_PERF_STATUS, Msr.Uint64); - @endcode - @note MSR_ATOM_PERF_STATUS is defined as MSR_PERF_STATUS in SDM. -**/ -#define MSR_ATOM_PERF_STATUS 0x00000198 - -/** - MSR information returned for MSR index #MSR_ATOM_PERF_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Current Performance State Value. - /// - UINT32 CurrentPerformanceStateValue:16; - UINT32 Reserved1:16; - UINT32 Reserved2:8; - /// - /// [Bits 44:40] Maximum Bus Ratio (R/O) Indicates maximum bus ratio - /// configured for the processor. - /// - UINT32 MaximumBusRatio:5; - UINT32 Reserved3:19; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_PERF_STATUS_REGISTER; - - -/** - Shared. - - @param ECX MSR_ATOM_THERM2_CTL (0x0000019D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_THERM2_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_THERM2_CTL_REGISTER. - - Example usage - @code - MSR_ATOM_THERM2_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_THERM2_CTL); - AsmWriteMsr64 (MSR_ATOM_THERM2_CTL, Msr.Uint64); - @endcode - @note MSR_ATOM_THERM2_CTL is defined as MSR_THERM2_CTL in SDM. -**/ -#define MSR_ATOM_THERM2_CTL 0x0000019D - -/** - MSR information returned for MSR index #MSR_ATOM_THERM2_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bit 16] TM_SELECT (R/W) Mode of automatic thermal monitor: 1. = - /// Thermal Monitor 1 (thermally-initiated on-die modulation of the - /// stop-clock duty cycle) 2. = Thermal Monitor 2 (thermally-initiated - /// frequency transitions) If bit 3 of the IA32_MISC_ENABLE register is - /// cleared, TM_SELECT has no effect. Neither TM1 nor TM2 are enabled. - /// - UINT32 TM_SELECT:1; - UINT32 Reserved2:15; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_THERM2_CTL_REGISTER; - - -/** - Unique. Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_ATOM_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_ATOM_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_ATOM_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_ATOM_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_ATOM_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_ATOM_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Unique. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. Default value is 0. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Shared. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:1; - UINT32 Reserved4:1; - /// - /// [Bit 10] Shared. FERR# Multiplexing Enable (R/W) 1 = FERR# asserted by - /// the processor to indicate a pending break event within the processor 0 - /// = Indicates compatible FERR# signaling behavior This bit must be set - /// to 1 to support XAPIC interrupt model usage. - /// - UINT32 FERR:1; - /// - /// [Bit 11] Shared. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Shared. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - /// - /// [Bit 13] Shared. TM2 Enable (R/W) When this bit is set (1) and the - /// thermal sensor indicates that the die temperature is at the - /// pre-determined threshold, the Thermal Monitor 2 mechanism is engaged. - /// TM2 will reduce the bus to core ratio and voltage according to the - /// value last written to MSR_THERM2_CTL bits 15:0. - /// When this bit is clear (0, default), the processor does not change - /// the VID signals or the bus to core ratio when the processor enters a - /// thermally managed state. The BIOS must enable this feature if the - /// TM2 feature flag (CPUID.1:ECX[8]) is set; if the TM2 feature flag is - /// not set, this feature is not supported and BIOS must not alter the - /// contents of the TM2 bit location. The processor is operating out of - /// specification if both this bit and the TM1 bit are set to 0. - /// - UINT32 TM2:1; - UINT32 Reserved5:2; - /// - /// [Bit 16] Shared. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved6:1; - /// - /// [Bit 18] Shared. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved7:1; - /// - /// [Bit 20] Shared. Enhanced Intel SpeedStep Technology Select Lock - /// (R/WO) When set, this bit causes the following bits to become - /// read-only: - Enhanced Intel SpeedStep Technology Select Lock (this - /// bit), - Enhanced Intel SpeedStep Technology Enable bit. The bit must - /// be set before an Enhanced Intel SpeedStep Technology transition is - /// requested. This bit is cleared on reset. - /// - UINT32 EISTLock:1; - UINT32 Reserved8:1; - /// - /// [Bit 22] Unique. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Shared. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved9:8; - UINT32 Reserved10:2; - /// - /// [Bit 34] Unique. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved11:29; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_IA32_MISC_ENABLE_REGISTER; - - -/** - Unique. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-2) - that points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP (at 40H). - - @param ECX MSR_ATOM_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_ATOM_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_ATOM_LASTBRANCH_TOS 0x000001C9 - - -/** - Unique. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_ATOM_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_LER_FROM_LIP); - @endcode - @note MSR_ATOM_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_ATOM_LER_FROM_LIP 0x000001DD - - -/** - Unique. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_ATOM_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_LER_TO_LIP); - @endcode - @note MSR_ATOM_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_ATOM_LER_TO_LIP 0x000001DE - - -/** - Unique. See Table 35-2. See Section 18.4.4, "Processor Event Based Sampling - (PEBS).". - - @param ECX MSR_ATOM_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_ATOM_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_ATOM_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_ATOM_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PEBS_ENABLE); - AsmWriteMsr64 (MSR_ATOM_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_ATOM_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_ATOM_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_ATOM_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. (R/W). - /// - UINT32 Enable:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_ATOM_PEBS_ENABLE_REGISTER; - - -/** - Package. Package C2 Residency Note: C-state values are processor specific - C-state code names, unrelated to MWAIT extension C-state parameters or ACPI - C-States. Package. Package C2 Residency Counter. (R/O) Time that this - package is in processor-specific C2 states since last reset. Counts at 1 Mhz - frequency. - - @param ECX MSR_ATOM_PKG_C2_RESIDENCY (0x000003F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_PKG_C2_RESIDENCY); - AsmWriteMsr64 (MSR_ATOM_PKG_C2_RESIDENCY, Msr); - @endcode - @note MSR_ATOM_PKG_C2_RESIDENCY is defined as MSR_PKG_C2_RESIDENCY in SDM. -**/ -#define MSR_ATOM_PKG_C2_RESIDENCY 0x000003F8 - - -/** - Package. Package C4 Residency Note: C-state values are processor specific - C-state code names, unrelated to MWAIT extension C-state parameters or ACPI - C-States. Package. Package C4 Residency Counter. (R/O) Time that this - package is in processor-specific C4 states since last reset. Counts at 1 Mhz - frequency. - - @param ECX MSR_ATOM_PKG_C4_RESIDENCY (0x000003F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_PKG_C4_RESIDENCY); - AsmWriteMsr64 (MSR_ATOM_PKG_C4_RESIDENCY, Msr); - @endcode - @note MSR_ATOM_PKG_C4_RESIDENCY is defined as MSR_PKG_C4_RESIDENCY in SDM. -**/ -#define MSR_ATOM_PKG_C4_RESIDENCY 0x000003F9 - - -/** - Package. Package C6 Residency Note: C-state values are processor specific - C-state code names, unrelated to MWAIT extension C-state parameters or ACPI - C-States. Package. Package C6 Residency Counter. (R/O) Time that this - package is in processor-specific C6 states since last reset. Counts at 1 Mhz - frequency. - - @param ECX MSR_ATOM_PKG_C6_RESIDENCY (0x000003FA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_ATOM_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_ATOM_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_ATOM_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003FA - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h deleted file mode 100644 index 90bd523c9..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h +++ /dev/null @@ -1,306 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Broadwell microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.13. - -**/ - -#ifndef __BROADWELL_MSR_H__ -#define __BROADWELL_MSR_H__ - -#include - -/** - Is Intel processors based on the Broadwell microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_BROADWELL_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x3D || \ - DisplayModel == 0x47 || \ - DisplayModel == 0x4F || \ - DisplayModel == 0x56 \ - ) \ - ) - -/** - Thread. See Table 35-2. See Section 18.4.2, "Global Counter Control - Facilities.". - - @param ECX MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS is defined as IA32_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS 0x0000038E - -/** - MSR information returned for MSR index #MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Trace_ToPA_PMI. See Section 36.2.6.2, "Table of Physical - /// Addresses (ToPA).". - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:5; - /// - /// [Bit 61] Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Ovf_BufDSSAVE. - /// - UINT32 OvfBuf:1; - /// - /// [Bit 63] CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_BROADWELL_IA32_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are processor - specific C-state code names, unrelated to MWAIT extension C-state parameters - or ACPI C-states. `See http://biosbits.org. `__. - - @param ECX MSR_BROADWELL_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_BROADWELL_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_BROADWELL_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_BROADWELL_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power) for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 0000b: - /// C0/C1 (no package C-state support) 0001b: C2 0010b: C3 0011b: C6 - /// 0100b: C7 0101b: C7s 0110b: C8 0111b: C9 1000b: C10. - /// - UINT32 Limit:4; - UINT32 Reserved1:6; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W). - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO). - /// - UINT32 CFGLock:1; - UINT32 Reserved3:9; - /// - /// [Bit 25] C3 State Auto Demotion Enable (R/W). - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 State Auto Demotion Enable (R/W). - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 Undemotion (R/W). - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 Undemotion (R/W). - /// - UINT32 C1Undemotion:1; - /// - /// [Bit 29] Enable Package C-State Auto-demotion (R/W). - /// - UINT32 CStateAutoDemotion:1; - /// - /// [Bit 30] Enable Package C-State Undemotion (R/W). - /// - UINT32 CStateUndemotion:1; - UINT32 Reserved4:1; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_BROADWELL_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_BROADWELL_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_BROADWELL_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_BROADWELL_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_TURBO_RATIO_LIMIT); - @endcode - @note MSR_BROADWELL_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_BROADWELL_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_BROADWELL_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C Maximum turbo ratio - /// limit of 5core active. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C Maximum turbo ratio - /// limit of 6core active. - /// - UINT32 Maximum6C:8; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_BROADWELL_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_BROADWELL_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_BROADWELL_PP0_ENERGY_STATUS); - @endcode - @note MSR_BROADWELL_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_BROADWELL_PP0_ENERGY_STATUS 0x00000639 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Core2Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/Core2Msr.h deleted file mode 100644 index 9ebca5e9b..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Core2Msr.h +++ /dev/null @@ -1,1134 +0,0 @@ -/** @file - MSR Definitions for the Intel(R) Core(TM) 2 Processor Family. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.2. - -**/ - -#ifndef __CORE2_MSR_H__ -#define __CORE2_MSR_H__ - -#include - -/** - Is Intel(R) Core(TM) 2 Processor Family? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_CORE2_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x0F || \ - DisplayModel == 0x17 \ - ) \ - ) - -/** - Shared. Model Specific Platform ID (R). - - @param ECX MSR_CORE2_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_CORE2_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PLATFORM_ID); - @endcode - @note MSR_CORE2_PLATFORM_ID is defined as MSR_PLATFORM_ID in SDM. -**/ -#define MSR_CORE2_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_CORE2_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 12:8] Maximum Qualified Ratio (R) The maximum allowed bus ratio. - /// - UINT32 MaximumQualifiedRatio:5; - UINT32 Reserved2:19; - UINT32 Reserved3:18; - /// - /// [Bits 52:50] See Table 35-2. - /// - UINT32 PlatformId:3; - UINT32 Reserved4:11; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_PLATFORM_ID_REGISTER; - - -/** - Shared. Processor Hard Power-On Configuration (R/W) Enables and disables - processor features; (R) indicates current processor configuration. - - @param ECX MSR_CORE2_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_CORE2_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_CORE2_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_CORE2_EBL_CR_POWERON is defined as MSR_EBL_CR_POWERON in SDM. -**/ -#define MSR_CORE2_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_CORE2_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Data Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Note: Not all processor implements R/W. - /// - UINT32 DataErrorCheckingEnable:1; - /// - /// [Bit 2] Response Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Note: Not all processor implements R/W. - /// - UINT32 ResponseErrorCheckingEnable:1; - /// - /// [Bit 3] MCERR# Drive Enable (R/W) 1 = Enabled; 0 = Disabled Note: Not - /// all processor implements R/W. - /// - UINT32 MCERR_DriveEnable:1; - /// - /// [Bit 4] Address Parity Enable (R/W) 1 = Enabled; 0 = Disabled Note: - /// Not all processor implements R/W. - /// - UINT32 AddressParityEnable:1; - UINT32 Reserved2:1; - UINT32 Reserved3:1; - /// - /// [Bit 7] BINIT# Driver Enable (R/W) 1 = Enabled; 0 = Disabled Note: Not - /// all processor implements R/W. - /// - UINT32 BINIT_DriverEnable:1; - /// - /// [Bit 8] Output Tri-state Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 OutputTriStateEnable:1; - /// - /// [Bit 9] Execute BIST (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 10] MCERR# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 MCERR_ObservationEnabled:1; - /// - /// [Bit 11] Intel TXT Capable Chipset. (R/O) 1 = Present; 0 = Not Present. - /// - UINT32 IntelTXTCapableChipset:1; - /// - /// [Bit 12] BINIT# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 BINIT_ObservationEnabled:1; - UINT32 Reserved4:1; - /// - /// [Bit 14] 1 MByte Power on Reset Vector (R/O) 1 = 1 MByte; 0 = 4 GBytes. - /// - UINT32 ResetVector:1; - UINT32 Reserved5:1; - /// - /// [Bits 17:16] APIC Cluster ID (R/O). - /// - UINT32 APICClusterID:2; - /// - /// [Bit 18] N/2 Non-Integer Bus Ratio (R/O) 0 = Integer ratio; 1 = - /// Non-integer ratio. - /// - UINT32 NonIntegerBusRatio:1; - UINT32 Reserved6:1; - /// - /// [Bits 21:20] Symmetric Arbitration ID (R/O). - /// - UINT32 SymmetricArbitrationID:2; - /// - /// [Bits 26:22] Integer Bus Frequency Ratio (R/O). - /// - UINT32 IntegerBusFrequencyRatio:5; - UINT32 Reserved7:5; - UINT32 Reserved8:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_EBL_CR_POWERON_REGISTER; - - -/** - Unique. Control Features in Intel 64Processor (R/W) See Table 35-2. - - @param ECX MSR_CORE2_FEATURE_CONTROL (0x0000003A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_CORE2_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_CORE2_FEATURE_CONTROL is defined as MSR_FEATURE_CONTROL in SDM. -**/ -#define MSR_CORE2_FEATURE_CONTROL 0x0000003A - -/** - MSR information returned for MSR index #MSR_CORE2_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:3; - /// - /// [Bit 3] Unique. SMRR Enable (R/WL) When this bit is set and the lock - /// bit is set makes the SMRR_PHYS_BASE and SMRR_PHYS_MASK registers read - /// visible and writeable while in SMM. - /// - UINT32 SMRREnable:1; - UINT32 Reserved2:28; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_FEATURE_CONTROL_REGISTER; - - -/** - Unique. Last Branch Record n From IP (R/W) One of four pairs of last branch - record registers on the last branch record stack. The From_IP part of the - stack contains pointers to the source instruction. See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.5. - - @param ECX MSR_CORE2_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_CORE2_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_CORE2_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_CORE2_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_CORE2_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - @{ -**/ -#define MSR_CORE2_LASTBRANCH_0_FROM_IP 0x00000040 -#define MSR_CORE2_LASTBRANCH_1_FROM_IP 0x00000041 -#define MSR_CORE2_LASTBRANCH_2_FROM_IP 0x00000042 -#define MSR_CORE2_LASTBRANCH_3_FROM_IP 0x00000043 -/// @} - - -/** - Unique. Last Branch Record n To IP (R/W) One of four pairs of last branch - record registers on the last branch record stack. This To_IP part of the - stack contains pointers to the destination instruction. - - @param ECX MSR_CORE2_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_CORE2_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_CORE2_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_CORE2_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_CORE2_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - @{ -**/ -#define MSR_CORE2_LASTBRANCH_0_TO_IP 0x00000060 -#define MSR_CORE2_LASTBRANCH_1_TO_IP 0x00000061 -#define MSR_CORE2_LASTBRANCH_2_TO_IP 0x00000062 -#define MSR_CORE2_LASTBRANCH_3_TO_IP 0x00000063 -/// @} - - -/** - Unique. System Management Mode Base Address register (WO in SMM) - Model-specific implementation of SMRR-like interface, read visible and write - only in SMM. - - @param ECX MSR_CORE2_SMRR_PHYSBASE (0x000000A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_SMRR_PHYSBASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_SMRR_PHYSBASE_REGISTER. - - Example usage - @code - MSR_CORE2_SMRR_PHYSBASE_REGISTER Msr; - - Msr.Uint64 = 0; - AsmWriteMsr64 (MSR_CORE2_SMRR_PHYSBASE, Msr.Uint64); - @endcode - @note MSR_CORE2_SMRR_PHYSBASE is defined as MSR_SMRR_PHYSBASE in SDM. -**/ -#define MSR_CORE2_SMRR_PHYSBASE 0x000000A0 - -/** - MSR information returned for MSR index #MSR_CORE2_SMRR_PHYSBASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:12; - /// - /// [Bits 31:12] PhysBase. SMRR physical Base Address. - /// - UINT32 PhysBase:20; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_SMRR_PHYSBASE_REGISTER; - - -/** - Unique. System Management Mode Physical Address Mask register (WO in SMM) - Model-specific implementation of SMRR-like interface, read visible and write - only in SMM. - - @param ECX MSR_CORE2_SMRR_PHYSMASK (0x000000A1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_SMRR_PHYSMASK_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_SMRR_PHYSMASK_REGISTER. - - Example usage - @code - MSR_CORE2_SMRR_PHYSMASK_REGISTER Msr; - - Msr.Uint64 = 0; - AsmWriteMsr64 (MSR_CORE2_SMRR_PHYSMASK, Msr.Uint64); - @endcode - @note MSR_CORE2_SMRR_PHYSMASK is defined as MSR_SMRR_PHYSMASK in SDM. -**/ -#define MSR_CORE2_SMRR_PHYSMASK 0x000000A1 - -/** - MSR information returned for MSR index #MSR_CORE2_SMRR_PHYSMASK -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:11; - /// - /// [Bit 11] Valid. Physical address base and range mask are valid. - /// - UINT32 Valid:1; - /// - /// [Bits 31:12] PhysMask. SMRR physical address range mask. - /// - UINT32 PhysMask:20; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_SMRR_PHYSMASK_REGISTER; - - -/** - Shared. Scalable Bus Speed(RO) This field indicates the intended scalable - bus clock speed for processors based on Intel Core microarchitecture:. - - @param ECX MSR_CORE2_FSB_FREQ (0x000000CD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_FSB_FREQ_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_FSB_FREQ_REGISTER. - - Example usage - @code - MSR_CORE2_FSB_FREQ_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_FSB_FREQ); - @endcode - @note MSR_CORE2_FSB_FREQ is defined as MSR_FSB_FREQ in SDM. -**/ -#define MSR_CORE2_FSB_FREQ 0x000000CD - -/** - MSR information returned for MSR index #MSR_CORE2_FSB_FREQ -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] - Scalable Bus Speed - /// 101B: 100 MHz (FSB 400) - /// 001B: 133 MHz (FSB 533) - /// 011B: 167 MHz (FSB 667) - /// 010B: 200 MHz (FSB 800) - /// 000B: 267 MHz (FSB 1067) - /// 100B: 333 MHz (FSB 1333) - /// - /// 133.33 MHz should be utilized if performing calculation with System - /// Bus Speed when encoding is 001B. 166.67 MHz should be utilized if - /// performing calculation with System Bus Speed when encoding is 011B. - /// 266.67 MHz should be utilized if performing calculation with System - /// Bus Speed when encoding is 000B. 333.33 MHz should be utilized if - /// performing calculation with System Bus Speed when encoding is 100B. - /// - UINT32 ScalableBusSpeed:3; - UINT32 Reserved1:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_FSB_FREQ_REGISTER; - - -/** - Shared. - - @param ECX MSR_CORE2_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_CORE2_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_CORE2_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_CORE2_BBL_CR_CTL3 is defined as MSR_BBL_CR_CTL3 in SDM. -**/ -#define MSR_CORE2_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_CORE2_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Hardware Enabled (RO) 1 = If the L2 is hardware-enabled 0 = - /// Indicates if the L2 is hardware-disabled. - /// - UINT32 L2HardwareEnabled:1; - UINT32 Reserved1:7; - /// - /// [Bit 8] L2 Enabled (R/W) 1 = L2 cache has been initialized 0 = - /// Disabled (default) Until this bit is set the processor will not - /// respond to the WBINVD instruction or the assertion of the FLUSH# input. - /// - UINT32 L2Enabled:1; - UINT32 Reserved2:14; - /// - /// [Bit 23] L2 Not Present (RO) 1. = L2 Present 2. = L2 Not Present. - /// - UINT32 L2NotPresent:1; - UINT32 Reserved3:8; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_BBL_CR_CTL3_REGISTER; - - -/** - Shared. - - @param ECX MSR_CORE2_PERF_STATUS (0x00000198) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_PERF_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_PERF_STATUS_REGISTER. - - Example usage - @code - MSR_CORE2_PERF_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PERF_STATUS); - AsmWriteMsr64 (MSR_CORE2_PERF_STATUS, Msr.Uint64); - @endcode - @note MSR_CORE2_PERF_STATUS is defined as MSR_PERF_STATUS in SDM. -**/ -#define MSR_CORE2_PERF_STATUS 0x00000198 - -/** - MSR information returned for MSR index #MSR_CORE2_PERF_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Current Performance State Value. - /// - UINT32 CurrentPerformanceStateValue:16; - UINT32 Reserved1:15; - /// - /// [Bit 31] XE Operation (R/O). If set, XE operation is enabled. Default - /// is cleared. - /// - UINT32 XEOperation:1; - UINT32 Reserved2:8; - /// - /// [Bits 44:40] Maximum Bus Ratio (R/O) Indicates maximum bus ratio - /// configured for the processor. - /// - UINT32 MaximumBusRatio:5; - UINT32 Reserved3:1; - /// - /// [Bit 46] Non-Integer Bus Ratio (R/O) Indicates non-integer bus ratio - /// is enabled. Applies processors based on Enhanced Intel Core - /// microarchitecture. - /// - UINT32 NonIntegerBusRatio:1; - UINT32 Reserved4:17; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_PERF_STATUS_REGISTER; - - -/** - Unique. - - @param ECX MSR_CORE2_THERM2_CTL (0x0000019D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_THERM2_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_THERM2_CTL_REGISTER. - - Example usage - @code - MSR_CORE2_THERM2_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_THERM2_CTL); - AsmWriteMsr64 (MSR_CORE2_THERM2_CTL, Msr.Uint64); - @endcode - @note MSR_CORE2_THERM2_CTL is defined as MSR_THERM2_CTL in SDM. -**/ -#define MSR_CORE2_THERM2_CTL 0x0000019D - -/** - MSR information returned for MSR index #MSR_CORE2_THERM2_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bit 16] TM_SELECT (R/W) Mode of automatic thermal monitor: 1. = - /// Thermal Monitor 1 (thermally-initiated on-die modulation of the - /// stop-clock duty cycle) 2. = Thermal Monitor 2 (thermally-initiated - /// frequency transitions) If bit 3 of the IA32_MISC_ENABLE register is - /// cleared, TM_SELECT has no effect. Neither TM1 nor TM2 are enabled. - /// - UINT32 TM_SELECT:1; - UINT32 Reserved2:15; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_THERM2_CTL_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_CORE2_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_CORE2_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_CORE2_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_CORE2_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_CORE2_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_CORE2_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Unique. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Shared. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:1; - /// - /// [Bit 9] Hardware Prefetcher Disable (R/W) When set, disables the - /// hardware prefetcher operation on streams of data. When clear - /// (default), enables the prefetch queue. Disabling of the hardware - /// prefetcher may impact processor performance. - /// - UINT32 HardwarePrefetcherDisable:1; - /// - /// [Bit 10] Shared. FERR# Multiplexing Enable (R/W) 1 = FERR# asserted by - /// the processor to indicate a pending break event within the processor 0 - /// = Indicates compatible FERR# signaling behavior This bit must be set - /// to 1 to support XAPIC interrupt model usage. - /// - UINT32 FERR:1; - /// - /// [Bit 11] Shared. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Shared. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - /// - /// [Bit 13] Shared. TM2 Enable (R/W) When this bit is set (1) and the - /// thermal sensor indicates that the die temperature is at the - /// pre-determined threshold, the Thermal Monitor 2 mechanism is engaged. - /// TM2 will reduce the bus to core ratio and voltage according to the - /// value last written to MSR_THERM2_CTL bits 15:0. - /// When this bit is clear (0, default), the processor does not change - /// the VID signals or the bus to core ratio when the processor enters a - /// thermally managed state. The BIOS must enable this feature if the - /// TM2 feature flag (CPUID.1:ECX[8]) is set; if the TM2 feature flag is - /// not set, this feature is not supported and BIOS must not alter the - /// contents of the TM2 bit location. The processor is operating out of - /// specification if both this bit and the TM1 bit are set to 0. - /// - UINT32 TM2:1; - UINT32 Reserved4:2; - /// - /// [Bit 16] Shared. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] Shared. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - /// - /// [Bit 19] Shared. Adjacent Cache Line Prefetch Disable (R/W) When set - /// to 1, the processor fetches the cache line that contains data - /// currently required by the processor. When set to 0, the processor - /// fetches cache lines that comprise a cache line pair (128 bytes). - /// Single processor platforms should not set this bit. Server platforms - /// should set or clear this bit based on platform performance observed in - /// validation and testing. BIOS may contain a setup option that controls - /// the setting of this bit. - /// - UINT32 AdjacentCacheLinePrefetchDisable:1; - /// - /// [Bit 20] Shared. Enhanced Intel SpeedStep Technology Select Lock - /// (R/WO) When set, this bit causes the following bits to become - /// read-only: - Enhanced Intel SpeedStep Technology Select Lock (this - /// bit), - Enhanced Intel SpeedStep Technology Enable bit. The bit must - /// be set before an Enhanced Intel SpeedStep Technology transition is - /// requested. This bit is cleared on reset. - /// - UINT32 EISTLock:1; - UINT32 Reserved6:1; - /// - /// [Bit 22] Shared. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Shared. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] Unique. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved9:2; - /// - /// [Bit 37] Unique. DCU Prefetcher Disable (R/W) When set to 1, The DCU - /// L1 data cache prefetcher is disabled. The default value after reset is - /// 0. BIOS may write '1' to disable this feature. The DCU prefetcher is - /// an L1 data cache prefetcher. When the DCU prefetcher detects multiple - /// loads from the same line done within a time limit, the DCU prefetcher - /// assumes the next line will be required. The next line is prefetched in - /// to the L1 data cache from memory or L2. - /// - UINT32 DCUPrefetcherDisable:1; - /// - /// [Bit 38] Shared. IDA Disable (R/W) When set to 1 on processors that - /// support IDA, the Intel Dynamic Acceleration feature (IDA) is disabled - /// and the IDA_Enable feature flag will be clear (CPUID.06H: EAX[1]=0). - /// When set to a 0 on processors that support IDA, CPUID.06H: EAX[1] - /// reports the processor's support of IDA is enabled. Note: the power-on - /// default value is used by BIOS to detect hardware support of IDA. If - /// power-on default value is 1, IDA is available in the processor. If - /// power-on default value is 0, IDA is not available. - /// - UINT32 IDADisable:1; - /// - /// [Bit 39] Unique. IP Prefetcher Disable (R/W) When set to 1, The IP - /// prefetcher is disabled. The default value after reset is 0. BIOS may - /// write '1' to disable this feature. The IP prefetcher is an L1 data - /// cache prefetcher. The IP prefetcher looks for sequential load history - /// to determine whether to prefetch the next expected data into the L1 - /// cache from memory or L2. - /// - UINT32 IPPrefetcherDisable:1; - UINT32 Reserved10:24; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_IA32_MISC_ENABLE_REGISTER; - - -/** - Unique. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-3) - that points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP (at 40H). - - @param ECX MSR_CORE2_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_CORE2_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_CORE2_LASTBRANCH_TOS 0x000001C9 - - -/** - Unique. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_CORE2_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_LER_FROM_LIP); - @endcode - @note MSR_CORE2_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_CORE2_LER_FROM_LIP 0x000001DD - - -/** - Unique. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_CORE2_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_LER_TO_LIP); - @endcode - @note MSR_CORE2_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_CORE2_LER_TO_LIP 0x000001DE - - -/** - Unique. Fixed-Function Performance Counter Register n (R/W). - - @param ECX MSR_CORE2_PERF_FIXED_CTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_PERF_FIXED_CTR0); - AsmWriteMsr64 (MSR_CORE2_PERF_FIXED_CTR0, Msr); - @endcode - @note MSR_CORE2_PERF_FIXED_CTR0 is defined as MSR_PERF_FIXED_CTR0 in SDM. - MSR_CORE2_PERF_FIXED_CTR1 is defined as MSR_PERF_FIXED_CTR1 in SDM. - MSR_CORE2_PERF_FIXED_CTR2 is defined as MSR_PERF_FIXED_CTR2 in SDM. - @{ -**/ -#define MSR_CORE2_PERF_FIXED_CTR0 0x00000309 -#define MSR_CORE2_PERF_FIXED_CTR1 0x0000030A -#define MSR_CORE2_PERF_FIXED_CTR2 0x0000030B -/// @} - - -/** - Unique. RO. This applies to processors that do not support architectural - perfmon version 2. - - @param ECX MSR_CORE2_PERF_CAPABILITIES (0x00000345) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_PERF_CAPABILITIES_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_PERF_CAPABILITIES_REGISTER. - - Example usage - @code - MSR_CORE2_PERF_CAPABILITIES_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PERF_CAPABILITIES); - AsmWriteMsr64 (MSR_CORE2_PERF_CAPABILITIES, Msr.Uint64); - @endcode - @note MSR_CORE2_PERF_CAPABILITIES is defined as MSR_PERF_CAPABILITIES in SDM. -**/ -#define MSR_CORE2_PERF_CAPABILITIES 0x00000345 - -/** - MSR information returned for MSR index #MSR_CORE2_PERF_CAPABILITIES -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 5:0] LBR Format. See Table 35-2. - /// - UINT32 LBR_FMT:6; - /// - /// [Bit 6] PEBS Record Format. - /// - UINT32 PEBS_FMT:1; - /// - /// [Bit 7] PEBSSaveArchRegs. See Table 35-2. - /// - UINT32 PEBS_ARCH_REG:1; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_PERF_CAPABILITIES_REGISTER; - - -/** - Unique. Fixed-Function-Counter Control Register (R/W). - - @param ECX MSR_CORE2_PERF_FIXED_CTR_CTRL (0x0000038D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_PERF_FIXED_CTR_CTRL); - AsmWriteMsr64 (MSR_CORE2_PERF_FIXED_CTR_CTRL, Msr); - @endcode - @note MSR_CORE2_PERF_FIXED_CTR_CTRL is defined as MSR_PERF_FIXED_CTR_CTRL in SDM. -**/ -#define MSR_CORE2_PERF_FIXED_CTR_CTRL 0x0000038D - - -/** - Unique. See Section 18.4.2, "Global Counter Control Facilities.". - - @param ECX MSR_CORE2_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_STATUS, Msr); - @endcode - @note MSR_CORE2_PERF_GLOBAL_STATUS is defined as MSR_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_CORE2_PERF_GLOBAL_STATUS 0x0000038E - - -/** - Unique. See Section 18.4.2, "Global Counter Control Facilities.". - - @param ECX MSR_CORE2_PERF_GLOBAL_CTRL (0x0000038F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_CTRL, Msr); - @endcode - @note MSR_CORE2_PERF_GLOBAL_CTRL is defined as MSR_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_CORE2_PERF_GLOBAL_CTRL 0x0000038F - - -/** - Unique. See Section 18.4.2, "Global Counter Control Facilities.". - - @param ECX MSR_CORE2_PERF_GLOBAL_OVF_CTRL (0x00000390) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_OVF_CTRL, Msr); - @endcode - @note MSR_CORE2_PERF_GLOBAL_OVF_CTRL is defined as MSR_PERF_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_CORE2_PERF_GLOBAL_OVF_CTRL 0x00000390 - - -/** - Unique. See Table 35-2. See Section 18.4.4, "Processor Event Based Sampling - (PEBS).". - - @param ECX MSR_CORE2_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE2_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE2_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_CORE2_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PEBS_ENABLE); - AsmWriteMsr64 (MSR_CORE2_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_CORE2_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_CORE2_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_CORE2_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. (R/W). - /// - UINT32 Enable:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE2_PEBS_ENABLE_REGISTER; - - -/** - Unique. GBUSQ Event Control/Counter Register (R/W) Apply to Intel Xeon - processor 7400 series (processor signature 06_1D) only. See Section 17.2.2. - - @param ECX MSR_CORE2_EMON_L3_CTR_CTLn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_EMON_L3_CTR_CTL0); - AsmWriteMsr64 (MSR_CORE2_EMON_L3_CTR_CTL0, Msr); - @endcode - @note MSR_CORE2_EMON_L3_CTR_CTL0 is defined as MSR_EMON_L3_CTR_CTL0 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL1 is defined as MSR_EMON_L3_CTR_CTL1 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL2 is defined as MSR_EMON_L3_CTR_CTL2 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL3 is defined as MSR_EMON_L3_CTR_CTL3 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL4 is defined as MSR_EMON_L3_CTR_CTL4 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL5 is defined as MSR_EMON_L3_CTR_CTL5 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL6 is defined as MSR_EMON_L3_CTR_CTL6 in SDM. - MSR_CORE2_EMON_L3_CTR_CTL7 is defined as MSR_EMON_L3_CTR_CTL7 in SDM. - @{ -**/ -#define MSR_CORE2_EMON_L3_CTR_CTL0 0x000107CC -#define MSR_CORE2_EMON_L3_CTR_CTL1 0x000107CD -#define MSR_CORE2_EMON_L3_CTR_CTL2 0x000107CE -#define MSR_CORE2_EMON_L3_CTR_CTL3 0x000107CF -#define MSR_CORE2_EMON_L3_CTR_CTL4 0x000107D0 -#define MSR_CORE2_EMON_L3_CTR_CTL5 0x000107D1 -#define MSR_CORE2_EMON_L3_CTR_CTL6 0x000107D2 -#define MSR_CORE2_EMON_L3_CTR_CTL7 0x000107D3 -/// @} - - -/** - Unique. L3/FSB Common Control Register (R/W) Apply to Intel Xeon processor - 7400 series (processor signature 06_1D) only. See Section 17.2.2. - - @param ECX MSR_CORE2_EMON_L3_GL_CTL (0x000107D8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE2_EMON_L3_GL_CTL); - AsmWriteMsr64 (MSR_CORE2_EMON_L3_GL_CTL, Msr); - @endcode - @note MSR_CORE2_EMON_L3_GL_CTL is defined as MSR_EMON_L3_GL_CTL in SDM. -**/ -#define MSR_CORE2_EMON_L3_GL_CTL 0x000107D8 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/CoreMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/CoreMsr.h deleted file mode 100644 index 4897c74d5..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/CoreMsr.h +++ /dev/null @@ -1,1110 +0,0 @@ -/** @file - MSR Definitions for Intel Core Solo and Intel Core Duo Processors. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.19. - -**/ - -#ifndef __CORE_MSR_H__ -#define __CORE_MSR_H__ - -#include - -/** - Is Intel Core Solo and Intel Core Duo Processors? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_CORE_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x0E \ - ) \ - ) - -/** - Unique. See Section 35.22, "MSRs in Pentium Processors," and see Table 35-2. - - @param ECX MSR_CORE_P5_MC_ADDR (0x00000000) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_P5_MC_ADDR); - AsmWriteMsr64 (MSR_CORE_P5_MC_ADDR, Msr); - @endcode - @note MSR_CORE_P5_MC_ADDR is defined as P5_MC_ADDR in SDM. -**/ -#define MSR_CORE_P5_MC_ADDR 0x00000000 - - -/** - Unique. See Section 35.22, "MSRs in Pentium Processors," and see Table 35-2. - - @param ECX MSR_CORE_P5_MC_TYPE (0x00000001) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_P5_MC_TYPE); - AsmWriteMsr64 (MSR_CORE_P5_MC_TYPE, Msr); - @endcode - @note MSR_CORE_P5_MC_TYPE is defined as P5_MC_TYPE in SDM. -**/ -#define MSR_CORE_P5_MC_TYPE 0x00000001 - - -/** - Shared. Processor Hard Power-On Configuration (R/W) Enables and disables - processor features; (R) indicates current processor configuration. - - @param ECX MSR_CORE_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_CORE_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_CORE_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_CORE_EBL_CR_POWERON is defined as MSR_EBL_CR_POWERON in SDM. -**/ -#define MSR_CORE_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_CORE_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Data Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Note: Not all processor implements R/W. - /// - UINT32 DataErrorCheckingEnable:1; - /// - /// [Bit 2] Response Error Checking Enable (R/W) 1 = Enabled; 0 = Disabled - /// Note: Not all processor implements R/W. - /// - UINT32 ResponseErrorCheckingEnable:1; - /// - /// [Bit 3] MCERR# Drive Enable (R/W) 1 = Enabled; 0 = Disabled Note: Not - /// all processor implements R/W. - /// - UINT32 MCERR_DriveEnable:1; - /// - /// [Bit 4] Address Parity Enable (R/W) 1 = Enabled; 0 = Disabled Note: - /// Not all processor implements R/W. - /// - UINT32 AddressParityEnable:1; - UINT32 Reserved2:2; - /// - /// [Bit 7] BINIT# Driver Enable (R/W) 1 = Enabled; 0 = Disabled Note: Not - /// all processor implements R/W. - /// - UINT32 BINIT_DriverEnable:1; - /// - /// [Bit 8] Output Tri-state Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 OutputTriStateEnable:1; - /// - /// [Bit 9] Execute BIST (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 10] MCERR# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 MCERR_ObservationEnabled:1; - UINT32 Reserved3:1; - /// - /// [Bit 12] BINIT# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 BINIT_ObservationEnabled:1; - UINT32 Reserved4:1; - /// - /// [Bit 14] 1 MByte Power on Reset Vector (R/O) 1 = 1 MByte; 0 = 4 GBytes. - /// - UINT32 ResetVector:1; - UINT32 Reserved5:1; - /// - /// [Bits 17:16] APIC Cluster ID (R/O). - /// - UINT32 APICClusterID:2; - /// - /// [Bit 18] System Bus Frequency (R/O) 1. = 100 MHz 2. = Reserved. - /// - UINT32 SystemBusFrequency:1; - UINT32 Reserved6:1; - /// - /// [Bits 21:20] Symmetric Arbitration ID (R/O). - /// - UINT32 SymmetricArbitrationID:2; - /// - /// [Bits 26:22] Clock Frequency Ratio (R/O). - /// - UINT32 ClockFrequencyRatio:5; - UINT32 Reserved7:5; - UINT32 Reserved8:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_EBL_CR_POWERON_REGISTER; - - -/** - Unique. Last Branch Record n (R/W) One of 8 last branch record registers on - the last branch record stack: bits 31-0 hold the 'from' address and bits - 63-32 hold the 'to' address. See also: - Last Branch Record Stack TOS at - 1C9H - Section 17.13, "Last Branch, Interrupt, and Exception Recording - (Pentium M Processors).". - - @param ECX MSR_CORE_LASTBRANCH_n - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_LASTBRANCH_0); - AsmWriteMsr64 (MSR_CORE_LASTBRANCH_0, Msr); - @endcode - @note MSR_CORE_LASTBRANCH_0 is defined as MSR_LASTBRANCH_0 in SDM. - MSR_CORE_LASTBRANCH_1 is defined as MSR_LASTBRANCH_1 in SDM. - MSR_CORE_LASTBRANCH_2 is defined as MSR_LASTBRANCH_2 in SDM. - MSR_CORE_LASTBRANCH_3 is defined as MSR_LASTBRANCH_3 in SDM. - MSR_CORE_LASTBRANCH_4 is defined as MSR_LASTBRANCH_4 in SDM. - MSR_CORE_LASTBRANCH_5 is defined as MSR_LASTBRANCH_5 in SDM. - MSR_CORE_LASTBRANCH_6 is defined as MSR_LASTBRANCH_6 in SDM. - MSR_CORE_LASTBRANCH_7 is defined as MSR_LASTBRANCH_7 in SDM. - @{ -**/ -#define MSR_CORE_LASTBRANCH_0 0x00000040 -#define MSR_CORE_LASTBRANCH_1 0x00000041 -#define MSR_CORE_LASTBRANCH_2 0x00000042 -#define MSR_CORE_LASTBRANCH_3 0x00000043 -#define MSR_CORE_LASTBRANCH_4 0x00000044 -#define MSR_CORE_LASTBRANCH_5 0x00000045 -#define MSR_CORE_LASTBRANCH_6 0x00000046 -#define MSR_CORE_LASTBRANCH_7 0x00000047 -/// @} - - -/** - Shared. Scalable Bus Speed (RO) This field indicates the scalable bus - clock speed:. - - @param ECX MSR_CORE_FSB_FREQ (0x000000CD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_FSB_FREQ_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_FSB_FREQ_REGISTER. - - Example usage - @code - MSR_CORE_FSB_FREQ_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_FSB_FREQ); - @endcode - @note MSR_CORE_FSB_FREQ is defined as MSR_FSB_FREQ in SDM. -**/ -#define MSR_CORE_FSB_FREQ 0x000000CD - -/** - MSR information returned for MSR index #MSR_CORE_FSB_FREQ -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] - Scalable Bus Speed - /// 101B: 100 MHz (FSB 400) - /// 001B: 133 MHz (FSB 533) - /// 011B: 167 MHz (FSB 667) - /// - /// 133.33 MHz should be utilized if performing calculation with System Bus - /// Speed when encoding is 101B. 166.67 MHz should be utilized if - /// performing calculation with System Bus Speed when encoding is 001B. - /// - UINT32 ScalableBusSpeed:3; - UINT32 Reserved1:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_FSB_FREQ_REGISTER; - - -/** - Shared. - - @param ECX MSR_CORE_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_CORE_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_CORE_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_CORE_BBL_CR_CTL3 is defined as MSR_BBL_CR_CTL3 in SDM. -**/ -#define MSR_CORE_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_CORE_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Hardware Enabled (RO) 1 = If the L2 is hardware-enabled 0 = - /// Indicates if the L2 is hardware-disabled. - /// - UINT32 L2HardwareEnabled:1; - UINT32 Reserved1:7; - /// - /// [Bit 8] L2 Enabled (R/W) 1 = L2 cache has been initialized 0 = - /// Disabled (default) Until this bit is set the processor will not - /// respond to the WBINVD instruction or the assertion of the FLUSH# input. - /// - UINT32 L2Enabled:1; - UINT32 Reserved2:14; - /// - /// [Bit 23] L2 Not Present (RO) 1. = L2 Present 2. = L2 Not Present. - /// - UINT32 L2NotPresent:1; - UINT32 Reserved3:8; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_BBL_CR_CTL3_REGISTER; - - -/** - Unique. - - @param ECX MSR_CORE_THERM2_CTL (0x0000019D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_THERM2_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_THERM2_CTL_REGISTER. - - Example usage - @code - MSR_CORE_THERM2_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_THERM2_CTL); - AsmWriteMsr64 (MSR_CORE_THERM2_CTL, Msr.Uint64); - @endcode - @note MSR_CORE_THERM2_CTL is defined as MSR_THERM2_CTL in SDM. -**/ -#define MSR_CORE_THERM2_CTL 0x0000019D - -/** - MSR information returned for MSR index #MSR_CORE_THERM2_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bit 16] TM_SELECT (R/W) Mode of automatic thermal monitor: 1. = - /// Thermal Monitor 1 (thermally-initiated on-die modulation of the - /// stop-clock duty cycle) 2. = Thermal Monitor 2 (thermally-initiated - /// frequency transitions) If bit 3 of the IA32_MISC_ENABLE register is - /// cleared, TM_SELECT has no effect. Neither TM1 nor TM2 will be enabled. - /// - UINT32 TM_SELECT:1; - UINT32 Reserved2:15; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_THERM2_CTL_REGISTER; - - -/** - Enable Miscellaneous Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_CORE_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_CORE_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_CORE_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_CORE_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_CORE_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_CORE_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:3; - /// - /// [Bit 3] Unique. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Shared. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:2; - /// - /// [Bit 10] Shared. FERR# Multiplexing Enable (R/W) 1 = FERR# asserted by - /// the processor to indicate a pending break event within the processor 0 - /// = Indicates compatible FERR# signaling behavior This bit must be set - /// to 1 to support XAPIC interrupt model usage. - /// - UINT32 FERR:1; - /// - /// [Bit 11] Shared. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - UINT32 Reserved4:1; - /// - /// [Bit 13] Shared. TM2 Enable (R/W) When this bit is set (1) and the - /// thermal sensor indicates that the die temperature is at the - /// pre-determined threshold, the Thermal Monitor 2 mechanism is engaged. - /// TM2 will reduce the bus to core ratio and voltage according to the - /// value last written to MSR_THERM2_CTL bits 15:0. When this bit is clear - /// (0, default), the processor does not change the VID signals or the bus - /// to core ratio when the processor enters a thermal managed state. If - /// the TM2 feature flag (ECX[8]) is not set to 1 after executing CPUID - /// with EAX = 1, then this feature is not supported and BIOS must not - /// alter the contents of this bit location. The processor is operating - /// out of spec if both this bit and the TM1 bit are set to disabled - /// states. - /// - UINT32 TM2:1; - UINT32 Reserved5:2; - /// - /// [Bit 16] Shared. Enhanced Intel SpeedStep Technology Enable (R/W) 1 = - /// Enhanced Intel SpeedStep Technology enabled. - /// - UINT32 EIST:1; - UINT32 Reserved6:1; - /// - /// [Bit 18] Shared. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved7:1; - UINT32 Reserved8:2; - /// - /// [Bit 22] Shared. Limit CPUID Maxval (R/W) See Table 35-2. Setting this - /// bit may cause behavior in software that depends on the availability of - /// CPUID leaves greater than 2. - /// - UINT32 LimitCpuidMaxval:1; - UINT32 Reserved9:9; - UINT32 Reserved10:2; - /// - /// [Bit 34] Shared. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved11:29; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_IA32_MISC_ENABLE_REGISTER; - - -/** - Unique. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-3) - that points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP (at 40H). - - @param ECX MSR_CORE_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_CORE_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_CORE_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_CORE_LASTBRANCH_TOS 0x000001C9 - - -/** - Unique. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_CORE_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_LER_FROM_LIP); - @endcode - @note MSR_CORE_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_CORE_LER_FROM_LIP 0x000001DD - - -/** - Unique. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_CORE_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_LER_TO_LIP); - @endcode - @note MSR_CORE_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_CORE_LER_TO_LIP 0x000001DE - - -/** - Unique. - - @param ECX MSR_CORE_ROB_CR_BKUPTMPDR6 (0x000001E0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_ROB_CR_BKUPTMPDR6_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_ROB_CR_BKUPTMPDR6_REGISTER. - - Example usage - @code - MSR_CORE_ROB_CR_BKUPTMPDR6_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_ROB_CR_BKUPTMPDR6); - AsmWriteMsr64 (MSR_CORE_ROB_CR_BKUPTMPDR6, Msr.Uint64); - @endcode - @note MSR_CORE_ROB_CR_BKUPTMPDR6 is defined as ROB_CR_BKUPTMPDR6 in SDM. -**/ -#define MSR_CORE_ROB_CR_BKUPTMPDR6 0x000001E0 - -/** - MSR information returned for MSR index #MSR_CORE_ROB_CR_BKUPTMPDR6 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:2; - /// - /// [Bit 2] Fast Strings Enable bit. (Default, enabled). - /// - UINT32 FastStrings:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_ROB_CR_BKUPTMPDR6_REGISTER; - - -/** - Unique. - - @param ECX MSR_CORE_MTRRPHYSBASEn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRPHYSBASE0); - AsmWriteMsr64 (MSR_CORE_MTRRPHYSBASE0, Msr); - @endcode - @note MSR_CORE_MTRRPHYSBASE0 is defined as MTRRPHYSBASE0 in SDM. - MSR_CORE_MTRRPHYSBASE1 is defined as MTRRPHYSBASE1 in SDM. - MSR_CORE_MTRRPHYSBASE2 is defined as MTRRPHYSBASE2 in SDM. - MSR_CORE_MTRRPHYSBASE3 is defined as MTRRPHYSBASE3 in SDM. - MSR_CORE_MTRRPHYSBASE4 is defined as MTRRPHYSBASE4 in SDM. - MSR_CORE_MTRRPHYSBASE5 is defined as MTRRPHYSBASE5 in SDM. - MSR_CORE_MTRRPHYSMASK6 is defined as MTRRPHYSMASK6 in SDM. - MSR_CORE_MTRRPHYSMASK7 is defined as MTRRPHYSMASK7 in SDM. - @{ -**/ -#define MSR_CORE_MTRRPHYSBASE0 0x00000200 -#define MSR_CORE_MTRRPHYSBASE1 0x00000202 -#define MSR_CORE_MTRRPHYSBASE2 0x00000204 -#define MSR_CORE_MTRRPHYSBASE3 0x00000206 -#define MSR_CORE_MTRRPHYSBASE4 0x00000208 -#define MSR_CORE_MTRRPHYSBASE5 0x0000020A -#define MSR_CORE_MTRRPHYSMASK6 0x0000020D -#define MSR_CORE_MTRRPHYSMASK7 0x0000020F -/// @} - - -/** - Unique. - - @param ECX MSR_CORE_MTRRPHYSMASKn (0x00000201) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRPHYSMASK0); - AsmWriteMsr64 (MSR_CORE_MTRRPHYSMASK0, Msr); - @endcode - @note MSR_CORE_MTRRPHYSMASK0 is defined as MTRRPHYSMASK0 in SDM. - MSR_CORE_MTRRPHYSMASK1 is defined as MTRRPHYSMASK1 in SDM. - MSR_CORE_MTRRPHYSMASK2 is defined as MTRRPHYSMASK2 in SDM. - MSR_CORE_MTRRPHYSMASK3 is defined as MTRRPHYSMASK3 in SDM. - MSR_CORE_MTRRPHYSMASK4 is defined as MTRRPHYSMASK4 in SDM. - MSR_CORE_MTRRPHYSMASK5 is defined as MTRRPHYSMASK5 in SDM. - MSR_CORE_MTRRPHYSBASE6 is defined as MTRRPHYSBASE6 in SDM. - MSR_CORE_MTRRPHYSBASE7 is defined as MTRRPHYSBASE7 in SDM. - @{ -**/ -#define MSR_CORE_MTRRPHYSMASK0 0x00000201 -#define MSR_CORE_MTRRPHYSMASK1 0x00000203 -#define MSR_CORE_MTRRPHYSMASK2 0x00000205 -#define MSR_CORE_MTRRPHYSMASK3 0x00000207 -#define MSR_CORE_MTRRPHYSMASK4 0x00000209 -#define MSR_CORE_MTRRPHYSMASK5 0x0000020B -#define MSR_CORE_MTRRPHYSBASE6 0x0000020C -#define MSR_CORE_MTRRPHYSBASE7 0x0000020E -/// @} - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX64K_00000 (0x00000250) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX64K_00000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX64K_00000, Msr); - @endcode - @note MSR_CORE_MTRRFIX64K_00000 is defined as MTRRFIX64K_00000 in SDM. -**/ -#define MSR_CORE_MTRRFIX64K_00000 0x00000250 - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX16K_80000 (0x00000258) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX16K_80000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX16K_80000, Msr); - @endcode - @note MSR_CORE_MTRRFIX16K_80000 is defined as MTRRFIX16K_80000 in SDM. -**/ -#define MSR_CORE_MTRRFIX16K_80000 0x00000258 - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX16K_A0000 (0x00000259) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX16K_A0000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX16K_A0000, Msr); - @endcode - @note MSR_CORE_MTRRFIX16K_A0000 is defined as MTRRFIX16K_A0000 in SDM. -**/ -#define MSR_CORE_MTRRFIX16K_A0000 0x00000259 - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_C0000 (0x00000268) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_C0000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_C0000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_C0000 is defined as MTRRFIX4K_C0000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_C0000 0x00000268 - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_C8000 (0x00000269) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_C8000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_C8000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_C8000 is defined as MTRRFIX4K_C8000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_C8000 0x00000269 - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_D0000 (0x0000026A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_D0000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_D0000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_D0000 is defined as MTRRFIX4K_D0000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_D0000 0x0000026A - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_D8000 (0x0000026B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_D8000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_D8000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_D8000 is defined as MTRRFIX4K_D8000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_D8000 0x0000026B - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_E0000 (0x0000026C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_E0000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_E0000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_E0000 is defined as MTRRFIX4K_E0000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_E0000 0x0000026C - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_E8000 (0x0000026D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_E8000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_E8000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_E8000 is defined as MTRRFIX4K_E8000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_E8000 0x0000026D - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_F0000 (0x0000026E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_F0000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_F0000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_F0000 is defined as MTRRFIX4K_F0000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_F0000 0x0000026E - - -/** - Unique. - - @param ECX MSR_CORE_MTRRFIX4K_F8000 (0x0000026F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_F8000); - AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_F8000, Msr); - @endcode - @note MSR_CORE_MTRRFIX4K_F8000 is defined as MTRRFIX4K_F8000 in SDM. -**/ -#define MSR_CORE_MTRRFIX4K_F8000 0x0000026F - - -/** - Unique. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.". - - @param ECX MSR_CORE_MC4_CTL (0x0000040C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC4_CTL); - AsmWriteMsr64 (MSR_CORE_MC4_CTL, Msr); - @endcode - @note MSR_CORE_MC4_CTL is defined as MSR_MC4_CTL in SDM. -**/ -#define MSR_CORE_MC4_CTL 0x0000040C - - -/** - Unique. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.". - - @param ECX MSR_CORE_MC4_STATUS (0x0000040D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC4_STATUS); - AsmWriteMsr64 (MSR_CORE_MC4_STATUS, Msr); - @endcode - @note MSR_CORE_MC4_STATUS is defined as MSR_MC4_STATUS in SDM. -**/ -#define MSR_CORE_MC4_STATUS 0x0000040D - - -/** - Unique. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs." The MSR_MC4_ADDR - register is either not implemented or contains no address if the ADDRV flag - in the MSR_MC4_STATUS register is clear. When not implemented in the - processor, all reads and writes to this MSR will cause a general-protection - exception. - - @param ECX MSR_CORE_MC4_ADDR (0x0000040E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC4_ADDR); - AsmWriteMsr64 (MSR_CORE_MC4_ADDR, Msr); - @endcode - @note MSR_CORE_MC4_ADDR is defined as MSR_MC4_ADDR in SDM. -**/ -#define MSR_CORE_MC4_ADDR 0x0000040E - - -/** - Unique. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs." The MSR_MC3_ADDR - register is either not implemented or contains no address if the ADDRV flag - in the MSR_MC3_STATUS register is clear. When not implemented in the - processor, all reads and writes to this MSR will cause a general-protection - exception. - - @param ECX MSR_CORE_MC3_ADDR (0x00000412) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC3_ADDR); - AsmWriteMsr64 (MSR_CORE_MC3_ADDR, Msr); - @endcode - @note MSR_CORE_MC3_ADDR is defined as MSR_MC3_ADDR in SDM. -**/ -#define MSR_CORE_MC3_ADDR 0x00000412 - - -/** - Unique. - - @param ECX MSR_CORE_MC3_MISC (0x00000413) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC3_MISC); - AsmWriteMsr64 (MSR_CORE_MC3_MISC, Msr); - @endcode - @note MSR_CORE_MC3_MISC is defined as MSR_MC3_MISC in SDM. -**/ -#define MSR_CORE_MC3_MISC 0x00000413 - - -/** - Unique. - - @param ECX MSR_CORE_MC5_CTL (0x00000414) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC5_CTL); - AsmWriteMsr64 (MSR_CORE_MC5_CTL, Msr); - @endcode - @note MSR_CORE_MC5_CTL is defined as MSR_MC5_CTL in SDM. -**/ -#define MSR_CORE_MC5_CTL 0x00000414 - - -/** - Unique. - - @param ECX MSR_CORE_MC5_STATUS (0x00000415) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC5_STATUS); - AsmWriteMsr64 (MSR_CORE_MC5_STATUS, Msr); - @endcode - @note MSR_CORE_MC5_STATUS is defined as MSR_MC5_STATUS in SDM. -**/ -#define MSR_CORE_MC5_STATUS 0x00000415 - - -/** - Unique. - - @param ECX MSR_CORE_MC5_ADDR (0x00000416) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC5_ADDR); - AsmWriteMsr64 (MSR_CORE_MC5_ADDR, Msr); - @endcode - @note MSR_CORE_MC5_ADDR is defined as MSR_MC5_ADDR in SDM. -**/ -#define MSR_CORE_MC5_ADDR 0x00000416 - - -/** - Unique. - - @param ECX MSR_CORE_MC5_MISC (0x00000417) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_CORE_MC5_MISC); - AsmWriteMsr64 (MSR_CORE_MC5_MISC, Msr); - @endcode - @note MSR_CORE_MC5_MISC is defined as MSR_MC5_MISC in SDM. -**/ -#define MSR_CORE_MC5_MISC 0x00000417 - - -/** - Unique. See Table 35-2. - - @param ECX MSR_CORE_IA32_EFER (0xC0000080) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_CORE_IA32_EFER_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_CORE_IA32_EFER_REGISTER. - - Example usage - @code - MSR_CORE_IA32_EFER_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_EFER); - AsmWriteMsr64 (MSR_CORE_IA32_EFER, Msr.Uint64); - @endcode - @note MSR_CORE_IA32_EFER is defined as IA32_EFER in SDM. -**/ -#define MSR_CORE_IA32_EFER 0xC0000080 - -/** - MSR information returned for MSR index #MSR_CORE_IA32_EFER -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:11; - /// - /// [Bit 11] Execute Disable Bit Enable. - /// - UINT32 NXE:1; - UINT32 Reserved2:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_CORE_IA32_EFER_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/GoldmontMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/GoldmontMsr.h deleted file mode 100644 index 5730918ec..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/GoldmontMsr.h +++ /dev/null @@ -1,2531 +0,0 @@ -/** @file - MSR Definitions for Intel Atom processors based on the Goldmont microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.5. - -**/ - -#ifndef __GOLDMONT_MSR_H__ -#define __GOLDMONT_MSR_H__ - -#include - -/** - Is Intel Atom processors based on the Goldmont microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_GOLDMONT_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x5C \ - ) \ - ) - -/** - Core. Control Features in Intel 64Processor (R/W). - - @param ECX MSR_GOLDMONT_FEATURE_CONTROL (0x0000003A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_GOLDMONT_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_FEATURE_CONTROL is defined as IA32_FEATURE_CONTROL in SDM. -**/ -#define MSR_GOLDMONT_FEATURE_CONTROL 0x0000003A - -/** - MSR information returned for MSR index #MSR_GOLDMONT_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock bit (R/WL) - /// - UINT32 Lock:1; - /// - /// [Bit 1] Enable VMX inside SMX operation (R/WL) - /// - UINT32 EnableVmxInsideSmx:1; - /// - /// [Bit 2] Enable VMX outside SMX operation (R/WL) - /// - UINT32 EnableVmxOutsideSmx:1; - UINT32 Reserved1:5; - /// - /// [Bits 14:8] SENTER local function enables (R/WL) - /// - UINT32 SenterLocalFunctionEnables:7; - /// - /// [Bit 15] SENTER global functions enable (R/WL) - /// - UINT32 SenterGlobalEnable:1; - UINT32 Reserved2:2; - /// - /// [Bit 18] SGX global functions enable (R/WL) - /// - UINT32 SgxEnable:1; - UINT32 Reserved3:13; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_FEATURE_CONTROL_REGISTER; - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_GOLDMONT_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PLATFORM_INFO); - AsmWriteMsr64 (MSR_GOLDMONT_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_GOLDMONT_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - /// - /// [Bit 30] Package. Programmable TJ OFFSET (R/O) When set to 1, - /// indicates that MSR_TEMPERATURE_TARGET.[27:24] is valid and writable to - /// specify an temperature offset. - /// - UINT32 TJOFFSET:1; - UINT32 Reserved3:1; - UINT32 Reserved4:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved5:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PLATFORM_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. See http://biosbits.org. - - @param ECX MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type - MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type - MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power). for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 0000b: - /// No limit 0001b: C1 0010b: C3 0011b: C6 0100b: C7 0101b: C7S 0110b: C8 - /// 0111b: C9 1000b: C10. - /// - UINT32 Limit:4; - UINT32 Reserved1:6; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W) When set, will map - /// IO_read instructions sent to IO register specified by - /// MSR_PMG_IO_CAPTURE_BASE to MWAIT instructions. - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO) When set, lock bits 15:0 of this register - /// until next reset. - /// - UINT32 CFGLock:1; - UINT32 Reserved3:16; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Core. Enhanced SMM Capabilities (SMM-RO) Reports SMM capability Enhancement. - Accessible only while in SMM. - - @param ECX MSR_GOLDMONT_SMM_MCA_CAP (0x0000017D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_MCA_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_MCA_CAP_REGISTER. - - Example usage - @code - MSR_GOLDMONT_SMM_MCA_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_SMM_MCA_CAP); - AsmWriteMsr64 (MSR_GOLDMONT_SMM_MCA_CAP, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_SMM_MCA_CAP is defined as MSR_SMM_MCA_CAP in SDM. -**/ -#define MSR_GOLDMONT_SMM_MCA_CAP 0x0000017D - -/** - MSR information returned for MSR index #MSR_GOLDMONT_SMM_MCA_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:26; - /// - /// [Bit 58] SMM_Code_Access_Chk (SMM-RO) If set to 1 indicates that the - /// SMM code access restriction is supported and the - /// MSR_SMM_FEATURE_CONTROL is supported. - /// - UINT32 SMM_Code_Access_Chk:1; - /// - /// [Bit 59] Long_Flow_Indication (SMM-RO) If set to 1 indicates that the - /// SMM long flow indicator is supported and the MSR_SMM_DELAYED is - /// supported. - /// - UINT32 Long_Flow_Indication:1; - UINT32 Reserved3:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_SMM_MCA_CAP_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_GOLDMONT_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_GOLDMONT_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Package. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. Default value is 1. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Core. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:3; - /// - /// [Bit 11] Core. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Core. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - UINT32 Reserved4:3; - /// - /// [Bit 16] Package. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] Core. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved6:3; - /// - /// [Bit 22] Core. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Package. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] Core. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved9:3; - /// - /// [Bit 38] Package. Turbo Mode Disable (R/W) When set to 1 on processors - /// that support Intel Turbo Boost Technology, the turbo mode feature is - /// disabled and the IDA_Enable feature flag will be clear (CPUID.06H: - /// EAX[1]=0). When set to a 0 on processors that support IDA, CPUID.06H: - /// EAX[1] reports the processor's support of turbo mode is enabled. Note: - /// the power-on default value is used by BIOS to detect hardware support - /// of turbo mode. If power-on default value is 1, turbo mode is available - /// in the processor. If power-on default value is 0, turbo mode is not - /// available. - /// - UINT32 TurboModeDisable:1; - UINT32 Reserved10:25; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_MISC_ENABLE_REGISTER; - - -/** - Miscellaneous Feature Control (R/W). - - @param ECX MSR_GOLDMONT_MISC_FEATURE_CONTROL (0x000001A4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_MISC_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_MISC_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_MISC_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_MISC_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_GOLDMONT_MISC_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_MISC_FEATURE_CONTROL is defined as MSR_MISC_FEATURE_CONTROL in SDM. -**/ -#define MSR_GOLDMONT_MISC_FEATURE_CONTROL 0x000001A4 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_MISC_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. L2 Hardware Prefetcher Disable (R/W) If 1, disables the - /// L2 hardware prefetcher, which fetches additional lines of code or data - /// into the L2 cache. - /// - UINT32 L2HardwarePrefetcherDisable:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Core. DCU Hardware Prefetcher Disable (R/W) If 1, disables - /// the L1 data cache prefetcher, which fetches the next cache line into - /// L1 data cache. - /// - UINT32 DCUHardwarePrefetcherDisable:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_MISC_FEATURE_CONTROL_REGISTER; - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_GOLDMONT_MISC_PWR_MGMT (0x000001AA) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_MISC_PWR_MGMT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_MISC_PWR_MGMT_REGISTER. - - Example usage - @code - MSR_GOLDMONT_MISC_PWR_MGMT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_MISC_PWR_MGMT); - AsmWriteMsr64 (MSR_GOLDMONT_MISC_PWR_MGMT, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_MISC_PWR_MGMT is defined as MSR_MISC_PWR_MGMT in SDM. -**/ -#define MSR_GOLDMONT_MISC_PWR_MGMT 0x000001AA - -/** - MSR information returned for MSR index #MSR_GOLDMONT_MISC_PWR_MGMT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] EIST Hardware Coordination Disable (R/W) When 0, enables - /// hardware coordination of Enhanced Intel Speedstep Technology request - /// from processor cores; When 1, disables hardware coordination of - /// Enhanced Intel Speedstep Technology requests. - /// - UINT32 EISTHardwareCoordinationDisable:1; - UINT32 Reserved1:21; - /// - /// [Bit 22] Thermal Interrupt Coordination Enable (R/W) If set, then - /// thermal interrupt on one core is routed to all cores. - /// - UINT32 ThermalInterruptCoordinationEnable:1; - UINT32 Reserved2:9; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_MISC_PWR_MGMT_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode by Core Groups (RW) Specifies - Maximum Ratio Limit for each Core Group. Max ratio for groups with more - cores must decrease monotonically. For groups with less than 4 cores, the - max ratio must be 32 or less. For groups with 4-5 cores, the max ratio must - be 22 or less. For groups with more than 5 cores, the max ratio must be 16 - or less.. - - @param ECX MSR_GOLDMONT_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_GOLDMONT_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_TURBO_RATIO_LIMIT); - AsmWriteMsr64 (MSR_GOLDMONT_TURBO_RATIO_LIMIT, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_GOLDMONT_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_GOLDMONT_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for Active cores in Group 0 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 0 threshold. - /// - UINT32 MaxRatioLimitGroup0:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for Active cores in Group 1 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 1 threshold and greater than Group 0 threshold. - /// - UINT32 MaxRatioLimitGroup1:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for Active cores in Group 2 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 2 threshold and greater than Group 1 threshold. - /// - UINT32 MaxRatioLimitGroup2:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for Active cores in Group 3 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 3 threshold and greater than Group 2 threshold. - /// - UINT32 MaxRatioLimitGroup3:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for Active cores in Group 4 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 4 threshold and greater than Group 3 threshold. - /// - UINT32 MaxRatioLimitGroup4:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for Active cores in Group 5 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 5 threshold and greater than Group 4 threshold. - /// - UINT32 MaxRatioLimitGroup5:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for Active cores in Group 6 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 6 threshold and greater than Group 5 threshold. - /// - UINT32 MaxRatioLimitGroup6:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for Active cores in Group 7 - /// Maximum turbo ratio limit when number of active cores is less or equal - /// to Group 7 threshold and greater than Group 6 threshold. - /// - UINT32 MaxRatioLimitGroup7:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. Group Size of Active Cores for Turbo Mode Operation (RW) Writes of - 0 threshold is ignored. - - @param ECX MSR_GOLDMONT_TURBO_GROUP_CORECNT (0x000001AE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_GROUP_CORECNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_GROUP_CORECNT_REGISTER. - - Example usage - @code - MSR_GOLDMONT_TURBO_GROUP_CORECNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_TURBO_GROUP_CORECNT); - AsmWriteMsr64 (MSR_GOLDMONT_TURBO_GROUP_CORECNT, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_TURBO_GROUP_CORECNT is defined as MSR_TURBO_GROUP_CORECNT in SDM. -**/ -#define MSR_GOLDMONT_TURBO_GROUP_CORECNT 0x000001AE - -/** - MSR information returned for MSR index #MSR_GOLDMONT_TURBO_GROUP_CORECNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Group 0 Core Count Threshold Maximum number of - /// active cores to operate under Group 0 Max Turbo Ratio limit. - /// - UINT32 CoreCountThresholdGroup0:8; - /// - /// [Bits 15:8] Package. Group 1 Core Count Threshold Maximum number of - /// active cores to operate under Group 1 Max Turbo Ratio limit. Must be - /// greater than Group 0 Core Count. - /// - UINT32 CoreCountThresholdGroup1:8; - /// - /// [Bits 23:16] Package. Group 2 Core Count Threshold Maximum number of - /// active cores to operate under Group 2 Max Turbo Ratio limit. Must be - /// greater than Group 1 Core Count. - /// - UINT32 CoreCountThresholdGroup2:8; - /// - /// [Bits 31:24] Package. Group 3 Core Count Threshold Maximum number of - /// active cores to operate under Group 3 Max Turbo Ratio limit. Must be - /// greater than Group 2 Core Count. - /// - UINT32 CoreCountThresholdGroup3:8; - /// - /// [Bits 39:32] Package. Group 4 Core Count Threshold Maximum number of - /// active cores to operate under Group 4 Max Turbo Ratio limit. Must be - /// greater than Group 3 Core Count. - /// - UINT32 CoreCountThresholdGroup4:8; - /// - /// [Bits 47:40] Package. Group 5 Core Count Threshold Maximum number of - /// active cores to operate under Group 5 Max Turbo Ratio limit. Must be - /// greater than Group 4 Core Count. - /// - UINT32 CoreCountThresholdGroup5:8; - /// - /// [Bits 55:48] Package. Group 6 Core Count Threshold Maximum number of - /// active cores to operate under Group 6 Max Turbo Ratio limit. Must be - /// greater than Group 5 Core Count. - /// - UINT32 CoreCountThresholdGroup6:8; - /// - /// [Bits 63:56] Package. Group 7 Core Count Threshold Maximum number of - /// active cores to operate under Group 7 Max Turbo Ratio limit. Must be - /// greater than Group 6 Core Count and not less than the total number of - /// processor cores in the package. E.g. specify 255. - /// - UINT32 CoreCountThresholdGroup7:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_TURBO_GROUP_CORECNT_REGISTER; - - -/** - Core. Last Branch Record Filtering Select Register (R/W) See Section - 17.7.2, "Filtering of Last Branch Records.". - - @param ECX MSR_GOLDMONT_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LBR_SELECT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LBR_SELECT_REGISTER. - - Example usage - @code - MSR_GOLDMONT_LBR_SELECT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_LBR_SELECT); - AsmWriteMsr64 (MSR_GOLDMONT_LBR_SELECT, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_GOLDMONT_LBR_SELECT 0x000001C8 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_LBR_SELECT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CPL_EQ_0. - /// - UINT32 CPL_EQ_0:1; - /// - /// [Bit 1] CPL_NEQ_0. - /// - UINT32 CPL_NEQ_0:1; - /// - /// [Bit 2] JCC. - /// - UINT32 JCC:1; - /// - /// [Bit 3] NEAR_REL_CALL. - /// - UINT32 NEAR_REL_CALL:1; - /// - /// [Bit 4] NEAR_IND_CALL. - /// - UINT32 NEAR_IND_CALL:1; - /// - /// [Bit 5] NEAR_RET. - /// - UINT32 NEAR_RET:1; - /// - /// [Bit 6] NEAR_IND_JMP. - /// - UINT32 NEAR_IND_JMP:1; - /// - /// [Bit 7] NEAR_REL_JMP. - /// - UINT32 NEAR_REL_JMP:1; - /// - /// [Bit 8] FAR_BRANCH. - /// - UINT32 FAR_BRANCH:1; - /// - /// [Bit 9] EN_CALL_STACK. - /// - UINT32 EN_CALL_STACK:1; - UINT32 Reserved1:22; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_LBR_SELECT_REGISTER; - - -/** - Core. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-4) that - points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP. - - @param ECX MSR_GOLDMONT_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_GOLDMONT_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_GOLDMONT_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_GOLDMONT_LASTBRANCH_TOS 0x000001C9 - - -/** - Core. Power Control Register. See http://biosbits.org. - - @param ECX MSR_GOLDMONT_POWER_CTL (0x000001FC) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_POWER_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_POWER_CTL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_POWER_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_POWER_CTL); - AsmWriteMsr64 (MSR_GOLDMONT_POWER_CTL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_POWER_CTL is defined as MSR_POWER_CTL in SDM. -**/ -#define MSR_GOLDMONT_POWER_CTL 0x000001FC - -/** - MSR information returned for MSR index #MSR_GOLDMONT_POWER_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Package. C1E Enable (R/W) When set to '1', will enable the - /// CPU to switch to the Minimum Enhanced Intel SpeedStep Technology - /// operating point when all execution cores enter MWAIT (C1). - /// - UINT32 C1EEnable:1; - UINT32 Reserved2:30; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_POWER_CTL_REGISTER; - - -/** - Package. Lower 64 Bit OwnerEpoch Component of SGX Key (RO). Low 64 bits of - an 128-bit external entropy value for key derivation of an enclave. - - @param ECX MSR_GOLDMONT_SGXOWNER0 (0x00000300) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_SGXOWNER0); - @endcode - @note MSR_GOLDMONT_SGXOWNER0 is defined as MSR_SGXOWNER0 in SDM. -**/ -#define MSR_GOLDMONT_SGXOWNER0 0x00000300 - - -/** - Package. Upper 64 Bit OwnerEpoch Component of SGX Key (RO). Upper 64 bits of - an 128-bit external entropy value for key derivation of an enclave. - - @param ECX MSR_GOLDMONT_SGXOWNER1 (0x00000301) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_SGXOWNER1); - @endcode - @note MSR_GOLDMONT_SGXOWNER1 is defined as MSR_SGXOWNER1 in SDM. -**/ -#define MSR_GOLDMONT_SGXOWNER1 0x00000301 - - -/** - Core. See Table 35-2. See Section 18.2.4, "Architectural Performance - Monitoring Version 4.". - - @param ECX MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET is defined as IA32_PERF_GLOBAL_STATUS_RESET in SDM. -**/ -#define MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET 0x00000390 - -/** - MSR information returned for MSR index - #MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Set 1 to clear Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Set 1 to clear Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Set 1 to clear Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Set 1 to clear Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Set 1 to clear Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Set 1 to clear Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Set 1 to clear Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Set 1 to clear Trace_ToPA_PMI. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] Set 1 to clear LBR_Frz. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Set 1 to clear CTR_Frz. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Set 1 to clear ASCI. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Set 1 to clear Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Set 1 to clear Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - /// - /// [Bit 63] Set 1 to clear CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER; - - -/** - Core. See Table 35-2. See Section 18.2.4, "Architectural Performance - Monitoring Version 4.". - - @param ECX MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET (0x00000391) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET is defined as IA32_PERF_GLOBAL_STATUS_SET in SDM. -**/ -#define MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET 0x00000391 - -/** - MSR information returned for MSR index - #MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Set 1 to cause Ovf_PMC0 = 1. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Set 1 to cause Ovf_PMC1 = 1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Set 1 to cause Ovf_PMC2 = 1. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Set 1 to cause Ovf_PMC3 = 1. - /// - UINT32 Ovf_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Set 1 to cause Ovf_FixedCtr0 = 1. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Set 1 to cause Ovf_FixedCtr1 = 1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Set 1 to cause Ovf_FixedCtr2 = 1. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Set 1 to cause Trace_ToPA_PMI = 1. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] Set 1 to cause LBR_Frz = 1. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Set 1 to cause CTR_Frz = 1. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Set 1 to cause ASCI = 1. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Set 1 to cause Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Set 1 to cause Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - UINT32 Reserved4:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_PERF_GLOBAL_STATUS_SET_REGISTER; - - -/** - Core. See Table 35-2. See Section 18.4.4, "Processor Event Based Sampling - (PEBS).". - - @param ECX MSR_GOLDMONT_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PEBS_ENABLE); - AsmWriteMsr64 (MSR_GOLDMONT_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_GOLDMONT_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS trigger and recording for the programmed event - /// (precise or otherwise) on IA32_PMC0. (R/W). - /// - UINT32 Enable:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PEBS_ENABLE_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C3 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_GOLDMONT_PKG_C3_RESIDENCY (0x000003F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_C3_RESIDENCY); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_C3_RESIDENCY, Msr); - @endcode - @note MSR_GOLDMONT_PKG_C3_RESIDENCY is defined as MSR_PKG_C3_RESIDENCY in SDM. -**/ -#define MSR_GOLDMONT_PKG_C3_RESIDENCY 0x000003F8 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C6 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C6 states. Count at the same frequency as the TSC. - - @param ECX MSR_GOLDMONT_PKG_C6_RESIDENCY (0x000003F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_GOLDMONT_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_GOLDMONT_PKG_C6_RESIDENCY 0x000003F9 - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C3 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_GOLDMONT_CORE_C3_RESIDENCY (0x000003FC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_CORE_C3_RESIDENCY); - AsmWriteMsr64 (MSR_GOLDMONT_CORE_C3_RESIDENCY, Msr); - @endcode - @note MSR_GOLDMONT_CORE_C3_RESIDENCY is defined as MSR_CORE_C3_RESIDENCY in SDM. -**/ -#define MSR_GOLDMONT_CORE_C3_RESIDENCY 0x000003FC - - -/** - Package. Enhanced SMM Feature Control (SMM-RW) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_GOLDMONT_SMM_FEATURE_CONTROL (0x000004E0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_SMM_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_SMM_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_GOLDMONT_SMM_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_SMM_FEATURE_CONTROL is defined as MSR_SMM_FEATURE_CONTROL in SDM. -**/ -#define MSR_GOLDMONT_SMM_FEATURE_CONTROL 0x000004E0 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_SMM_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock (SMM-RWO) When set to '1' locks this register from - /// further changes. - /// - UINT32 Lock:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] SMM_Code_Chk_En (SMM-RW) This control bit is available only if - /// MSR_SMM_MCA_CAP[58] == 1. When set to '0' (default) none of the - /// logical processors are prevented from executing SMM code outside the - /// ranges defined by the SMRR. When set to '1' any logical processor in - /// the package that attempts to execute SMM code not within the ranges - /// defined by the SMRR will assert an unrecoverable MCE. - /// - UINT32 SMM_Code_Chk_En:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_SMM_FEATURE_CONTROL_REGISTER; - - -/** - Package. SMM Delayed (SMM-RO) Reports the interruptible state of all logical - processors in the package. Available only while in SMM and - MSR_SMM_MCA_CAP[LONG_FLOW_INDICATION] == 1. - - @param ECX MSR_GOLDMONT_SMM_DELAYED (0x000004E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_DELAYED_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_DELAYED_REGISTER. - - Example usage - @code - MSR_GOLDMONT_SMM_DELAYED_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_SMM_DELAYED); - AsmWriteMsr64 (MSR_GOLDMONT_SMM_DELAYED, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_SMM_DELAYED is defined as MSR_SMM_DELAYED in SDM. -**/ -#define MSR_GOLDMONT_SMM_DELAYED 0x000004E2 - - -/** - Package. SMM Blocked (SMM-RO) Reports the blocked state of all logical - processors in the package. Available only while in SMM. - - @param ECX MSR_GOLDMONT_SMM_BLOCKED (0x000004E3) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_BLOCKED_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_SMM_BLOCKED_REGISTER. - - Example usage - @code - MSR_GOLDMONT_SMM_BLOCKED_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_SMM_BLOCKED); - AsmWriteMsr64 (MSR_GOLDMONT_SMM_BLOCKED, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_SMM_BLOCKED is defined as MSR_SMM_BLOCKED in SDM. -**/ -#define MSR_GOLDMONT_SMM_BLOCKED 0x000004E3 - - -/** - Core. Trace Control Register (R/W). - - @param ECX MSR_GOLDMONT_IA32_RTIT_CTL (0x00000570) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_RTIT_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_RTIT_CTL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_RTIT_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_RTIT_CTL); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_RTIT_CTL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_RTIT_CTL is defined as IA32_RTIT_CTL in SDM. -**/ -#define MSR_IA32_RTIT_CTL 0x00000570 - -/** - MSR information returned for MSR index #MSR_IA32_RTIT_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] TraceEn. - /// - UINT32 TraceEn:1; - /// - /// [Bit 1] CYCEn. - /// - UINT32 CYCEn:1; - /// - /// [Bit 2] OS. - /// - UINT32 OS:1; - /// - /// [Bit 3] User. - /// - UINT32 User:1; - UINT32 Reserved1:3; - /// - /// [Bit 7] CR3 filter. - /// - UINT32 CR3:1; - /// - /// [Bit 8] ToPA. Writing 0 will #GP if also setting TraceEn. - /// - UINT32 ToPA:1; - /// - /// [Bit 9] MTCEn. - /// - UINT32 MTCEn:1; - /// - /// [Bit 10] TSCEn. - /// - UINT32 TSCEn:1; - /// - /// [Bit 11] DisRETC. - /// - UINT32 DisRETC:1; - UINT32 Reserved2:1; - /// - /// [Bit 13] BranchEn. - /// - UINT32 BranchEn:1; - /// - /// [Bits 17:14] MTCFreq. - /// - UINT32 MTCFreq:4; - UINT32 Reserved3:1; - /// - /// [Bits 22:19] CYCThresh. - /// - UINT32 CYCThresh:4; - UINT32 Reserved4:1; - /// - /// [Bits 27:24] PSBFreq. - /// - UINT32 PSBFreq:4; - UINT32 Reserved5:4; - /// - /// [Bits 35:32] ADDR0_CFG. - /// - UINT32 ADDR0_CFG:4; - /// - /// [Bits 39:36] ADDR1_CFG. - /// - UINT32 ADDR1_CFG:4; - UINT32 Reserved6:24; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_RTIT_CTL_REGISTER; - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O) See Section 14.9.1, - "RAPL Interfaces.". - - @param ECX MSR_GOLDMONT_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_GOLDMONT_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_RAPL_POWER_UNIT); - @endcode - @note MSR_GOLDMONT_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_GOLDMONT_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Power Units. Power related information (in Watts) is in - /// unit of, 1W/2^PU; where PU is an unsigned integer represented by bits - /// 3:0. Default value is 1000b, indicating power unit is in 3.9 - /// milliWatts increment. - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Energy Status Units. Energy related information (in - /// Joules) is in unit of, 1Joule/ (2^ESU); where ESU is an unsigned - /// integer represented by bits 12:8. Default value is 01110b, indicating - /// energy unit is in 61 microJoules. - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Time Unit. Time related information (in seconds) is in - /// unit of, 1S/2^TU; where TU is an unsigned integer represented by bits - /// 19:16. Default value is 1010b, indicating power unit is in 0.977 - /// millisecond. - /// - UINT32 TimeUnit:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. Package C3 Interrupt Response Limit (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. - - @param ECX MSR_GOLDMONT_PKGC3_IRTL (0x0000060A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC3_IRTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC3_IRTL_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PKGC3_IRTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PKGC3_IRTL); - AsmWriteMsr64 (MSR_GOLDMONT_PKGC3_IRTL, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PKGC3_IRTL is defined as MSR_PKGC3_IRTL in SDM. -**/ -#define MSR_GOLDMONT_PKGC3_IRTL 0x0000060A - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PKGC3_IRTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C3 state. - /// - UINT32 InterruptResponseTimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. See Table 35-18 for - /// supported time unit encodings. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PKGC3_IRTL_REGISTER; - - -/** - Package. Package C6/C7S Interrupt Response Limit 1 (R/W) This MSR defines - the interrupt response time limit used by the processor to manage transition - to package C6 or C7S state. Note: C-state values are processor specific - C-state code names, unrelated to MWAIT extension C-state parameters or ACPI - CStates. - - @param ECX MSR_GOLDMONT_PKGC_IRTL1 (0x0000060B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC_IRTL1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC_IRTL1_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PKGC_IRTL1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PKGC_IRTL1); - AsmWriteMsr64 (MSR_GOLDMONT_PKGC_IRTL1, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PKGC_IRTL1 is defined as MSR_PKGC_IRTL1 in SDM. -**/ -#define MSR_GOLDMONT_PKGC_IRTL1 0x0000060B - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PKGC_IRTL1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C6 or C7S state. - /// - UINT32 InterruptResponseTimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. See Table 35-18 for - /// supported time unit encodings. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PKGC_IRTL1_REGISTER; - - -/** - Package. Package C7 Interrupt Response Limit 2 (R/W) This MSR defines the - interrupt response time limit used by the processor to manage transition to - package C7 state. Note: C-state values are processor specific C-state code - names, unrelated to MWAIT extension C-state parameters or ACPI CStates. - - @param ECX MSR_GOLDMONT_PKGC_IRTL2 (0x0000060C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC_IRTL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKGC_IRTL2_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PKGC_IRTL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PKGC_IRTL2); - AsmWriteMsr64 (MSR_GOLDMONT_PKGC_IRTL2, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PKGC_IRTL2 is defined as MSR_PKGC_IRTL2 in SDM. -**/ -#define MSR_GOLDMONT_PKGC_IRTL2 0x0000060C - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PKGC_IRTL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C7 state. - /// - UINT32 InterruptResponseTimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. See Table 35-18 for - /// supported time unit encodings. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PKGC_IRTL2_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C2 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C2 states. Count at the same frequency as the TSC. - - @param ECX MSR_GOLDMONT_PKG_C2_RESIDENCY (0x0000060D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_C2_RESIDENCY); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_C2_RESIDENCY, Msr); - @endcode - @note MSR_GOLDMONT_PKG_C2_RESIDENCY is defined as MSR_PKG_C2_RESIDENCY in SDM. -**/ -#define MSR_GOLDMONT_PKG_C2_RESIDENCY 0x0000060D - - -/** - Package. PKG RAPL Power Limit Control (R/W) See Section 14.9.3, "Package - RAPL Domain.". - - @param ECX MSR_GOLDMONT_PKG_POWER_LIMIT (0x00000610) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_POWER_LIMIT); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_POWER_LIMIT, Msr); - @endcode - @note MSR_GOLDMONT_PKG_POWER_LIMIT is defined as MSR_PKG_POWER_LIMIT in SDM. -**/ -#define MSR_GOLDMONT_PKG_POWER_LIMIT 0x00000610 - - -/** - Package. PKG Energy Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_GOLDMONT_PKG_ENERGY_STATUS (0x00000611) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_ENERGY_STATUS); - @endcode - @note MSR_GOLDMONT_PKG_ENERGY_STATUS is defined as MSR_PKG_ENERGY_STATUS in SDM. -**/ -#define MSR_GOLDMONT_PKG_ENERGY_STATUS 0x00000611 - - -/** - Package. PKG Perf Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_GOLDMONT_PKG_PERF_STATUS (0x00000613) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_PERF_STATUS); - @endcode - @note MSR_GOLDMONT_PKG_PERF_STATUS is defined as MSR_PKG_PERF_STATUS in SDM. -**/ -#define MSR_GOLDMONT_PKG_PERF_STATUS 0x00000613 - - -/** - Package. PKG RAPL Parameters (R/W). - - @param ECX MSR_GOLDMONT_PKG_POWER_INFO (0x00000614) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKG_POWER_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_PKG_POWER_INFO_REGISTER. - - Example usage - @code - MSR_GOLDMONT_PKG_POWER_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_PKG_POWER_INFO); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_POWER_INFO, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_PKG_POWER_INFO is defined as MSR_PKG_POWER_INFO in SDM. -**/ -#define MSR_GOLDMONT_PKG_POWER_INFO 0x00000614 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_PKG_POWER_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Thermal Spec Power (R/W) See Section 14.9.3, "Package - /// RAPL Domain.". - /// - UINT32 ThermalSpecPower:15; - UINT32 Reserved1:1; - /// - /// [Bits 30:16] Minimum Power (R/W) See Section 14.9.3, "Package RAPL - /// Domain.". - /// - UINT32 MinimumPower:15; - UINT32 Reserved2:1; - /// - /// [Bits 46:32] Maximum Power (R/W) See Section 14.9.3, "Package RAPL - /// Domain.". - /// - UINT32 MaximumPower:15; - UINT32 Reserved3:1; - /// - /// [Bits 54:48] Maximum Time Window (R/W) Specified by 2^Y * (1.0 + - /// Z/4.0) * Time_Unit, where "Y" is the unsigned integer value - /// represented. by bits 52:48, "Z" is an unsigned integer represented by - /// bits 54:53. "Time_Unit" is specified by the "Time Units" field of - /// MSR_RAPL_POWER_UNIT. - /// - UINT32 MaximumTimeWindow:7; - UINT32 Reserved4:9; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_PKG_POWER_INFO_REGISTER; - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_GOLDMONT_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_GOLDMONT_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_GOLDMONT_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_GOLDMONT_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_GOLDMONT_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_DRAM_ENERGY_STATUS); - @endcode - @note MSR_GOLDMONT_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_GOLDMONT_DRAM_ENERGY_STATUS 0x00000619 - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_GOLDMONT_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_DRAM_PERF_STATUS); - @endcode - @note MSR_GOLDMONT_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_GOLDMONT_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_GOLDMONT_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_GOLDMONT_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_GOLDMONT_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_GOLDMONT_DRAM_POWER_INFO 0x0000061C - - -/** - Package. Note: C-state values are processor specific C-state code names,. - Package C10 Residency Counter. (R/O) Value since last reset that the entire - SOC is in an S0i3 state. Count at the same frequency as the TSC. - - @param ECX MSR_GOLDMONT_PKG_C10_RESIDENCY (0x00000632) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PKG_C10_RESIDENCY); - AsmWriteMsr64 (MSR_GOLDMONT_PKG_C10_RESIDENCY, Msr); - @endcode - @note MSR_GOLDMONT_PKG_C10_RESIDENCY is defined as MSR_PKG_C10_RESIDENCY in SDM. -**/ -#define MSR_GOLDMONT_PKG_C10_RESIDENCY 0x00000632 - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_GOLDMONT_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PP0_ENERGY_STATUS); - @endcode - @note MSR_GOLDMONT_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_GOLDMONT_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. PP1 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_GOLDMONT_PP1_ENERGY_STATUS (0x00000641) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_GOLDMONT_PP1_ENERGY_STATUS); - @endcode - @note MSR_GOLDMONT_PP1_ENERGY_STATUS is defined as MSR_PP1_ENERGY_STATUS in SDM. -**/ -#define MSR_GOLDMONT_PP1_ENERGY_STATUS 0x00000641 - - -/** - Package. ConfigTDP Control (R/W). - - @param ECX MSR_GOLDMONT_TURBO_ACTIVATION_RATIO (0x0000064C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_ACTIVATION_RATIO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_TURBO_ACTIVATION_RATIO_REGISTER. - - Example usage - @code - MSR_GOLDMONT_TURBO_ACTIVATION_RATIO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_TURBO_ACTIVATION_RATIO); - AsmWriteMsr64 (MSR_GOLDMONT_TURBO_ACTIVATION_RATIO, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_TURBO_ACTIVATION_RATIO is defined as MSR_TURBO_ACTIVATION_RATIO in SDM. -**/ -#define MSR_GOLDMONT_TURBO_ACTIVATION_RATIO 0x0000064C - -/** - MSR information returned for MSR index #MSR_GOLDMONT_TURBO_ACTIVATION_RATIO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] MAX_NON_TURBO_RATIO (RW/L) System BIOS can program this - /// field. - /// - UINT32 MAX_NON_TURBO_RATIO:8; - UINT32 Reserved1:23; - /// - /// [Bit 31] TURBO_ACTIVATION_RATIO_Lock (RW/L) When this bit is set, the - /// content of this register is locked until a reset. - /// - UINT32 TURBO_ACTIVATION_RATIO_Lock:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_TURBO_ACTIVATION_RATIO_REGISTER; - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS (0x0000064F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS 0x0000064F - -/** - MSR information returned for MSR index #MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, processor core frequency is - /// reduced below the operating system request due to assertion of - /// external PROCHOT. - /// - UINT32 PROCHOTStatus:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - /// - /// [Bit 2] Package-Level Power Limiting PL1 Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL1. - /// - UINT32 PL1Status:1; - /// - /// [Bit 3] Package-Level PL2 Power Limiting Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL2. - /// - UINT32 PL2Status:1; - UINT32 Reserved1:5; - /// - /// [Bit 9] Core Power Limiting Status (R0) When set, frequency is reduced - /// below the operating system request due to domain-level power limiting. - /// - UINT32 PowerLimitingStatus:1; - /// - /// [Bit 10] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - /// - /// [Bit 11] Max Turbo Limit Status (R0) When set, frequency is reduced - /// below the operating system request due to multi-core turbo limits. - /// - UINT32 MaxTurboLimitStatus:1; - /// - /// [Bit 12] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - /// - /// [Bit 13] Turbo Transition Attenuation Status (R0) When set, frequency - /// is reduced below the operating system request due to Turbo transition - /// attenuation. This prevents performance degradation due to frequent - /// operating ratio changes. - /// - UINT32 TurboTransitionAttenuationStatus:1; - /// - /// [Bit 14] Maximum Efficiency Frequency Status (R0) When set, frequency - /// is reduced below the maximum efficiency frequency. - /// - UINT32 MaximumEfficiencyFrequencyStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - /// - /// [Bit 18] Package-Level PL1 Power Limiting Log When set, indicates - /// that the Package Level PL1 Power Limiting Status bit has asserted - /// since the log bit was last cleared. This log bit will remain set until - /// cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 19] Package-Level PL2 Power Limiting Log When set, indicates that - /// the Package Level PL2 Power Limiting Status bit has asserted since the - /// log bit was last cleared. This log bit will remain set until cleared - /// by software writing 0. - /// - UINT32 PL2Log:1; - UINT32 Reserved3:5; - /// - /// [Bit 25] Core Power Limiting Log When set, indicates that the Core - /// Power Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CorePowerLimitingLog:1; - /// - /// [Bit 26] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - /// - /// [Bit 27] Max Turbo Limit Log When set, indicates that the Max Turbo - /// Limit Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MaxTurboLimitLog:1; - /// - /// [Bit 28] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - /// - /// [Bit 29] Turbo Transition Attenuation Log When set, indicates that the - /// Turbo Transition Attenuation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 TurboTransitionAttenuationLog:1; - /// - /// [Bit 30] Maximum Efficiency Frequency Log When set, indicates that - /// the Maximum Efficiency Frequency Status bit has asserted since the log - /// bit was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 MaximumEfficiencyFrequencyLog:1; - UINT32 Reserved4:1; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_CORE_PERF_LIMIT_REASONS_REGISTER; - - -/** - Core. Last Branch Record n From IP (R/W) One of 32 pairs of last branch - record registers on the last branch record stack. The From_IP part of the - stack contains pointers to the source instruction . See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.6 and record format in Section - 17.4.8.1. - - @param ECX MSR_GOLDMONT_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LASTBRANCH_FROM_IP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LASTBRANCH_FROM_IP_REGISTER. - - Example usage - @code - MSR_GOLDMONT_LASTBRANCH_FROM_IP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_LASTBRANCH_n_FROM_IP); - AsmWriteMsr64 (MSR_GOLDMONT_LASTBRANCH_n_FROM_IP, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_8_FROM_IP is defined as MSR_LASTBRANCH_8_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_9_FROM_IP is defined as MSR_LASTBRANCH_9_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_10_FROM_IP is defined as MSR_LASTBRANCH_10_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_11_FROM_IP is defined as MSR_LASTBRANCH_11_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_12_FROM_IP is defined as MSR_LASTBRANCH_12_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_13_FROM_IP is defined as MSR_LASTBRANCH_13_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_14_FROM_IP is defined as MSR_LASTBRANCH_14_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_15_FROM_IP is defined as MSR_LASTBRANCH_15_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_16_FROM_IP is defined as MSR_LASTBRANCH_16_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_17_FROM_IP is defined as MSR_LASTBRANCH_17_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_18_FROM_IP is defined as MSR_LASTBRANCH_18_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_19_FROM_IP is defined as MSR_LASTBRANCH_19_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_20_FROM_IP is defined as MSR_LASTBRANCH_20_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_21_FROM_IP is defined as MSR_LASTBRANCH_21_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_22_FROM_IP is defined as MSR_LASTBRANCH_22_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_23_FROM_IP is defined as MSR_LASTBRANCH_23_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_24_FROM_IP is defined as MSR_LASTBRANCH_24_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_25_FROM_IP is defined as MSR_LASTBRANCH_25_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_26_FROM_IP is defined as MSR_LASTBRANCH_26_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_27_FROM_IP is defined as MSR_LASTBRANCH_27_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_28_FROM_IP is defined as MSR_LASTBRANCH_28_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_29_FROM_IP is defined as MSR_LASTBRANCH_29_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_30_FROM_IP is defined as MSR_LASTBRANCH_30_FROM_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_31_FROM_IP is defined as MSR_LASTBRANCH_31_FROM_IP in SDM. - @{ -**/ -#define MSR_GOLDMONT_LASTBRANCH_0_FROM_IP 0x00000680 -#define MSR_GOLDMONT_LASTBRANCH_1_FROM_IP 0x00000681 -#define MSR_GOLDMONT_LASTBRANCH_2_FROM_IP 0x00000682 -#define MSR_GOLDMONT_LASTBRANCH_3_FROM_IP 0x00000683 -#define MSR_GOLDMONT_LASTBRANCH_4_FROM_IP 0x00000684 -#define MSR_GOLDMONT_LASTBRANCH_5_FROM_IP 0x00000685 -#define MSR_GOLDMONT_LASTBRANCH_6_FROM_IP 0x00000686 -#define MSR_GOLDMONT_LASTBRANCH_7_FROM_IP 0x00000687 -#define MSR_GOLDMONT_LASTBRANCH_8_FROM_IP 0x00000688 -#define MSR_GOLDMONT_LASTBRANCH_9_FROM_IP 0x00000689 -#define MSR_GOLDMONT_LASTBRANCH_10_FROM_IP 0x0000068A -#define MSR_GOLDMONT_LASTBRANCH_11_FROM_IP 0x0000068B -#define MSR_GOLDMONT_LASTBRANCH_12_FROM_IP 0x0000068C -#define MSR_GOLDMONT_LASTBRANCH_13_FROM_IP 0x0000068D -#define MSR_GOLDMONT_LASTBRANCH_14_FROM_IP 0x0000068E -#define MSR_GOLDMONT_LASTBRANCH_15_FROM_IP 0x0000068F -#define MSR_GOLDMONT_LASTBRANCH_16_FROM_IP 0x00000690 -#define MSR_GOLDMONT_LASTBRANCH_17_FROM_IP 0x00000691 -#define MSR_GOLDMONT_LASTBRANCH_18_FROM_IP 0x00000692 -#define MSR_GOLDMONT_LASTBRANCH_19_FROM_IP 0x00000693 -#define MSR_GOLDMONT_LASTBRANCH_20_FROM_IP 0x00000694 -#define MSR_GOLDMONT_LASTBRANCH_21_FROM_IP 0x00000695 -#define MSR_GOLDMONT_LASTBRANCH_22_FROM_IP 0x00000696 -#define MSR_GOLDMONT_LASTBRANCH_23_FROM_IP 0x00000697 -#define MSR_GOLDMONT_LASTBRANCH_24_FROM_IP 0x00000698 -#define MSR_GOLDMONT_LASTBRANCH_25_FROM_IP 0x00000699 -#define MSR_GOLDMONT_LASTBRANCH_26_FROM_IP 0x0000069A -#define MSR_GOLDMONT_LASTBRANCH_27_FROM_IP 0x0000069B -#define MSR_GOLDMONT_LASTBRANCH_28_FROM_IP 0x0000069C -#define MSR_GOLDMONT_LASTBRANCH_29_FROM_IP 0x0000069D -#define MSR_GOLDMONT_LASTBRANCH_30_FROM_IP 0x0000069E -#define MSR_GOLDMONT_LASTBRANCH_31_FROM_IP 0x0000069F -/// @} - -/** - MSR information returned for MSR indexes #MSR_GOLDMONT_LASTBRANCH_0_FROM_IP - to #MSR_GOLDMONT_LASTBRANCH_31_FROM_IP. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 31:0] From Linear Address (R/W). - /// - UINT32 FromLinearAddress:32; - /// - /// [Bit 47:32] From Linear Address (R/W). - /// - UINT32 FromLinearAddressHi:16; - /// - /// [Bits 62:48] Signed extension of bits 47:0. - /// - UINT32 SignedExtension:15; - /// - /// [Bit 63] Mispred. - /// - UINT32 Mispred:1; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_LASTBRANCH_FROM_IP_REGISTER; - - -/** - Core. Last Branch Record n To IP (R/W) One of 32 pairs of last branch record - registers on the last branch record stack. The To_IP part of the stack - contains pointers to the Destination instruction and elapsed cycles from - last LBR update. See also: - Section 17.6. - - @param ECX MSR_GOLDMONT_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LASTBRANCH_TO_IP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_LASTBRANCH_TO_IP_REGISTER. - - Example usage - @code - MSR_GOLDMONT_LASTBRANCH_TO_IP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_GOLDMONT_LASTBRANCH_0_TO_IP, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_8_TO_IP is defined as MSR_LASTBRANCH_8_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_9_TO_IP is defined as MSR_LASTBRANCH_9_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_10_TO_IP is defined as MSR_LASTBRANCH_10_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_11_TO_IP is defined as MSR_LASTBRANCH_11_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_12_TO_IP is defined as MSR_LASTBRANCH_12_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_13_TO_IP is defined as MSR_LASTBRANCH_13_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_14_TO_IP is defined as MSR_LASTBRANCH_14_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_15_TO_IP is defined as MSR_LASTBRANCH_15_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_16_TO_IP is defined as MSR_LASTBRANCH_16_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_17_TO_IP is defined as MSR_LASTBRANCH_17_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_18_TO_IP is defined as MSR_LASTBRANCH_18_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_19_TO_IP is defined as MSR_LASTBRANCH_19_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_20_TO_IP is defined as MSR_LASTBRANCH_20_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_21_TO_IP is defined as MSR_LASTBRANCH_21_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_22_TO_IP is defined as MSR_LASTBRANCH_22_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_23_TO_IP is defined as MSR_LASTBRANCH_23_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_24_TO_IP is defined as MSR_LASTBRANCH_24_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_25_TO_IP is defined as MSR_LASTBRANCH_25_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_26_TO_IP is defined as MSR_LASTBRANCH_26_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_27_TO_IP is defined as MSR_LASTBRANCH_27_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_28_TO_IP is defined as MSR_LASTBRANCH_28_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_29_TO_IP is defined as MSR_LASTBRANCH_29_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_30_TO_IP is defined as MSR_LASTBRANCH_30_TO_IP in SDM. - MSR_GOLDMONT_LASTBRANCH_31_TO_IP is defined as MSR_LASTBRANCH_31_TO_IP in SDM. - @{ -**/ -#define MSR_GOLDMONT_LASTBRANCH_0_TO_IP 0x000006C0 -#define MSR_GOLDMONT_LASTBRANCH_1_TO_IP 0x000006C1 -#define MSR_GOLDMONT_LASTBRANCH_2_TO_IP 0x000006C2 -#define MSR_GOLDMONT_LASTBRANCH_3_TO_IP 0x000006C3 -#define MSR_GOLDMONT_LASTBRANCH_4_TO_IP 0x000006C4 -#define MSR_GOLDMONT_LASTBRANCH_5_TO_IP 0x000006C5 -#define MSR_GOLDMONT_LASTBRANCH_6_TO_IP 0x000006C6 -#define MSR_GOLDMONT_LASTBRANCH_7_TO_IP 0x000006C7 -#define MSR_GOLDMONT_LASTBRANCH_8_TO_IP 0x000006C8 -#define MSR_GOLDMONT_LASTBRANCH_9_TO_IP 0x000006C9 -#define MSR_GOLDMONT_LASTBRANCH_10_TO_IP 0x000006CA -#define MSR_GOLDMONT_LASTBRANCH_11_TO_IP 0x000006CB -#define MSR_GOLDMONT_LASTBRANCH_12_TO_IP 0x000006CC -#define MSR_GOLDMONT_LASTBRANCH_13_TO_IP 0x000006CD -#define MSR_GOLDMONT_LASTBRANCH_14_TO_IP 0x000006CE -#define MSR_GOLDMONT_LASTBRANCH_15_TO_IP 0x000006CF -#define MSR_GOLDMONT_LASTBRANCH_16_TO_IP 0x000006D0 -#define MSR_GOLDMONT_LASTBRANCH_17_TO_IP 0x000006D1 -#define MSR_GOLDMONT_LASTBRANCH_18_TO_IP 0x000006D2 -#define MSR_GOLDMONT_LASTBRANCH_19_TO_IP 0x000006D3 -#define MSR_GOLDMONT_LASTBRANCH_20_TO_IP 0x000006D4 -#define MSR_GOLDMONT_LASTBRANCH_21_TO_IP 0x000006D5 -#define MSR_GOLDMONT_LASTBRANCH_22_TO_IP 0x000006D6 -#define MSR_GOLDMONT_LASTBRANCH_23_TO_IP 0x000006D7 -#define MSR_GOLDMONT_LASTBRANCH_24_TO_IP 0x000006D8 -#define MSR_GOLDMONT_LASTBRANCH_25_TO_IP 0x000006D9 -#define MSR_GOLDMONT_LASTBRANCH_26_TO_IP 0x000006DA -#define MSR_GOLDMONT_LASTBRANCH_27_TO_IP 0x000006DB -#define MSR_GOLDMONT_LASTBRANCH_28_TO_IP 0x000006DC -#define MSR_GOLDMONT_LASTBRANCH_29_TO_IP 0x000006DD -#define MSR_GOLDMONT_LASTBRANCH_30_TO_IP 0x000006DE -#define MSR_GOLDMONT_LASTBRANCH_31_TO_IP 0x000006DF -/// @} - -/** - MSR information returned for MSR indexes #MSR_GOLDMONT_LASTBRANCH_0_TO_IP to - #MSR_GOLDMONT_LASTBRANCH_31_TO_IP. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 31:0] Target Linear Address (R/W). - /// - UINT32 TargetLinearAddress:32; - /// - /// [Bit 47:32] Target Linear Address (R/W). - /// - UINT32 TargetLinearAddressHi:16; - /// - /// [Bits 63:48] Elapsed cycles from last update to the LBR. - /// - UINT32 ElapsedCycles:16; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_LASTBRANCH_TO_IP_REGISTER; - - -/** - Core. Resource Association Register (R/W). - - @param ECX MSR_GOLDMONT_IA32_PQR_ASSOC (0x00000C8F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PQR_ASSOC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_PQR_ASSOC_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_PQR_ASSOC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_PQR_ASSOC); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_PQR_ASSOC, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_PQR_ASSOC is defined as IA32_PQR_ASSOC in SDM. -**/ -#define MSR_GOLDMONT_IA32_PQR_ASSOC 0x00000C8F - -/** - MSR information returned for MSR index #MSR_GOLDMONT_IA32_PQR_ASSOC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - /// - /// [Bits 33:32] COS (R/W). - /// - UINT32 COS:2; - UINT32 Reserved2:30; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_PQR_ASSOC_REGISTER; - - -/** - Module. L2 Class Of Service Mask - COS n (R/W) if CPUID.(EAX=10H, - ECX=1):EDX.COS_MAX[15:0] >=n. - - @param ECX MSR_GOLDMONT_IA32_L2_QOS_MASK_n - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_L2_QOS_MASK_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_L2_QOS_MASK_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_L2_QOS_MASK_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_L2_QOS_MASK_n); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_L2_QOS_MASK_n, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_L2_QOS_MASK_0 is defined as IA32_L2_QOS_MASK_0 in SDM. - MSR_GOLDMONT_IA32_L2_QOS_MASK_1 is defined as IA32_L2_QOS_MASK_1 in SDM. - MSR_GOLDMONT_IA32_L2_QOS_MASK_2 is defined as IA32_L2_QOS_MASK_2 in SDM. - @{ -**/ -#define MSR_GOLDMONT_IA32_L2_QOS_MASK_0 0x00000D10 -#define MSR_GOLDMONT_IA32_L2_QOS_MASK_1 0x00000D11 -#define MSR_GOLDMONT_IA32_L2_QOS_MASK_2 0x00000D12 -/// @} - -/** - MSR information returned for MSR indexes #MSR_GOLDMONT_IA32_L2_QOS_MASK_0 to - #MSR_GOLDMONT_IA32_L2_QOS_MASK_2. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] CBM: Bit vector of available L2 ways for COS 0 enforcement - /// - UINT32 CBM:8; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_L2_QOS_MASK_REGISTER; - - -/** - Package. L2 Class Of Service Mask - COS 3 (R/W) if CPUID.(EAX=10H, - ECX=1):EDX.COS_MAX[15:0] >=3. - - @param ECX MSR_GOLDMONT_IA32_L2_QOS_MASK_3 - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_L2_QOS_MASK_3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_GOLDMONT_IA32_L2_QOS_MASK_3_REGISTER. - - Example usage - @code - MSR_GOLDMONT_IA32_L2_QOS_MASK_3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_GOLDMONT_IA32_L2_QOS_MASK_3); - AsmWriteMsr64 (MSR_GOLDMONT_IA32_L2_QOS_MASK_3, Msr.Uint64); - @endcode - @note MSR_GOLDMONT_IA32_L2_QOS_MASK_3 is defined as IA32_L2_QOS_MASK_3 in SDM. -**/ -#define MSR_GOLDMONT_IA32_L2_QOS_MASK_3 0x00000D13 - -/** - MSR information returned for MSR index #MSR_GOLDMONT_IA32_L2_QOS_MASK_3. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 19:0] CBM: Bit vector of available L2 ways for COS 0 enforcement - /// - UINT32 CBM:20; - UINT32 Reserved1:12; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_GOLDMONT_IA32_L2_QOS_MASK_3_REGISTER; - - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h deleted file mode 100644 index b737a9e4b..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h +++ /dev/null @@ -1,6352 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Haswell-E microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.12. - -**/ - -#ifndef __HASWELL_E_MSR_H__ -#define __HASWELL_E_MSR_H__ - -#include - -/** - Is Intel processors based on the Haswell-E microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_HASWELL_E_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x3F \ - ) \ - ) - -/** - Package. Configured State of Enabled Processor Core Count and Logical - Processor Count (RO) - After a Power-On RESET, enumerates factory - configuration of the number of processor cores and logical processors in the - physical package. - Following the sequence of (i) BIOS modified a - Configuration Mask which selects a subset of processor cores to be active - post RESET and (ii) a RESET event after the modification, enumerates the - current configuration of enabled processor core count and logical processor - count in the physical package. - - @param ECX MSR_HASWELL_E_CORE_THREAD_COUNT (0x00000035) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_CORE_THREAD_COUNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_CORE_THREAD_COUNT_REGISTER. - - Example usage - @code - MSR_HASWELL_E_CORE_THREAD_COUNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_CORE_THREAD_COUNT); - @endcode - @note MSR_HASWELL_E_CORE_THREAD_COUNT is defined as MSR_CORE_THREAD_COUNT in SDM. -**/ -#define MSR_HASWELL_E_CORE_THREAD_COUNT 0x00000035 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_CORE_THREAD_COUNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Core_COUNT (RO) The number of processor cores that are - /// currently enabled (by either factory configuration or BIOS - /// configuration) in the physical package. - /// - UINT32 Core_Count:16; - /// - /// [Bits 31:16] THREAD_COUNT (RO) The number of logical processors that - /// are currently enabled (by either factory configuration or BIOS - /// configuration) in the physical package. - /// - UINT32 Thread_Count:16; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_CORE_THREAD_COUNT_REGISTER; - - -/** - Thread. A Hardware Assigned ID for the Logical Processor (RO). - - @param ECX MSR_HASWELL_E_THREAD_ID_INFO (0x00000053) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_THREAD_ID_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_THREAD_ID_INFO_REGISTER. - - Example usage - @code - MSR_HASWELL_E_THREAD_ID_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_THREAD_ID_INFO); - @endcode - @note MSR_HASWELL_E_THREAD_ID_INFO is defined as MSR_THREAD_ID_INFO in SDM. -**/ -#define MSR_HASWELL_E_THREAD_ID_INFO 0x00000053 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_THREAD_ID_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Logical_Processor_ID (RO) An implementation-specific - /// numerical. value physically assigned to each logical processor. This - /// ID is not related to Initial APIC ID or x2APIC ID, it is unique within - /// a physical package. - /// - UINT32 Logical_Processor_ID:8; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_THREAD_ID_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are processor - specific C-state code names, unrelated to MWAIT extension C-state parameters - or ACPI C-states. `See http://biosbits.org. `__. - - @param ECX MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power) for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0/C1 (no package C-state support) 001b: C2 010b: C6 (non-retention) - /// 011b: C6 (retention) 111b: No Package C state limits. All C states - /// supported by the processor are available. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W). - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO). - /// - UINT32 CFGLock:1; - UINT32 Reserved3:9; - /// - /// [Bit 25] C3 State Auto Demotion Enable (R/W). - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 State Auto Demotion Enable (R/W). - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 Undemotion (R/W). - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 Undemotion (R/W). - /// - UINT32 C1Undemotion:1; - /// - /// [Bit 29] Package C State Demotion Enable (R/W). - /// - UINT32 CStateDemotion:1; - /// - /// [Bit 30] Package C State UnDemotion Enable (R/W). - /// - UINT32 CStateUndemotion:1; - UINT32 Reserved4:1; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Thread. Global Machine Check Capability (R/O). - - @param ECX MSR_HASWELL_E_IA32_MCG_CAP (0x00000179) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_MCG_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_MCG_CAP_REGISTER. - - Example usage - @code - MSR_HASWELL_E_IA32_MCG_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_IA32_MCG_CAP); - @endcode - @note MSR_HASWELL_E_IA32_MCG_CAP is defined as IA32_MCG_CAP in SDM. -**/ -#define MSR_HASWELL_E_IA32_MCG_CAP 0x00000179 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_IA32_MCG_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Count. - /// - UINT32 Count:8; - /// - /// [Bit 8] MCG_CTL_P. - /// - UINT32 MCG_CTL_P:1; - /// - /// [Bit 9] MCG_EXT_P. - /// - UINT32 MCG_EXT_P:1; - /// - /// [Bit 10] MCP_CMCI_P. - /// - UINT32 MCP_CMCI_P:1; - /// - /// [Bit 11] MCG_TES_P. - /// - UINT32 MCG_TES_P:1; - UINT32 Reserved1:4; - /// - /// [Bits 23:16] MCG_EXT_CNT. - /// - UINT32 MCG_EXT_CNT:8; - /// - /// [Bit 24] MCG_SER_P. - /// - UINT32 MCG_SER_P:1; - /// - /// [Bit 25] MCG_EM_P. - /// - UINT32 MCG_EM_P:1; - /// - /// [Bit 26] MCG_ELOG_P. - /// - UINT32 MCG_ELOG_P:1; - UINT32 Reserved2:5; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_IA32_MCG_CAP_REGISTER; - - -/** - THREAD. Enhanced SMM Capabilities (SMM-RO) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_HASWELL_E_SMM_MCA_CAP (0x0000017D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_SMM_MCA_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_SMM_MCA_CAP_REGISTER. - - Example usage - @code - MSR_HASWELL_E_SMM_MCA_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_SMM_MCA_CAP); - AsmWriteMsr64 (MSR_HASWELL_E_SMM_MCA_CAP, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_SMM_MCA_CAP is defined as MSR_SMM_MCA_CAP in SDM. -**/ -#define MSR_HASWELL_E_SMM_MCA_CAP 0x0000017D - -/** - MSR information returned for MSR index #MSR_HASWELL_E_SMM_MCA_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:26; - /// - /// [Bit 58] SMM_Code_Access_Chk (SMM-RO) If set to 1 indicates that the - /// SMM code access restriction is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 SMM_Code_Access_Chk:1; - /// - /// [Bit 59] Long_Flow_Indication (SMM-RO) If set to 1 indicates that the - /// SMM long flow indicator is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 Long_Flow_Indication:1; - UINT32 Reserved3:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_SMM_MCA_CAP_REGISTER; - - -/** - Package. MC Bank Error Configuration (R/W). - - @param ECX MSR_HASWELL_E_ERROR_CONTROL (0x0000017F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_ERROR_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_ERROR_CONTROL_REGISTER. - - Example usage - @code - MSR_HASWELL_E_ERROR_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_ERROR_CONTROL); - AsmWriteMsr64 (MSR_HASWELL_E_ERROR_CONTROL, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_ERROR_CONTROL is defined as MSR_ERROR_CONTROL in SDM. -**/ -#define MSR_HASWELL_E_ERROR_CONTROL 0x0000017F - -/** - MSR information returned for MSR index #MSR_HASWELL_E_ERROR_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] MemError Log Enable (R/W) When set, enables IMC status bank - /// to log additional info in bits 36:32. - /// - UINT32 MemErrorLogEnable:1; - UINT32 Reserved2:30; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_ERROR_CONTROL_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_HASWELL_E_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_HASWELL_E_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT); - @endcode - @note MSR_HASWELL_E_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_HASWELL_E_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_HASWELL_E_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C Maximum turbo ratio - /// limit of 5 core active. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C Maximum turbo ratio - /// limit of 6 core active. - /// - UINT32 Maximum6C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 7C Maximum turbo ratio - /// limit of 7 core active. - /// - UINT32 Maximum7C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for 8C Maximum turbo ratio - /// limit of 8 core active. - /// - UINT32 Maximum8C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_HASWELL_E_TURBO_RATIO_LIMIT1 (0x000001AE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT1_REGISTER. - - Example usage - @code - MSR_HASWELL_E_TURBO_RATIO_LIMIT1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT1); - @endcode - @note MSR_HASWELL_E_TURBO_RATIO_LIMIT1 is defined as MSR_TURBO_RATIO_LIMIT1 in SDM. -**/ -#define MSR_HASWELL_E_TURBO_RATIO_LIMIT1 0x000001AE - -/** - MSR information returned for MSR index #MSR_HASWELL_E_TURBO_RATIO_LIMIT1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 9C Maximum turbo ratio - /// limit of 9 core active. - /// - UINT32 Maximum9C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 10C Maximum turbo ratio - /// limit of 10 core active. - /// - UINT32 Maximum10C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 11C Maximum turbo ratio - /// limit of 11 core active. - /// - UINT32 Maximum11C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 12C Maximum turbo ratio - /// limit of 12 core active. - /// - UINT32 Maximum12C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 13C Maximum turbo ratio - /// limit of 13 core active. - /// - UINT32 Maximum13C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 14C Maximum turbo ratio - /// limit of 14 core active. - /// - UINT32 Maximum14C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 15C Maximum turbo ratio - /// limit of 15 core active. - /// - UINT32 Maximum15C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for16C Maximum turbo ratio - /// limit of 16 core active. - /// - UINT32 Maximum16C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_TURBO_RATIO_LIMIT1_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_HASWELL_E_TURBO_RATIO_LIMIT2 (0x000001AF) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_TURBO_RATIO_LIMIT2_REGISTER. - - Example usage - @code - MSR_HASWELL_E_TURBO_RATIO_LIMIT2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT2); - @endcode - @note MSR_HASWELL_E_TURBO_RATIO_LIMIT2 is defined as MSR_TURBO_RATIO_LIMIT2 in SDM. -**/ -#define MSR_HASWELL_E_TURBO_RATIO_LIMIT2 0x000001AF - -/** - MSR information returned for MSR index #MSR_HASWELL_E_TURBO_RATIO_LIMIT2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 17C Maximum turbo ratio - /// limit of 17 core active. - /// - UINT32 Maximum17C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 18C Maximum turbo ratio - /// limit of 18 core active. - /// - UINT32 Maximum18C:8; - UINT32 Reserved1:16; - UINT32 Reserved2:31; - /// - /// [Bit 63] Package. Semaphore for Turbo Ratio Limit Configuration If 1, - /// the processor uses override configuration specified in - /// MSR_TURBO_RATIO_LIMIT, MSR_TURBO_RATIO_LIMIT1 and - /// MSR_TURBO_RATIO_LIMIT2. If 0, the processor uses factory-set - /// configuration (Default). - /// - UINT32 TurboRatioLimitConfigurationSemaphore:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_TURBO_RATIO_LIMIT2_REGISTER; - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O). - - @param ECX MSR_HASWELL_E_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_HASWELL_E_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_RAPL_POWER_UNIT); - @endcode - @note MSR_HASWELL_E_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_HASWELL_E_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package. Power Units See Section 14.9.1, "RAPL Interfaces.". - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Package. Energy Status Units Energy related information - /// (in Joules) is based on the multiplier, 1/2^ESU; where ESU is an - /// unsigned integer represented by bits 12:8. Default value is 0EH (or 61 - /// micro-joules). - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Package. Time Units See Section 14.9.1, "RAPL - /// Interfaces.". - /// - UINT32 TimeUnits:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_HASWELL_E_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_HASWELL_E_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_HASWELL_E_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_HASWELL_E_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) Energy Consumed by DRAM devices. - - @param ECX MSR_HASWELL_E_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_DRAM_ENERGY_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_DRAM_ENERGY_STATUS_REGISTER. - - Example usage - @code - MSR_HASWELL_E_DRAM_ENERGY_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_DRAM_ENERGY_STATUS); - @endcode - @note MSR_HASWELL_E_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_HASWELL_E_DRAM_ENERGY_STATUS 0x00000619 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_DRAM_ENERGY_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Energy in 15.3 micro-joules. Requires BIOS configuration - /// to enable DRAM RAPL mode 0 (Direct VR). - /// - UINT32 Energy:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_DRAM_ENERGY_STATUS_REGISTER; - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_HASWELL_E_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_PERF_STATUS); - @endcode - @note MSR_HASWELL_E_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_HASWELL_E_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_HASWELL_E_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_HASWELL_E_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_HASWELL_E_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_HASWELL_E_DRAM_POWER_INFO 0x0000061C - - -/** - Package. Configuration of PCIE PLL Relative to BCLK(R/W). - - @param ECX MSR_HASWELL_E_PCIE_PLL_RATIO (0x0000061E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_PCIE_PLL_RATIO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_PCIE_PLL_RATIO_REGISTER. - - Example usage - @code - MSR_HASWELL_E_PCIE_PLL_RATIO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_PCIE_PLL_RATIO); - AsmWriteMsr64 (MSR_HASWELL_E_PCIE_PLL_RATIO, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_PCIE_PLL_RATIO is defined as MSR_PCIE_PLL_RATIO in SDM. -**/ -#define MSR_HASWELL_E_PCIE_PLL_RATIO 0x0000061E - -/** - MSR information returned for MSR index #MSR_HASWELL_E_PCIE_PLL_RATIO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] Package. PCIE Ratio (R/W) 00b: Use 5:5 mapping for100MHz - /// operation (default) 01b: Use 5:4 mapping for125MHz operation 10b: Use - /// 5:3 mapping for166MHz operation 11b: Use 5:2 mapping for250MHz - /// operation. - /// - UINT32 PCIERatio:2; - /// - /// [Bit 2] Package. LPLL Select (R/W) if 1, use configured setting of - /// PCIE Ratio. - /// - UINT32 LPLLSelect:1; - /// - /// [Bit 3] Package. LONG RESET (R/W) if 1, wait additional time-out - /// before re-locking Gen2/Gen3 PLLs. - /// - UINT32 LONGRESET:1; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_PCIE_PLL_RATIO_REGISTER; - - -/** - Package. Reserved (R/O) Reads return 0. - - @param ECX MSR_HASWELL_E_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PP0_ENERGY_STATUS); - @endcode - @note MSR_HASWELL_E_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_HASWELL_E_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS (0x00000690) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS 0x00000690 - -/** - MSR information returned for MSR index #MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, processor core frequency is - /// reduced below the operating system request due to assertion of - /// external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - /// - /// [Bit 2] Power Budget Management Status (R0) When set, frequency is - /// reduced below the operating system request due to PBM limit. - /// - UINT32 PowerBudgetManagementStatus:1; - /// - /// [Bit 3] Platform Configuration Services Status (R0) When set, - /// frequency is reduced below the operating system request due to PCS - /// limit. - /// - UINT32 PlatformConfigurationServicesStatus:1; - UINT32 Reserved1:1; - /// - /// [Bit 5] Autonomous Utilization-Based Frequency Control Status (R0) - /// When set, frequency is reduced below the operating system request - /// because the processor has detected that utilization is low. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - UINT32 Reserved3:1; - /// - /// [Bit 10] Multi-Core Turbo Status (R0) When set, frequency is reduced - /// below the operating system request due to Multi-Core Turbo limits. - /// - UINT32 MultiCoreTurboStatus:1; - UINT32 Reserved4:2; - /// - /// [Bit 13] Core Frequency P1 Status (R0) When set, frequency is reduced - /// below max non-turbo P1. - /// - UINT32 FrequencyP1Status:1; - /// - /// [Bit 14] Core Max n-core Turbo Frequency Limiting Status (R0) When - /// set, frequency is reduced below max n-core turbo frequency. - /// - UINT32 TurboFrequencyLimitingStatus:1; - /// - /// [Bit 15] Core Frequency Limiting Status (R0) When set, frequency is - /// reduced below the operating system request. - /// - UINT32 FrequencyLimitingStatus:1; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - /// - /// [Bit 18] Power Budget Management Log When set, indicates that the PBM - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 PowerBudgetManagementLog:1; - /// - /// [Bit 19] Platform Configuration Services Log When set, indicates that - /// the PCS Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 PlatformConfigurationServicesLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 21] Autonomous Utilization-Based Frequency Control Log When set, - /// indicates that the AUBFC Status bit has asserted since the log bit was - /// last cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - UINT32 Reserved6:1; - /// - /// [Bit 24] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - UINT32 Reserved7:1; - /// - /// [Bit 26] Multi-Core Turbo Log When set, indicates that the Multi-Core - /// Turbo Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MultiCoreTurboLog:1; - UINT32 Reserved8:2; - /// - /// [Bit 29] Core Frequency P1 Log When set, indicates that the Core - /// Frequency P1 Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CoreFrequencyP1Log:1; - /// - /// [Bit 30] Core Max n-core Turbo Frequency Limiting Log When set, - /// indicates that the Core Max n-core Turbo Frequency Limiting Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 TurboFrequencyLimitingLog:1; - /// - /// [Bit 31] Core Frequency Limiting Log When set, indicates that the Core - /// Frequency Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CoreFrequencyLimitingLog:1; - UINT32 Reserved9:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_CORE_PERF_LIMIT_REASONS_REGISTER; - - -/** - THREAD. Monitoring Event Select Register (R/W). if CPUID.(EAX=07H, - ECX=0):EBX.RDT-M[bit 12] = 1. - - @param ECX MSR_HASWELL_E_IA32_QM_EVTSEL (0x00000C8D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_QM_EVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_QM_EVTSEL_REGISTER. - - Example usage - @code - MSR_HASWELL_E_IA32_QM_EVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_IA32_QM_EVTSEL); - AsmWriteMsr64 (MSR_HASWELL_E_IA32_QM_EVTSEL, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_IA32_QM_EVTSEL is defined as IA32_QM_EVTSEL in SDM. -**/ -#define MSR_HASWELL_E_IA32_QM_EVTSEL 0x00000C8D - -/** - MSR information returned for MSR index #MSR_HASWELL_E_IA32_QM_EVTSEL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] EventID (RW) Event encoding: 0x0: no monitoring 0x1: L3 - /// occupancy monitoring all other encoding reserved.. - /// - UINT32 EventID:8; - UINT32 Reserved1:24; - /// - /// [Bits 41:32] RMID (RW). - /// - UINT32 RMID:10; - UINT32 Reserved2:22; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_IA32_QM_EVTSEL_REGISTER; - - -/** - THREAD. Resource Association Register (R/W).. - - @param ECX MSR_HASWELL_E_IA32_PQR_ASSOC (0x00000C8F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_PQR_ASSOC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_E_IA32_PQR_ASSOC_REGISTER. - - Example usage - @code - MSR_HASWELL_E_IA32_PQR_ASSOC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_IA32_PQR_ASSOC); - AsmWriteMsr64 (MSR_HASWELL_E_IA32_PQR_ASSOC, Msr.Uint64); - @endcode - @note MSR_HASWELL_E_IA32_PQR_ASSOC is defined as IA32_PQR_ASSOC in SDM. -**/ -#define MSR_HASWELL_E_IA32_PQR_ASSOC 0x00000C8F - -/** - MSR information returned for MSR index #MSR_HASWELL_E_IA32_PQR_ASSOC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] RMID. - /// - UINT32 RMID:10; - UINT32 Reserved1:22; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_E_IA32_PQR_ASSOC_REGISTER; - - -/** - Package. Uncore perfmon per-socket global control. - - @param ECX MSR_HASWELL_E_PMON_GLOBAL_CTL (0x00000700) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CTL, Msr); - @endcode - @note MSR_HASWELL_E_PMON_GLOBAL_CTL is defined as MSR_PMON_GLOBAL_CTL in SDM. -**/ -#define MSR_HASWELL_E_PMON_GLOBAL_CTL 0x00000700 - - -/** - Package. Uncore perfmon per-socket global status. - - @param ECX MSR_HASWELL_E_PMON_GLOBAL_STATUS (0x00000701) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_PMON_GLOBAL_STATUS is defined as MSR_PMON_GLOBAL_STATUS in SDM. -**/ -#define MSR_HASWELL_E_PMON_GLOBAL_STATUS 0x00000701 - - -/** - Package. Uncore perfmon per-socket global configuration. - - @param ECX MSR_HASWELL_E_PMON_GLOBAL_CONFIG (0x00000702) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CONFIG); - AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CONFIG, Msr); - @endcode - @note MSR_HASWELL_E_PMON_GLOBAL_CONFIG is defined as MSR_PMON_GLOBAL_CONFIG in SDM. -**/ -#define MSR_HASWELL_E_PMON_GLOBAL_CONFIG 0x00000702 - - -/** - Package. Uncore U-box UCLK fixed counter control. - - @param ECX MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL (0x00000703) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL is defined as MSR_U_PMON_UCLK_FIXED_CTL in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL 0x00000703 - - -/** - Package. Uncore U-box UCLK fixed counter. - - @param ECX MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR (0x00000704) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR is defined as MSR_U_PMON_UCLK_FIXED_CTR in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR 0x00000704 - - -/** - Package. Uncore U-box perfmon event select for U-box counter 0. - - @param ECX MSR_HASWELL_E_U_PMON_EVNTSEL0 (0x00000705) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_EVNTSEL0 is defined as MSR_U_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_EVNTSEL0 0x00000705 - - -/** - Package. Uncore U-box perfmon event select for U-box counter 1. - - @param ECX MSR_HASWELL_E_U_PMON_EVNTSEL1 (0x00000706) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_EVNTSEL1 is defined as MSR_U_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_EVNTSEL1 0x00000706 - - -/** - Package. Uncore U-box perfmon U-box wide status. - - @param ECX MSR_HASWELL_E_U_PMON_BOX_STATUS (0x00000708) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_BOX_STATUS is defined as MSR_U_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_BOX_STATUS 0x00000708 - - -/** - Package. Uncore U-box perfmon counter 0. - - @param ECX MSR_HASWELL_E_U_PMON_CTR0 (0x00000709) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_CTR0 is defined as MSR_U_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_CTR0 0x00000709 - - -/** - Package. Uncore U-box perfmon counter 1. - - @param ECX MSR_HASWELL_E_U_PMON_CTR1 (0x0000070A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_U_PMON_CTR1 is defined as MSR_U_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_U_PMON_CTR1 0x0000070A - - -/** - Package. Uncore PCU perfmon for PCU-box-wide control. - - @param ECX MSR_HASWELL_E_PCU_PMON_BOX_CTL (0x00000710) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_BOX_CTL is defined as MSR_PCU_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_BOX_CTL 0x00000710 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 0. - - @param ECX MSR_HASWELL_E_PCU_PMON_EVNTSEL0 (0x00000711) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_EVNTSEL0 is defined as MSR_PCU_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_EVNTSEL0 0x00000711 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 1. - - @param ECX MSR_HASWELL_E_PCU_PMON_EVNTSEL1 (0x00000712) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_EVNTSEL1 is defined as MSR_PCU_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_EVNTSEL1 0x00000712 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 2. - - @param ECX MSR_HASWELL_E_PCU_PMON_EVNTSEL2 (0x00000713) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_EVNTSEL2 is defined as MSR_PCU_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_EVNTSEL2 0x00000713 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 3. - - @param ECX MSR_HASWELL_E_PCU_PMON_EVNTSEL3 (0x00000714) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_EVNTSEL3 is defined as MSR_PCU_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_EVNTSEL3 0x00000714 - - -/** - Package. Uncore PCU perfmon box-wide filter. - - @param ECX MSR_HASWELL_E_PCU_PMON_BOX_FILTER (0x00000715) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_BOX_FILTER is defined as MSR_PCU_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_BOX_FILTER 0x00000715 - - -/** - Package. Uncore PCU perfmon box wide status. - - @param ECX MSR_HASWELL_E_PCU_PMON_BOX_STATUS (0x00000716) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_BOX_STATUS is defined as MSR_PCU_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_BOX_STATUS 0x00000716 - - -/** - Package. Uncore PCU perfmon counter 0. - - @param ECX MSR_HASWELL_E_PCU_PMON_CTR0 (0x00000717) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_CTR0 is defined as MSR_PCU_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_CTR0 0x00000717 - - -/** - Package. Uncore PCU perfmon counter 1. - - @param ECX MSR_HASWELL_E_PCU_PMON_CTR1 (0x00000718) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_CTR1 is defined as MSR_PCU_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_CTR1 0x00000718 - - -/** - Package. Uncore PCU perfmon counter 2. - - @param ECX MSR_HASWELL_E_PCU_PMON_CTR2 (0x00000719) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_CTR2 is defined as MSR_PCU_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_CTR2 0x00000719 - - -/** - Package. Uncore PCU perfmon counter 3. - - @param ECX MSR_HASWELL_E_PCU_PMON_CTR3 (0x0000071A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_PCU_PMON_CTR3 is defined as MSR_PCU_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_PCU_PMON_CTR3 0x0000071A - - -/** - Package. Uncore SBo 0 perfmon for SBo 0 box-wide control. - - @param ECX MSR_HASWELL_E_S0_PMON_BOX_CTL (0x00000720) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_BOX_CTL is defined as MSR_S0_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_BOX_CTL 0x00000720 - - -/** - Package. Uncore SBo 0 perfmon event select for SBo 0 counter 0. - - @param ECX MSR_HASWELL_E_S0_PMON_EVNTSEL0 (0x00000721) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_EVNTSEL0 is defined as MSR_S0_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_EVNTSEL0 0x00000721 - - -/** - Package. Uncore SBo 0 perfmon event select for SBo 0 counter 1. - - @param ECX MSR_HASWELL_E_S0_PMON_EVNTSEL1 (0x00000722) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_EVNTSEL1 is defined as MSR_S0_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_EVNTSEL1 0x00000722 - - -/** - Package. Uncore SBo 0 perfmon event select for SBo 0 counter 2. - - @param ECX MSR_HASWELL_E_S0_PMON_EVNTSEL2 (0x00000723) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_EVNTSEL2 is defined as MSR_S0_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_EVNTSEL2 0x00000723 - - -/** - Package. Uncore SBo 0 perfmon event select for SBo 0 counter 3. - - @param ECX MSR_HASWELL_E_S0_PMON_EVNTSEL3 (0x00000724) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_EVNTSEL3 is defined as MSR_S0_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_EVNTSEL3 0x00000724 - - -/** - Package. Uncore SBo 0 perfmon box-wide filter. - - @param ECX MSR_HASWELL_E_S0_PMON_BOX_FILTER (0x00000725) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_BOX_FILTER is defined as MSR_S0_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_BOX_FILTER 0x00000725 - - -/** - Package. Uncore SBo 0 perfmon counter 0. - - @param ECX MSR_HASWELL_E_S0_PMON_CTR0 (0x00000726) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_CTR0 is defined as MSR_S0_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_CTR0 0x00000726 - - -/** - Package. Uncore SBo 0 perfmon counter 1. - - @param ECX MSR_HASWELL_E_S0_PMON_CTR1 (0x00000727) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_CTR1 is defined as MSR_S0_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_CTR1 0x00000727 - - -/** - Package. Uncore SBo 0 perfmon counter 2. - - @param ECX MSR_HASWELL_E_S0_PMON_CTR2 (0x00000728) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_CTR2 is defined as MSR_S0_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_CTR2 0x00000728 - - -/** - Package. Uncore SBo 0 perfmon counter 3. - - @param ECX MSR_HASWELL_E_S0_PMON_CTR3 (0x00000729) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_S0_PMON_CTR3 is defined as MSR_S0_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_S0_PMON_CTR3 0x00000729 - - -/** - Package. Uncore SBo 1 perfmon for SBo 1 box-wide control. - - @param ECX MSR_HASWELL_E_S1_PMON_BOX_CTL (0x0000072A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_BOX_CTL is defined as MSR_S1_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_BOX_CTL 0x0000072A - - -/** - Package. Uncore SBo 1 perfmon event select for SBo 1 counter 0. - - @param ECX MSR_HASWELL_E_S1_PMON_EVNTSEL0 (0x0000072B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_EVNTSEL0 is defined as MSR_S1_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_EVNTSEL0 0x0000072B - - -/** - Package. Uncore SBo 1 perfmon event select for SBo 1 counter 1. - - @param ECX MSR_HASWELL_E_S1_PMON_EVNTSEL1 (0x0000072C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_EVNTSEL1 is defined as MSR_S1_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_EVNTSEL1 0x0000072C - - -/** - Package. Uncore SBo 1 perfmon event select for SBo 1 counter 2. - - @param ECX MSR_HASWELL_E_S1_PMON_EVNTSEL2 (0x0000072D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_EVNTSEL2 is defined as MSR_S1_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_EVNTSEL2 0x0000072D - - -/** - Package. Uncore SBo 1 perfmon event select for SBo 1 counter 3. - - @param ECX MSR_HASWELL_E_S1_PMON_EVNTSEL3 (0x0000072E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_EVNTSEL3 is defined as MSR_S1_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_EVNTSEL3 0x0000072E - - -/** - Package. Uncore SBo 1 perfmon box-wide filter. - - @param ECX MSR_HASWELL_E_S1_PMON_BOX_FILTER (0x0000072F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_BOX_FILTER is defined as MSR_S1_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_BOX_FILTER 0x0000072F - - -/** - Package. Uncore SBo 1 perfmon counter 0. - - @param ECX MSR_HASWELL_E_S1_PMON_CTR0 (0x00000730) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_CTR0 is defined as MSR_S1_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_CTR0 0x00000730 - - -/** - Package. Uncore SBo 1 perfmon counter 1. - - @param ECX MSR_HASWELL_E_S1_PMON_CTR1 (0x00000731) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_CTR1 is defined as MSR_S1_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_CTR1 0x00000731 - - -/** - Package. Uncore SBo 1 perfmon counter 2. - - @param ECX MSR_HASWELL_E_S1_PMON_CTR2 (0x00000732) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_CTR2 is defined as MSR_S1_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_CTR2 0x00000732 - - -/** - Package. Uncore SBo 1 perfmon counter 3. - - @param ECX MSR_HASWELL_E_S1_PMON_CTR3 (0x00000733) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_S1_PMON_CTR3 is defined as MSR_S1_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_S1_PMON_CTR3 0x00000733 - - -/** - Package. Uncore SBo 2 perfmon for SBo 2 box-wide control. - - @param ECX MSR_HASWELL_E_S2_PMON_BOX_CTL (0x00000734) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_BOX_CTL is defined as MSR_S2_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_BOX_CTL 0x00000734 - - -/** - Package. Uncore SBo 2 perfmon event select for SBo 2 counter 0. - - @param ECX MSR_HASWELL_E_S2_PMON_EVNTSEL0 (0x00000735) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_EVNTSEL0 is defined as MSR_S2_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_EVNTSEL0 0x00000735 - - -/** - Package. Uncore SBo 2 perfmon event select for SBo 2 counter 1. - - @param ECX MSR_HASWELL_E_S2_PMON_EVNTSEL1 (0x00000736) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_EVNTSEL1 is defined as MSR_S2_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_EVNTSEL1 0x00000736 - - -/** - Package. Uncore SBo 2 perfmon event select for SBo 2 counter 2. - - @param ECX MSR_HASWELL_E_S2_PMON_EVNTSEL2 (0x00000737) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_EVNTSEL2 is defined as MSR_S2_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_EVNTSEL2 0x00000737 - - -/** - Package. Uncore SBo 2 perfmon event select for SBo 2 counter 3. - - @param ECX MSR_HASWELL_E_S2_PMON_EVNTSEL3 (0x00000738) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_EVNTSEL3 is defined as MSR_S2_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_EVNTSEL3 0x00000738 - - -/** - Package. Uncore SBo 2 perfmon box-wide filter. - - @param ECX MSR_HASWELL_E_S2_PMON_BOX_FILTER (0x00000739) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_BOX_FILTER is defined as MSR_S2_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_BOX_FILTER 0x00000739 - - -/** - Package. Uncore SBo 2 perfmon counter 0. - - @param ECX MSR_HASWELL_E_S2_PMON_CTR0 (0x0000073A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_CTR0 is defined as MSR_S2_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_CTR0 0x0000073A - - -/** - Package. Uncore SBo 2 perfmon counter 1. - - @param ECX MSR_HASWELL_E_S2_PMON_CTR1 (0x0000073B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_CTR1 is defined as MSR_S2_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_CTR1 0x0000073B - - -/** - Package. Uncore SBo 2 perfmon counter 2. - - @param ECX MSR_HASWELL_E_S2_PMON_CTR2 (0x0000073C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_CTR2 is defined as MSR_S2_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_CTR2 0x0000073C - - -/** - Package. Uncore SBo 2 perfmon counter 3. - - @param ECX MSR_HASWELL_E_S2_PMON_CTR3 (0x0000073D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_S2_PMON_CTR3 is defined as MSR_S2_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_S2_PMON_CTR3 0x0000073D - - -/** - Package. Uncore SBo 3 perfmon for SBo 3 box-wide control. - - @param ECX MSR_HASWELL_E_S3_PMON_BOX_CTL (0x0000073E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_BOX_CTL is defined as MSR_S3_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_BOX_CTL 0x0000073E - - -/** - Package. Uncore SBo 3 perfmon event select for SBo 3 counter 0. - - @param ECX MSR_HASWELL_E_S3_PMON_EVNTSEL0 (0x0000073F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_EVNTSEL0 is defined as MSR_S3_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_EVNTSEL0 0x0000073F - - -/** - Package. Uncore SBo 3 perfmon event select for SBo 3 counter 1. - - @param ECX MSR_HASWELL_E_S3_PMON_EVNTSEL1 (0x00000740) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_EVNTSEL1 is defined as MSR_S3_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_EVNTSEL1 0x00000740 - - -/** - Package. Uncore SBo 3 perfmon event select for SBo 3 counter 2. - - @param ECX MSR_HASWELL_E_S3_PMON_EVNTSEL2 (0x00000741) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_EVNTSEL2 is defined as MSR_S3_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_EVNTSEL2 0x00000741 - - -/** - Package. Uncore SBo 3 perfmon event select for SBo 3 counter 3. - - @param ECX MSR_HASWELL_E_S3_PMON_EVNTSEL3 (0x00000742) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_EVNTSEL3 is defined as MSR_S3_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_EVNTSEL3 0x00000742 - - -/** - Package. Uncore SBo 3 perfmon box-wide filter. - - @param ECX MSR_HASWELL_E_S3_PMON_BOX_FILTER (0x00000743) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_BOX_FILTER is defined as MSR_S3_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_BOX_FILTER 0x00000743 - - -/** - Package. Uncore SBo 3 perfmon counter 0. - - @param ECX MSR_HASWELL_E_S3_PMON_CTR0 (0x00000744) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_CTR0 is defined as MSR_S3_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_CTR0 0x00000744 - - -/** - Package. Uncore SBo 3 perfmon counter 1. - - @param ECX MSR_HASWELL_E_S3_PMON_CTR1 (0x00000745) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_CTR1 is defined as MSR_S3_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_CTR1 0x00000745 - - -/** - Package. Uncore SBo 3 perfmon counter 2. - - @param ECX MSR_HASWELL_E_S3_PMON_CTR2 (0x00000746) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_CTR2 is defined as MSR_S3_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_CTR2 0x00000746 - - -/** - Package. Uncore SBo 3 perfmon counter 3. - - @param ECX MSR_HASWELL_E_S3_PMON_CTR3 (0x00000747) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_S3_PMON_CTR3 is defined as MSR_S3_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_S3_PMON_CTR3 0x00000747 - - -/** - Package. Uncore C-box 0 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C0_PMON_BOX_CTL (0x00000E00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_BOX_CTL is defined as MSR_C0_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_BOX_CTL 0x00000E00 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 0. - - @param ECX MSR_HASWELL_E_C0_PMON_EVNTSEL0 (0x00000E01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_EVNTSEL0 is defined as MSR_C0_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_EVNTSEL0 0x00000E01 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 1. - - @param ECX MSR_HASWELL_E_C0_PMON_EVNTSEL1 (0x00000E02) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_EVNTSEL1 is defined as MSR_C0_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_EVNTSEL1 0x00000E02 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 2. - - @param ECX MSR_HASWELL_E_C0_PMON_EVNTSEL2 (0x00000E03) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_EVNTSEL2 is defined as MSR_C0_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_EVNTSEL2 0x00000E03 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 3. - - @param ECX MSR_HASWELL_E_C0_PMON_EVNTSEL3 (0x00000E04) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_EVNTSEL3 is defined as MSR_C0_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_EVNTSEL3 0x00000E04 - - -/** - Package. Uncore C-box 0 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C0_PMON_BOX_FILTER0 (0x00000E05) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_BOX_FILTER0 is defined as MSR_C0_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_BOX_FILTER0 0x00000E05 - - -/** - Package. Uncore C-box 0 perfmon box wide filter 1. - - @param ECX MSR_HASWELL_E_C0_PMON_BOX_FILTER1 (0x00000E06) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_BOX_FILTER1 is defined as MSR_C0_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_BOX_FILTER1 0x00000E06 - - -/** - Package. Uncore C-box 0 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C0_PMON_BOX_STATUS (0x00000E07) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_BOX_STATUS is defined as MSR_C0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_BOX_STATUS 0x00000E07 - - -/** - Package. Uncore C-box 0 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C0_PMON_CTR0 (0x00000E08) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_CTR0 is defined as MSR_C0_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_CTR0 0x00000E08 - - -/** - Package. Uncore C-box 0 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C0_PMON_CTR1 (0x00000E09) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_CTR1 is defined as MSR_C0_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_CTR1 0x00000E09 - - -/** - Package. Uncore C-box 0 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C0_PMON_CTR2 (0x00000E0A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_CTR2 is defined as MSR_C0_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_CTR2 0x00000E0A - - -/** - Package. Uncore C-box 0 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C0_PMON_CTR3 (0x00000E0B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C0_PMON_CTR3 is defined as MSR_C0_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C0_PMON_CTR3 0x00000E0B - - -/** - Package. Uncore C-box 1 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C1_PMON_BOX_CTL (0x00000E10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_BOX_CTL is defined as MSR_C1_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_BOX_CTL 0x00000E10 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 0. - - @param ECX MSR_HASWELL_E_C1_PMON_EVNTSEL0 (0x00000E11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_EVNTSEL0 is defined as MSR_C1_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_EVNTSEL0 0x00000E11 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 1. - - @param ECX MSR_HASWELL_E_C1_PMON_EVNTSEL1 (0x00000E12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_EVNTSEL1 is defined as MSR_C1_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_EVNTSEL1 0x00000E12 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 2. - - @param ECX MSR_HASWELL_E_C1_PMON_EVNTSEL2 (0x00000E13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_EVNTSEL2 is defined as MSR_C1_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_EVNTSEL2 0x00000E13 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 3. - - @param ECX MSR_HASWELL_E_C1_PMON_EVNTSEL3 (0x00000E14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_EVNTSEL3 is defined as MSR_C1_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_EVNTSEL3 0x00000E14 - - -/** - Package. Uncore C-box 1 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C1_PMON_BOX_FILTER0 (0x00000E15) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_BOX_FILTER0 is defined as MSR_C1_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_BOX_FILTER0 0x00000E15 - - -/** - Package. Uncore C-box 1 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C1_PMON_BOX_FILTER1 (0x00000E16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_BOX_FILTER1 is defined as MSR_C1_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_BOX_FILTER1 0x00000E16 - - -/** - Package. Uncore C-box 1 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C1_PMON_BOX_STATUS (0x00000E17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_BOX_STATUS is defined as MSR_C1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_BOX_STATUS 0x00000E17 - - -/** - Package. Uncore C-box 1 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C1_PMON_CTR0 (0x00000E18) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_CTR0 is defined as MSR_C1_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_CTR0 0x00000E18 - - -/** - Package. Uncore C-box 1 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C1_PMON_CTR1 (0x00000E19) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_CTR1 is defined as MSR_C1_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_CTR1 0x00000E19 - - -/** - Package. Uncore C-box 1 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C1_PMON_CTR2 (0x00000E1A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_CTR2 is defined as MSR_C1_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_CTR2 0x00000E1A - - -/** - Package. Uncore C-box 1 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C1_PMON_CTR3 (0x00000E1B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C1_PMON_CTR3 is defined as MSR_C1_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C1_PMON_CTR3 0x00000E1B - - -/** - Package. Uncore C-box 2 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C2_PMON_BOX_CTL (0x00000E20) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_BOX_CTL is defined as MSR_C2_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_BOX_CTL 0x00000E20 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 0. - - @param ECX MSR_HASWELL_E_C2_PMON_EVNTSEL0 (0x00000E21) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_EVNTSEL0 is defined as MSR_C2_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_EVNTSEL0 0x00000E21 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 1. - - @param ECX MSR_HASWELL_E_C2_PMON_EVNTSEL1 (0x00000E22) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_EVNTSEL1 is defined as MSR_C2_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_EVNTSEL1 0x00000E22 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 2. - - @param ECX MSR_HASWELL_E_C2_PMON_EVNTSEL2 (0x00000E23) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_EVNTSEL2 is defined as MSR_C2_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_EVNTSEL2 0x00000E23 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 3. - - @param ECX MSR_HASWELL_E_C2_PMON_EVNTSEL3 (0x00000E24) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_EVNTSEL3 is defined as MSR_C2_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_EVNTSEL3 0x00000E24 - - -/** - Package. Uncore C-box 2 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C2_PMON_BOX_FILTER0 (0x00000E25) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_BOX_FILTER0 is defined as MSR_C2_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_BOX_FILTER0 0x00000E25 - - -/** - Package. Uncore C-box 2 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C2_PMON_BOX_FILTER1 (0x00000E26) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_BOX_FILTER1 is defined as MSR_C2_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_BOX_FILTER1 0x00000E26 - - -/** - Package. Uncore C-box 2 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C2_PMON_BOX_STATUS (0x00000E27) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_BOX_STATUS is defined as MSR_C2_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_BOX_STATUS 0x00000E27 - - -/** - Package. Uncore C-box 2 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C2_PMON_CTR0 (0x00000E28) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_CTR0 is defined as MSR_C2_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_CTR0 0x00000E28 - - -/** - Package. Uncore C-box 2 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C2_PMON_CTR1 (0x00000E29) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_CTR1 is defined as MSR_C2_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_CTR1 0x00000E29 - - -/** - Package. Uncore C-box 2 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C2_PMON_CTR2 (0x00000E2A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_CTR2 is defined as MSR_C2_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_CTR2 0x00000E2A - - -/** - Package. Uncore C-box 2 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C2_PMON_CTR3 (0x00000E2B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C2_PMON_CTR3 is defined as MSR_C2_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C2_PMON_CTR3 0x00000E2B - - -/** - Package. Uncore C-box 3 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C3_PMON_BOX_CTL (0x00000E30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_BOX_CTL is defined as MSR_C3_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_BOX_CTL 0x00000E30 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 0. - - @param ECX MSR_HASWELL_E_C3_PMON_EVNTSEL0 (0x00000E31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_EVNTSEL0 is defined as MSR_C3_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_EVNTSEL0 0x00000E31 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 1. - - @param ECX MSR_HASWELL_E_C3_PMON_EVNTSEL1 (0x00000E32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_EVNTSEL1 is defined as MSR_C3_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_EVNTSEL1 0x00000E32 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 2. - - @param ECX MSR_HASWELL_E_C3_PMON_EVNTSEL2 (0x00000E33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_EVNTSEL2 is defined as MSR_C3_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_EVNTSEL2 0x00000E33 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 3. - - @param ECX MSR_HASWELL_E_C3_PMON_EVNTSEL3 (0x00000E34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_EVNTSEL3 is defined as MSR_C3_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_EVNTSEL3 0x00000E34 - - -/** - Package. Uncore C-box 3 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C3_PMON_BOX_FILTER0 (0x00000E35) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_BOX_FILTER0 is defined as MSR_C3_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_BOX_FILTER0 0x00000E35 - - -/** - Package. Uncore C-box 3 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C3_PMON_BOX_FILTER1 (0x00000E36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_BOX_FILTER1 is defined as MSR_C3_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_BOX_FILTER1 0x00000E36 - - -/** - Package. Uncore C-box 3 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C3_PMON_BOX_STATUS (0x00000E37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_BOX_STATUS is defined as MSR_C3_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_BOX_STATUS 0x00000E37 - - -/** - Package. Uncore C-box 3 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C3_PMON_CTR0 (0x00000E38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_CTR0 is defined as MSR_C3_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_CTR0 0x00000E38 - - -/** - Package. Uncore C-box 3 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C3_PMON_CTR1 (0x00000E39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_CTR1 is defined as MSR_C3_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_CTR1 0x00000E39 - - -/** - Package. Uncore C-box 3 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C3_PMON_CTR2 (0x00000E3A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_CTR2 is defined as MSR_C3_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_CTR2 0x00000E3A - - -/** - Package. Uncore C-box 3 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C3_PMON_CTR3 (0x00000E3B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C3_PMON_CTR3 is defined as MSR_C3_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C3_PMON_CTR3 0x00000E3B - - -/** - Package. Uncore C-box 4 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C4_PMON_BOX_CTL (0x00000E40) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_BOX_CTL is defined as MSR_C4_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_BOX_CTL 0x00000E40 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 0. - - @param ECX MSR_HASWELL_E_C4_PMON_EVNTSEL0 (0x00000E41) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_EVNTSEL0 is defined as MSR_C4_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_EVNTSEL0 0x00000E41 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 1. - - @param ECX MSR_HASWELL_E_C4_PMON_EVNTSEL1 (0x00000E42) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_EVNTSEL1 is defined as MSR_C4_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_EVNTSEL1 0x00000E42 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 2. - - @param ECX MSR_HASWELL_E_C4_PMON_EVNTSEL2 (0x00000E43) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_EVNTSEL2 is defined as MSR_C4_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_EVNTSEL2 0x00000E43 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 3. - - @param ECX MSR_HASWELL_E_C4_PMON_EVNTSEL3 (0x00000E44) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_EVNTSEL3 is defined as MSR_C4_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_EVNTSEL3 0x00000E44 - - -/** - Package. Uncore C-box 4 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C4_PMON_BOX_FILTER0 (0x00000E45) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_BOX_FILTER0 is defined as MSR_C4_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_BOX_FILTER0 0x00000E45 - - -/** - Package. Uncore C-box 4 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C4_PMON_BOX_FILTER1 (0x00000E46) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_BOX_FILTER1 is defined as MSR_C4_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_BOX_FILTER1 0x00000E46 - - -/** - Package. Uncore C-box 4 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C4_PMON_BOX_STATUS (0x00000E47) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_BOX_STATUS is defined as MSR_C4_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_BOX_STATUS 0x00000E47 - - -/** - Package. Uncore C-box 4 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C4_PMON_CTR0 (0x00000E48) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_CTR0 is defined as MSR_C4_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_CTR0 0x00000E48 - - -/** - Package. Uncore C-box 4 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C4_PMON_CTR1 (0x00000E49) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_CTR1 is defined as MSR_C4_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_CTR1 0x00000E49 - - -/** - Package. Uncore C-box 4 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C4_PMON_CTR2 (0x00000E4A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_CTR2 is defined as MSR_C4_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_CTR2 0x00000E4A - - -/** - Package. Uncore C-box 4 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C4_PMON_CTR3 (0x00000E4B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C4_PMON_CTR3 is defined as MSR_C4_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C4_PMON_CTR3 0x00000E4B - - -/** - Package. Uncore C-box 5 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C5_PMON_BOX_CTL (0x00000E50) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_BOX_CTL is defined as MSR_C5_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_BOX_CTL 0x00000E50 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 0. - - @param ECX MSR_HASWELL_E_C5_PMON_EVNTSEL0 (0x00000E51) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_EVNTSEL0 is defined as MSR_C5_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_EVNTSEL0 0x00000E51 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 1. - - @param ECX MSR_HASWELL_E_C5_PMON_EVNTSEL1 (0x00000E52) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_EVNTSEL1 is defined as MSR_C5_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_EVNTSEL1 0x00000E52 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 2. - - @param ECX MSR_HASWELL_E_C5_PMON_EVNTSEL2 (0x00000E53) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_EVNTSEL2 is defined as MSR_C5_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_EVNTSEL2 0x00000E53 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 3. - - @param ECX MSR_HASWELL_E_C5_PMON_EVNTSEL3 (0x00000E54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_EVNTSEL3 is defined as MSR_C5_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_EVNTSEL3 0x00000E54 - - -/** - Package. Uncore C-box 5 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C5_PMON_BOX_FILTER0 (0x00000E55) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_BOX_FILTER0 is defined as MSR_C5_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_BOX_FILTER0 0x00000E55 - - -/** - Package. Uncore C-box 5 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C5_PMON_BOX_FILTER1 (0x00000E56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_BOX_FILTER1 is defined as MSR_C5_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_BOX_FILTER1 0x00000E56 - - -/** - Package. Uncore C-box 5 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C5_PMON_BOX_STATUS (0x00000E57) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_BOX_STATUS is defined as MSR_C5_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_BOX_STATUS 0x00000E57 - - -/** - Package. Uncore C-box 5 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C5_PMON_CTR0 (0x00000E58) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_CTR0 is defined as MSR_C5_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_CTR0 0x00000E58 - - -/** - Package. Uncore C-box 5 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C5_PMON_CTR1 (0x00000E59) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_CTR1 is defined as MSR_C5_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_CTR1 0x00000E59 - - -/** - Package. Uncore C-box 5 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C5_PMON_CTR2 (0x00000E5A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_CTR2 is defined as MSR_C5_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_CTR2 0x00000E5A - - -/** - Package. Uncore C-box 5 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C5_PMON_CTR3 (0x00000E5B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C5_PMON_CTR3 is defined as MSR_C5_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C5_PMON_CTR3 0x00000E5B - - -/** - Package. Uncore C-box 6 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C6_PMON_BOX_CTL (0x00000E60) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_BOX_CTL is defined as MSR_C6_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_BOX_CTL 0x00000E60 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 0. - - @param ECX MSR_HASWELL_E_C6_PMON_EVNTSEL0 (0x00000E61) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_EVNTSEL0 is defined as MSR_C6_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_EVNTSEL0 0x00000E61 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 1. - - @param ECX MSR_HASWELL_E_C6_PMON_EVNTSEL1 (0x00000E62) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_EVNTSEL1 is defined as MSR_C6_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_EVNTSEL1 0x00000E62 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 2. - - @param ECX MSR_HASWELL_E_C6_PMON_EVNTSEL2 (0x00000E63) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_EVNTSEL2 is defined as MSR_C6_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_EVNTSEL2 0x00000E63 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 3. - - @param ECX MSR_HASWELL_E_C6_PMON_EVNTSEL3 (0x00000E64) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_EVNTSEL3 is defined as MSR_C6_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_EVNTSEL3 0x00000E64 - - -/** - Package. Uncore C-box 6 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C6_PMON_BOX_FILTER0 (0x00000E65) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_BOX_FILTER0 is defined as MSR_C6_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_BOX_FILTER0 0x00000E65 - - -/** - Package. Uncore C-box 6 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C6_PMON_BOX_FILTER1 (0x00000E66) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_BOX_FILTER1 is defined as MSR_C6_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_BOX_FILTER1 0x00000E66 - - -/** - Package. Uncore C-box 6 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C6_PMON_BOX_STATUS (0x00000E67) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_BOX_STATUS is defined as MSR_C6_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_BOX_STATUS 0x00000E67 - - -/** - Package. Uncore C-box 6 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C6_PMON_CTR0 (0x00000E68) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_CTR0 is defined as MSR_C6_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_CTR0 0x00000E68 - - -/** - Package. Uncore C-box 6 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C6_PMON_CTR1 (0x00000E69) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_CTR1 is defined as MSR_C6_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_CTR1 0x00000E69 - - -/** - Package. Uncore C-box 6 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C6_PMON_CTR2 (0x00000E6A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_CTR2 is defined as MSR_C6_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_CTR2 0x00000E6A - - -/** - Package. Uncore C-box 6 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C6_PMON_CTR3 (0x00000E6B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C6_PMON_CTR3 is defined as MSR_C6_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C6_PMON_CTR3 0x00000E6B - - -/** - Package. Uncore C-box 7 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C7_PMON_BOX_CTL (0x00000E70) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_BOX_CTL is defined as MSR_C7_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_BOX_CTL 0x00000E70 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 0. - - @param ECX MSR_HASWELL_E_C7_PMON_EVNTSEL0 (0x00000E71) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_EVNTSEL0 is defined as MSR_C7_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_EVNTSEL0 0x00000E71 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 1. - - @param ECX MSR_HASWELL_E_C7_PMON_EVNTSEL1 (0x00000E72) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_EVNTSEL1 is defined as MSR_C7_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_EVNTSEL1 0x00000E72 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 2. - - @param ECX MSR_HASWELL_E_C7_PMON_EVNTSEL2 (0x00000E73) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_EVNTSEL2 is defined as MSR_C7_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_EVNTSEL2 0x00000E73 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 3. - - @param ECX MSR_HASWELL_E_C7_PMON_EVNTSEL3 (0x00000E74) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_EVNTSEL3 is defined as MSR_C7_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_EVNTSEL3 0x00000E74 - - -/** - Package. Uncore C-box 7 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C7_PMON_BOX_FILTER0 (0x00000E75) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_BOX_FILTER0 is defined as MSR_C7_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_BOX_FILTER0 0x00000E75 - - -/** - Package. Uncore C-box 7 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C7_PMON_BOX_FILTER1 (0x00000E76) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_BOX_FILTER1 is defined as MSR_C7_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_BOX_FILTER1 0x00000E76 - - -/** - Package. Uncore C-box 7 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C7_PMON_BOX_STATUS (0x00000E77) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_BOX_STATUS is defined as MSR_C7_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_BOX_STATUS 0x00000E77 - - -/** - Package. Uncore C-box 7 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C7_PMON_CTR0 (0x00000E78) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_CTR0 is defined as MSR_C7_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_CTR0 0x00000E78 - - -/** - Package. Uncore C-box 7 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C7_PMON_CTR1 (0x00000E79) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_CTR1 is defined as MSR_C7_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_CTR1 0x00000E79 - - -/** - Package. Uncore C-box 7 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C7_PMON_CTR2 (0x00000E7A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_CTR2 is defined as MSR_C7_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_CTR2 0x00000E7A - - -/** - Package. Uncore C-box 7 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C7_PMON_CTR3 (0x00000E7B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C7_PMON_CTR3 is defined as MSR_C7_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C7_PMON_CTR3 0x00000E7B - - -/** - Package. Uncore C-box 8 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C8_PMON_BOX_CTL (0x00000E80) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_BOX_CTL is defined as MSR_C8_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_BOX_CTL 0x00000E80 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 0. - - @param ECX MSR_HASWELL_E_C8_PMON_EVNTSEL0 (0x00000E81) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_EVNTSEL0 is defined as MSR_C8_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_EVNTSEL0 0x00000E81 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 1. - - @param ECX MSR_HASWELL_E_C8_PMON_EVNTSEL1 (0x00000E82) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_EVNTSEL1 is defined as MSR_C8_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_EVNTSEL1 0x00000E82 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 2. - - @param ECX MSR_HASWELL_E_C8_PMON_EVNTSEL2 (0x00000E83) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_EVNTSEL2 is defined as MSR_C8_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_EVNTSEL2 0x00000E83 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 3. - - @param ECX MSR_HASWELL_E_C8_PMON_EVNTSEL3 (0x00000E84) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_EVNTSEL3 is defined as MSR_C8_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_EVNTSEL3 0x00000E84 - - -/** - Package. Uncore C-box 8 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C8_PMON_BOX_FILTER0 (0x00000E85) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_BOX_FILTER0 is defined as MSR_C8_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_BOX_FILTER0 0x00000E85 - - -/** - Package. Uncore C-box 8 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C8_PMON_BOX_FILTER1 (0x00000E86) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_BOX_FILTER1 is defined as MSR_C8_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_BOX_FILTER1 0x00000E86 - - -/** - Package. Uncore C-box 8 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C8_PMON_BOX_STATUS (0x00000E87) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_BOX_STATUS is defined as MSR_C8_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_BOX_STATUS 0x00000E87 - - -/** - Package. Uncore C-box 8 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C8_PMON_CTR0 (0x00000E88) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_CTR0 is defined as MSR_C8_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_CTR0 0x00000E88 - - -/** - Package. Uncore C-box 8 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C8_PMON_CTR1 (0x00000E89) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_CTR1 is defined as MSR_C8_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_CTR1 0x00000E89 - - -/** - Package. Uncore C-box 8 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C8_PMON_CTR2 (0x00000E8A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_CTR2 is defined as MSR_C8_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_CTR2 0x00000E8A - - -/** - Package. Uncore C-box 8 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C8_PMON_CTR3 (0x00000E8B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C8_PMON_CTR3 is defined as MSR_C8_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C8_PMON_CTR3 0x00000E8B - - -/** - Package. Uncore C-box 9 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C9_PMON_BOX_CTL (0x00000E90) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_BOX_CTL is defined as MSR_C9_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_BOX_CTL 0x00000E90 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 0. - - @param ECX MSR_HASWELL_E_C9_PMON_EVNTSEL0 (0x00000E91) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_EVNTSEL0 is defined as MSR_C9_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_EVNTSEL0 0x00000E91 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 1. - - @param ECX MSR_HASWELL_E_C9_PMON_EVNTSEL1 (0x00000E92) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_EVNTSEL1 is defined as MSR_C9_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_EVNTSEL1 0x00000E92 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 2. - - @param ECX MSR_HASWELL_E_C9_PMON_EVNTSEL2 (0x00000E93) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_EVNTSEL2 is defined as MSR_C9_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_EVNTSEL2 0x00000E93 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 3. - - @param ECX MSR_HASWELL_E_C9_PMON_EVNTSEL3 (0x00000E94) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_EVNTSEL3 is defined as MSR_C9_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_EVNTSEL3 0x00000E94 - - -/** - Package. Uncore C-box 9 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C9_PMON_BOX_FILTER0 (0x00000E95) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_BOX_FILTER0 is defined as MSR_C9_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_BOX_FILTER0 0x00000E95 - - -/** - Package. Uncore C-box 9 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C9_PMON_BOX_FILTER1 (0x00000E96) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_BOX_FILTER1 is defined as MSR_C9_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_BOX_FILTER1 0x00000E96 - - -/** - Package. Uncore C-box 9 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C9_PMON_BOX_STATUS (0x00000E97) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_BOX_STATUS is defined as MSR_C9_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_BOX_STATUS 0x00000E97 - - -/** - Package. Uncore C-box 9 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C9_PMON_CTR0 (0x00000E98) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_CTR0 is defined as MSR_C9_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_CTR0 0x00000E98 - - -/** - Package. Uncore C-box 9 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C9_PMON_CTR1 (0x00000E99) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_CTR1 is defined as MSR_C9_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_CTR1 0x00000E99 - - -/** - Package. Uncore C-box 9 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C9_PMON_CTR2 (0x00000E9A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_CTR2 is defined as MSR_C9_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_CTR2 0x00000E9A - - -/** - Package. Uncore C-box 9 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C9_PMON_CTR3 (0x00000E9B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C9_PMON_CTR3 is defined as MSR_C9_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C9_PMON_CTR3 0x00000E9B - - -/** - Package. Uncore C-box 10 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C10_PMON_BOX_CTL (0x00000EA0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_BOX_CTL is defined as MSR_C10_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_BOX_CTL 0x00000EA0 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 0. - - @param ECX MSR_HASWELL_E_C10_PMON_EVNTSEL0 (0x00000EA1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_EVNTSEL0 is defined as MSR_C10_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_EVNTSEL0 0x00000EA1 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 1. - - @param ECX MSR_HASWELL_E_C10_PMON_EVNTSEL1 (0x00000EA2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_EVNTSEL1 is defined as MSR_C10_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_EVNTSEL1 0x00000EA2 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 2. - - @param ECX MSR_HASWELL_E_C10_PMON_EVNTSEL2 (0x00000EA3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_EVNTSEL2 is defined as MSR_C10_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_EVNTSEL2 0x00000EA3 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 3. - - @param ECX MSR_HASWELL_E_C10_PMON_EVNTSEL3 (0x00000EA4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_EVNTSEL3 is defined as MSR_C10_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_EVNTSEL3 0x00000EA4 - - -/** - Package. Uncore C-box 10 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C10_PMON_BOX_FILTER0 (0x00000EA5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_BOX_FILTER0 is defined as MSR_C10_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_BOX_FILTER0 0x00000EA5 - - -/** - Package. Uncore C-box 10 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C10_PMON_BOX_FILTER1 (0x00000EA6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_BOX_FILTER1 is defined as MSR_C10_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_BOX_FILTER1 0x00000EA6 - - -/** - Package. Uncore C-box 10 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C10_PMON_BOX_STATUS (0x00000EA7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_BOX_STATUS is defined as MSR_C10_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_BOX_STATUS 0x00000EA7 - - -/** - Package. Uncore C-box 10 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C10_PMON_CTR0 (0x00000EA8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_CTR0 is defined as MSR_C10_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_CTR0 0x00000EA8 - - -/** - Package. Uncore C-box 10 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C10_PMON_CTR1 (0x00000EA9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_CTR1 is defined as MSR_C10_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_CTR1 0x00000EA9 - - -/** - Package. Uncore C-box 10 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C10_PMON_CTR2 (0x00000EAA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_CTR2 is defined as MSR_C10_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_CTR2 0x00000EAA - - -/** - Package. Uncore C-box 10 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C10_PMON_CTR3 (0x00000EAB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C10_PMON_CTR3 is defined as MSR_C10_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C10_PMON_CTR3 0x00000EAB - - -/** - Package. Uncore C-box 11 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C11_PMON_BOX_CTL (0x00000EB0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_BOX_CTL is defined as MSR_C11_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_BOX_CTL 0x00000EB0 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 0. - - @param ECX MSR_HASWELL_E_C11_PMON_EVNTSEL0 (0x00000EB1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_EVNTSEL0 is defined as MSR_C11_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_EVNTSEL0 0x00000EB1 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 1. - - @param ECX MSR_HASWELL_E_C11_PMON_EVNTSEL1 (0x00000EB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_EVNTSEL1 is defined as MSR_C11_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_EVNTSEL1 0x00000EB2 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 2. - - @param ECX MSR_HASWELL_E_C11_PMON_EVNTSEL2 (0x00000EB3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_EVNTSEL2 is defined as MSR_C11_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_EVNTSEL2 0x00000EB3 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 3. - - @param ECX MSR_HASWELL_E_C11_PMON_EVNTSEL3 (0x00000EB4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_EVNTSEL3 is defined as MSR_C11_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_EVNTSEL3 0x00000EB4 - - -/** - Package. Uncore C-box 11 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C11_PMON_BOX_FILTER0 (0x00000EB5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_BOX_FILTER0 is defined as MSR_C11_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_BOX_FILTER0 0x00000EB5 - - -/** - Package. Uncore C-box 11 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C11_PMON_BOX_FILTER1 (0x00000EB6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_BOX_FILTER1 is defined as MSR_C11_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_BOX_FILTER1 0x00000EB6 - - -/** - Package. Uncore C-box 11 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C11_PMON_BOX_STATUS (0x00000EB7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_BOX_STATUS is defined as MSR_C11_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_BOX_STATUS 0x00000EB7 - - -/** - Package. Uncore C-box 11 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C11_PMON_CTR0 (0x00000EB8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_CTR0 is defined as MSR_C11_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_CTR0 0x00000EB8 - - -/** - Package. Uncore C-box 11 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C11_PMON_CTR1 (0x00000EB9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_CTR1 is defined as MSR_C11_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_CTR1 0x00000EB9 - - -/** - Package. Uncore C-box 11 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C11_PMON_CTR2 (0x00000EBA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_CTR2 is defined as MSR_C11_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_CTR2 0x00000EBA - - -/** - Package. Uncore C-box 11 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C11_PMON_CTR3 (0x00000EBB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C11_PMON_CTR3 is defined as MSR_C11_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C11_PMON_CTR3 0x00000EBB - - -/** - Package. Uncore C-box 12 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C12_PMON_BOX_CTL (0x00000EC0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_BOX_CTL is defined as MSR_C12_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_BOX_CTL 0x00000EC0 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 0. - - @param ECX MSR_HASWELL_E_C12_PMON_EVNTSEL0 (0x00000EC1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_EVNTSEL0 is defined as MSR_C12_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_EVNTSEL0 0x00000EC1 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 1. - - @param ECX MSR_HASWELL_E_C12_PMON_EVNTSEL1 (0x00000EC2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_EVNTSEL1 is defined as MSR_C12_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_EVNTSEL1 0x00000EC2 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 2. - - @param ECX MSR_HASWELL_E_C12_PMON_EVNTSEL2 (0x00000EC3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_EVNTSEL2 is defined as MSR_C12_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_EVNTSEL2 0x00000EC3 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 3. - - @param ECX MSR_HASWELL_E_C12_PMON_EVNTSEL3 (0x00000EC4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_EVNTSEL3 is defined as MSR_C12_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_EVNTSEL3 0x00000EC4 - - -/** - Package. Uncore C-box 12 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C12_PMON_BOX_FILTER0 (0x00000EC5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_BOX_FILTER0 is defined as MSR_C12_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_BOX_FILTER0 0x00000EC5 - - -/** - Package. Uncore C-box 12 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C12_PMON_BOX_FILTER1 (0x00000EC6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_BOX_FILTER1 is defined as MSR_C12_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_BOX_FILTER1 0x00000EC6 - - -/** - Package. Uncore C-box 12 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C12_PMON_BOX_STATUS (0x00000EC7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_BOX_STATUS is defined as MSR_C12_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_BOX_STATUS 0x00000EC7 - - -/** - Package. Uncore C-box 12 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C12_PMON_CTR0 (0x00000EC8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_CTR0 is defined as MSR_C12_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_CTR0 0x00000EC8 - - -/** - Package. Uncore C-box 12 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C12_PMON_CTR1 (0x00000EC9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_CTR1 is defined as MSR_C12_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_CTR1 0x00000EC9 - - -/** - Package. Uncore C-box 12 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C12_PMON_CTR2 (0x00000ECA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_CTR2 is defined as MSR_C12_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_CTR2 0x00000ECA - - -/** - Package. Uncore C-box 12 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C12_PMON_CTR3 (0x00000ECB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C12_PMON_CTR3 is defined as MSR_C12_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C12_PMON_CTR3 0x00000ECB - - -/** - Package. Uncore C-box 13 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C13_PMON_BOX_CTL (0x00000ED0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_BOX_CTL is defined as MSR_C13_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_BOX_CTL 0x00000ED0 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 0. - - @param ECX MSR_HASWELL_E_C13_PMON_EVNTSEL0 (0x00000ED1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_EVNTSEL0 is defined as MSR_C13_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_EVNTSEL0 0x00000ED1 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 1. - - @param ECX MSR_HASWELL_E_C13_PMON_EVNTSEL1 (0x00000ED2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_EVNTSEL1 is defined as MSR_C13_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_EVNTSEL1 0x00000ED2 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 2. - - @param ECX MSR_HASWELL_E_C13_PMON_EVNTSEL2 (0x00000ED3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_EVNTSEL2 is defined as MSR_C13_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_EVNTSEL2 0x00000ED3 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 3. - - @param ECX MSR_HASWELL_E_C13_PMON_EVNTSEL3 (0x00000ED4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_EVNTSEL3 is defined as MSR_C13_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_EVNTSEL3 0x00000ED4 - - -/** - Package. Uncore C-box 13 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C13_PMON_BOX_FILTER0 (0x00000ED5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_BOX_FILTER0 is defined as MSR_C13_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_BOX_FILTER0 0x00000ED5 - - -/** - Package. Uncore C-box 13 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C13_PMON_BOX_FILTER1 (0x00000ED6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_BOX_FILTER1 is defined as MSR_C13_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_BOX_FILTER1 0x00000ED6 - - -/** - Package. Uncore C-box 13 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C13_PMON_BOX_STATUS (0x00000ED7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_BOX_STATUS is defined as MSR_C13_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_BOX_STATUS 0x00000ED7 - - -/** - Package. Uncore C-box 13 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C13_PMON_CTR0 (0x00000ED8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_CTR0 is defined as MSR_C13_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_CTR0 0x00000ED8 - - -/** - Package. Uncore C-box 13 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C13_PMON_CTR1 (0x00000ED9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_CTR1 is defined as MSR_C13_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_CTR1 0x00000ED9 - - -/** - Package. Uncore C-box 13 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C13_PMON_CTR2 (0x00000EDA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_CTR2 is defined as MSR_C13_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_CTR2 0x00000EDA - - -/** - Package. Uncore C-box 13 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C13_PMON_CTR3 (0x00000EDB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C13_PMON_CTR3 is defined as MSR_C13_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C13_PMON_CTR3 0x00000EDB - - -/** - Package. Uncore C-box 14 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C14_PMON_BOX_CTL (0x00000EE0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_BOX_CTL is defined as MSR_C14_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_BOX_CTL 0x00000EE0 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 0. - - @param ECX MSR_HASWELL_E_C14_PMON_EVNTSEL0 (0x00000EE1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_EVNTSEL0 is defined as MSR_C14_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_EVNTSEL0 0x00000EE1 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 1. - - @param ECX MSR_HASWELL_E_C14_PMON_EVNTSEL1 (0x00000EE2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_EVNTSEL1 is defined as MSR_C14_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_EVNTSEL1 0x00000EE2 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 2. - - @param ECX MSR_HASWELL_E_C14_PMON_EVNTSEL2 (0x00000EE3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_EVNTSEL2 is defined as MSR_C14_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_EVNTSEL2 0x00000EE3 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 3. - - @param ECX MSR_HASWELL_E_C14_PMON_EVNTSEL3 (0x00000EE4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_EVNTSEL3 is defined as MSR_C14_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_EVNTSEL3 0x00000EE4 - - -/** - Package. Uncore C-box 14 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C14_PMON_BOX_FILTER (0x00000EE5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_BOX_FILTER is defined as MSR_C14_PMON_BOX_FILTER in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_BOX_FILTER 0x00000EE5 - - -/** - Package. Uncore C-box 14 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C14_PMON_BOX_FILTER1 (0x00000EE6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_BOX_FILTER1 is defined as MSR_C14_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_BOX_FILTER1 0x00000EE6 - - -/** - Package. Uncore C-box 14 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C14_PMON_BOX_STATUS (0x00000EE7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_BOX_STATUS is defined as MSR_C14_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_BOX_STATUS 0x00000EE7 - - -/** - Package. Uncore C-box 14 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C14_PMON_CTR0 (0x00000EE8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_CTR0 is defined as MSR_C14_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_CTR0 0x00000EE8 - - -/** - Package. Uncore C-box 14 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C14_PMON_CTR1 (0x00000EE9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_CTR1 is defined as MSR_C14_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_CTR1 0x00000EE9 - - -/** - Package. Uncore C-box 14 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C14_PMON_CTR2 (0x00000EEA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_CTR2 is defined as MSR_C14_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_CTR2 0x00000EEA - - -/** - Package. Uncore C-box 14 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C14_PMON_CTR3 (0x00000EEB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C14_PMON_CTR3 is defined as MSR_C14_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C14_PMON_CTR3 0x00000EEB - - -/** - Package. Uncore C-box 15 perfmon local box wide control. - - @param ECX MSR_HASWELL_E_C15_PMON_BOX_CTL (0x00000EF0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_BOX_CTL is defined as MSR_C15_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_BOX_CTL 0x00000EF0 - - -/** - Package. Uncore C-box 15 perfmon event select for C-box 15 counter 0. - - @param ECX MSR_HASWELL_E_C15_PMON_EVNTSEL0 (0x00000EF1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_EVNTSEL0 is defined as MSR_C15_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_EVNTSEL0 0x00000EF1 - - -/** - Package. Uncore C-box 15 perfmon event select for C-box 15 counter 1. - - @param ECX MSR_HASWELL_E_C15_PMON_EVNTSEL1 (0x00000EF2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_EVNTSEL1 is defined as MSR_C15_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_EVNTSEL1 0x00000EF2 - - -/** - Package. Uncore C-box 15 perfmon event select for C-box 15 counter 2. - - @param ECX MSR_HASWELL_E_C15_PMON_EVNTSEL2 (0x00000EF3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_EVNTSEL2 is defined as MSR_C15_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_EVNTSEL2 0x00000EF3 - - -/** - Package. Uncore C-box 15 perfmon event select for C-box 15 counter 3. - - @param ECX MSR_HASWELL_E_C15_PMON_EVNTSEL3 (0x00000EF4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_EVNTSEL3 is defined as MSR_C15_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_EVNTSEL3 0x00000EF4 - - -/** - Package. Uncore C-box 15 perfmon box wide filter0. - - @param ECX MSR_HASWELL_E_C15_PMON_BOX_FILTER0 (0x00000EF5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_BOX_FILTER0 is defined as MSR_C15_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_BOX_FILTER0 0x00000EF5 - - -/** - Package. Uncore C-box 15 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C15_PMON_BOX_FILTER1 (0x00000EF6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_BOX_FILTER1 is defined as MSR_C15_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_BOX_FILTER1 0x00000EF6 - - -/** - Package. Uncore C-box 15 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C15_PMON_BOX_STATUS (0x00000EF7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_BOX_STATUS is defined as MSR_C15_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_BOX_STATUS 0x00000EF7 - - -/** - Package. Uncore C-box 15 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C15_PMON_CTR0 (0x00000EF8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_CTR0 is defined as MSR_C15_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_CTR0 0x00000EF8 - - -/** - Package. Uncore C-box 15 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C15_PMON_CTR1 (0x00000EF9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_CTR1 is defined as MSR_C15_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_CTR1 0x00000EF9 - - -/** - Package. Uncore C-box 15 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C15_PMON_CTR2 (0x00000EFA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_CTR2 is defined as MSR_C15_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_CTR2 0x00000EFA - - -/** - Package. Uncore C-box 15 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C15_PMON_CTR3 (0x00000EFB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C15_PMON_CTR3 is defined as MSR_C15_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C15_PMON_CTR3 0x00000EFB - - -/** - Package. Uncore C-box 16 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C16_PMON_BOX_CTL (0x00000F00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_BOX_CTL is defined as MSR_C16_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_BOX_CTL 0x00000F00 - - -/** - Package. Uncore C-box 16 perfmon event select for C-box 16 counter 0. - - @param ECX MSR_HASWELL_E_C16_PMON_EVNTSEL0 (0x00000F01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_EVNTSEL0 is defined as MSR_C16_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_EVNTSEL0 0x00000F01 - - -/** - Package. Uncore C-box 16 perfmon event select for C-box 16 counter 1. - - @param ECX MSR_HASWELL_E_C16_PMON_EVNTSEL1 (0x00000F02) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_EVNTSEL1 is defined as MSR_C16_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_EVNTSEL1 0x00000F02 - - -/** - Package. Uncore C-box 16 perfmon event select for C-box 16 counter 2. - - @param ECX MSR_HASWELL_E_C16_PMON_EVNTSEL2 (0x00000F03) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_EVNTSEL2 is defined as MSR_C16_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_EVNTSEL2 0x00000F03 - - -/** - Package. Uncore C-box 16 perfmon event select for C-box 16 counter 3. - - @param ECX MSR_HASWELL_E_C16_PMON_EVNTSEL3 (0x00000F04) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_EVNTSEL3 is defined as MSR_C16_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_EVNTSEL3 0x00000F04 - - -/** - Package. Uncore C-box 16 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C16_PMON_BOX_FILTER0 (0x00000F05) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_BOX_FILTER0 is defined as MSR_C16_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_BOX_FILTER0 0x00000F05 - - -/** - Package. Uncore C-box 16 perfmon box wide filter 1. - - @param ECX MSR_HASWELL_E_C16_PMON_BOX_FILTER1 (0x00000F06) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_BOX_FILTER1 is defined as MSR_C16_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_BOX_FILTER1 0x00000F06 - - -/** - Package. Uncore C-box 16 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C16_PMON_BOX_STATUS (0x00000F07) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_BOX_STATUS is defined as MSR_C16_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_BOX_STATUS 0x00000F07 - - -/** - Package. Uncore C-box 16 perfmon counter 0. - - @param ECX MSR_HASWELL_E_C16_PMON_CTR0 (0x00000F08) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_CTR0 is defined as MSR_C16_PMON_CTR0 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_CTR0 0x00000F08 - - -/** - Package. Uncore C-box 16 perfmon counter 1. - - @param ECX MSR_HASWELL_E_C16_PMON_CTR1 (0x00000F09) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR1); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR1, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_CTR1 is defined as MSR_C16_PMON_CTR1 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_CTR1 0x00000F09 - - -/** - Package. Uncore C-box 16 perfmon counter 2. - - @param ECX MSR_HASWELL_E_C16_PMON_CTR2 (0x00000F0A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR2); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR2, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_CTR2 is defined as MSR_C16_PMON_CTR2 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_CTR2 0x00000F0A - - -/** - Package. Uncore C-box 16 perfmon counter 3. - - @param ECX MSR_HASWELL_E_C16_PMON_CTR3 (0x00000E0B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR3); - AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR3, Msr); - @endcode - @note MSR_HASWELL_E_C16_PMON_CTR3 is defined as MSR_C16_PMON_CTR3 in SDM. -**/ -#define MSR_HASWELL_E_C16_PMON_CTR3 0x00000E0B - - -/** - Package. Uncore C-box 17 perfmon for box-wide control. - - @param ECX MSR_HASWELL_E_C17_PMON_BOX_CTL (0x00000F10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_CTL, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_BOX_CTL is defined as MSR_C17_PMON_BOX_CTL in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_BOX_CTL 0x00000F10 - - -/** - Package. Uncore C-box 17 perfmon event select for C-box 17 counter 0. - - @param ECX MSR_HASWELL_E_C17_PMON_EVNTSEL0 (0x00000F11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_EVNTSEL0 is defined as MSR_C17_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_EVNTSEL0 0x00000F11 - - -/** - Package. Uncore C-box 17 perfmon event select for C-box 17 counter 1. - - @param ECX MSR_HASWELL_E_C17_PMON_EVNTSEL1 (0x00000F12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_EVNTSEL1 is defined as MSR_C17_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_EVNTSEL1 0x00000F12 - - -/** - Package. Uncore C-box 17 perfmon event select for C-box 17 counter 2. - - @param ECX MSR_HASWELL_E_C17_PMON_EVNTSEL2 (0x00000F13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_EVNTSEL2 is defined as MSR_C17_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_EVNTSEL2 0x00000F13 - - -/** - Package. Uncore C-box 17 perfmon event select for C-box 17 counter 3. - - @param ECX MSR_HASWELL_E_C17_PMON_EVNTSEL3 (0x00000F14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_EVNTSEL3 is defined as MSR_C17_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_EVNTSEL3 0x00000F14 - - -/** - Package. Uncore C-box 17 perfmon box wide filter 0. - - @param ECX MSR_HASWELL_E_C17_PMON_BOX_FILTER0 (0x00000F15) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER0); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER0, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_BOX_FILTER0 is defined as MSR_C17_PMON_BOX_FILTER0 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_BOX_FILTER0 0x00000F15 - - -/** - Package. Uncore C-box 17 perfmon box wide filter1. - - @param ECX MSR_HASWELL_E_C17_PMON_BOX_FILTER1 (0x00000F16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_BOX_FILTER1 is defined as MSR_C17_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_BOX_FILTER1 0x00000F16 - -/** - Package. Uncore C-box 17 perfmon box wide status. - - @param ECX MSR_HASWELL_E_C17_PMON_BOX_STATUS (0x00000F17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_BOX_STATUS is defined as MSR_C17_PMON_BOX_STATUS in SDM. -**/ -#define MSR_HASWELL_E_C17_PMON_BOX_STATUS 0x00000F17 - - -/** - Package. Uncore C-box 17 perfmon counter n. - - @param ECX MSR_HASWELL_E_C17_PMON_CTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_CTR0); - AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_CTR0, Msr); - @endcode - @note MSR_HASWELL_E_C17_PMON_CTR0 is defined as MSR_C17_PMON_CTR0 in SDM. - MSR_HASWELL_E_C17_PMON_CTR1 is defined as MSR_C17_PMON_CTR1 in SDM. - MSR_HASWELL_E_C17_PMON_CTR2 is defined as MSR_C17_PMON_CTR2 in SDM. - MSR_HASWELL_E_C17_PMON_CTR3 is defined as MSR_C17_PMON_CTR3 in SDM. - @{ -**/ -#define MSR_HASWELL_E_C17_PMON_CTR0 0x00000F18 -#define MSR_HASWELL_E_C17_PMON_CTR1 0x00000F19 -#define MSR_HASWELL_E_C17_PMON_CTR2 0x00000F1A -#define MSR_HASWELL_E_C17_PMON_CTR3 0x00000F1B -/// @} - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h deleted file mode 100644 index 3cd15846b..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h +++ /dev/null @@ -1,2637 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Haswell microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.11. - -**/ - -#ifndef __HASWELL_MSR_H__ -#define __HASWELL_MSR_H__ - -#include - -/** - Is Intel processors based on the Haswell microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_HASWELL_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x3C || \ - DisplayModel == 0x45 || \ - DisplayModel == 0x46 \ - ) \ - ) - -/** - Package. - - @param ECX MSR_HASWELL_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_HASWELL_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PLATFORM_INFO); - AsmWriteMsr64 (MSR_HASWELL_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_HASWELL_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_HASWELL_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_HASWELL_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - UINT32 Reserved3:2; - /// - /// [Bit 32] Package. Low Power Mode Support (LPM) (R/O) When set to 1, - /// indicates that LPM is supported, and when set to 0, indicates LPM is - /// not supported. - /// - UINT32 LowPowerModeSupport:1; - /// - /// [Bits 34:33] Package. Number of ConfigTDP Levels (R/O) 00: Only Base - /// TDP level available. 01: One additional TDP level available. 02: Two - /// additional TDP level available. 11: Reserved. - /// - UINT32 ConfigTDPLevels:2; - UINT32 Reserved4:5; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - /// - /// [Bits 55:48] Package. Minimum Operating Ratio (R/O) Contains the - /// minimum supported operating ratio in units of 100 MHz. - /// - UINT32 MinimumOperatingRatio:8; - UINT32 Reserved5:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PLATFORM_INFO_REGISTER; - - -/** - THREAD. Performance Event Select for Counter n (R/W) Supports all fields - described inTable 35-2 and the fields below. - - @param ECX MSR_HASWELL_IA32_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_IA32_PERFEVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_IA32_PERFEVTSEL_REGISTER. - - Example usage - @code - MSR_HASWELL_IA32_PERFEVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_IA32_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_IA32_PERFEVTSEL0, Msr.Uint64); - @endcode - @note MSR_HASWELL_IA32_PERFEVTSEL0 is defined as IA32_PERFEVTSEL0 in SDM. - MSR_HASWELL_IA32_PERFEVTSEL1 is defined as IA32_PERFEVTSEL1 in SDM. - MSR_HASWELL_IA32_PERFEVTSEL3 is defined as IA32_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_HASWELL_IA32_PERFEVTSEL0 0x00000186 -#define MSR_HASWELL_IA32_PERFEVTSEL1 0x00000187 -#define MSR_HASWELL_IA32_PERFEVTSEL3 0x00000189 -/// @} - -/** - MSR information returned for MSR indexes #MSR_HASWELL_IA32_PERFEVTSEL0, - #MSR_HASWELL_IA32_PERFEVTSEL1, and #MSR_HASWELL_IA32_PERFEVTSEL3. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Event Select: Selects a performance event logic unit. - /// - UINT32 EventSelect:8; - /// - /// [Bits 15:8] UMask: Qualifies the microarchitectural condition to - /// detect on the selected event logic. - /// - UINT32 UMASK:8; - /// - /// [Bit 16] USR: Counts while in privilege level is not ring 0. - /// - UINT32 USR:1; - /// - /// [Bit 17] OS: Counts while in privilege level is ring 0. - /// - UINT32 OS:1; - /// - /// [Bit 18] Edge: Enables edge detection if set. - /// - UINT32 E:1; - /// - /// [Bit 19] PC: enables pin control. - /// - UINT32 PC:1; - /// - /// [Bit 20] INT: enables interrupt on counter overflow. - /// - UINT32 INT:1; - /// - /// [Bit 21] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. - /// - UINT32 ANY:1; - /// - /// [Bit 22] EN: enables the corresponding performance counter to commence - /// counting when this bit is set. - /// - UINT32 EN:1; - /// - /// [Bit 23] INV: invert the CMASK. - /// - UINT32 INV:1; - /// - /// [Bits 31:24] CMASK: When CMASK is not zero, the corresponding - /// performance counter increments each cycle if the event count is - /// greater than or equal to the CMASK. - /// - UINT32 CMASK:8; - UINT32 Reserved:32; - /// - /// [Bit 32] IN_TX: see Section 18.11.5.1 When IN_TX (bit 32) is set, - /// AnyThread (bit 21) should be cleared to prevent incorrect results. - /// - UINT32 IN_TX:1; - UINT32 Reserved2:31; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_IA32_PERFEVTSEL_REGISTER; - - -/** - THREAD. Performance Event Select for Counter 2 (R/W) Supports all fields - described inTable 35-2 and the fields below. - - @param ECX MSR_HASWELL_IA32_PERFEVTSEL2 (0x00000188) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_IA32_PERFEVTSEL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_IA32_PERFEVTSEL2_REGISTER. - - Example usage - @code - MSR_HASWELL_IA32_PERFEVTSEL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_IA32_PERFEVTSEL2); - AsmWriteMsr64 (MSR_HASWELL_IA32_PERFEVTSEL2, Msr.Uint64); - @endcode - @note MSR_HASWELL_IA32_PERFEVTSEL2 is defined as IA32_PERFEVTSEL2 in SDM. -**/ -#define MSR_HASWELL_IA32_PERFEVTSEL2 0x00000188 - -/** - MSR information returned for MSR index #MSR_HASWELL_IA32_PERFEVTSEL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Event Select: Selects a performance event logic unit. - /// - UINT32 EventSelect:8; - /// - /// [Bits 15:8] UMask: Qualifies the microarchitectural condition to - /// detect on the selected event logic. - /// - UINT32 UMASK:8; - /// - /// [Bit 16] USR: Counts while in privilege level is not ring 0. - /// - UINT32 USR:1; - /// - /// [Bit 17] OS: Counts while in privilege level is ring 0. - /// - UINT32 OS:1; - /// - /// [Bit 18] Edge: Enables edge detection if set. - /// - UINT32 E:1; - /// - /// [Bit 19] PC: enables pin control. - /// - UINT32 PC:1; - /// - /// [Bit 20] INT: enables interrupt on counter overflow. - /// - UINT32 INT:1; - /// - /// [Bit 21] AnyThread: When set to 1, it enables counting the associated - /// event conditions occurring across all logical processors sharing a - /// processor core. When set to 0, the counter only increments the - /// associated event conditions occurring in the logical processor which - /// programmed the MSR. - /// - UINT32 ANY:1; - /// - /// [Bit 22] EN: enables the corresponding performance counter to commence - /// counting when this bit is set. - /// - UINT32 EN:1; - /// - /// [Bit 23] INV: invert the CMASK. - /// - UINT32 INV:1; - /// - /// [Bits 31:24] CMASK: When CMASK is not zero, the corresponding - /// performance counter increments each cycle if the event count is - /// greater than or equal to the CMASK. - /// - UINT32 CMASK:8; - UINT32 Reserved:32; - /// - /// [Bit 32] IN_TX: see Section 18.11.5.1 When IN_TX (bit 32) is set, - /// AnyThread (bit 21) should be cleared to prevent incorrect results. - /// - UINT32 IN_TX:1; - /// - /// [Bit 33] IN_TXCP: see Section 18.11.5.1 When IN_TXCP=1 & IN_TX=1 and - /// in sampling, spurious PMI may occur and transactions may continuously - /// abort near overflow conditions. Software should favor using IN_TXCP - /// for counting over sampling. If sampling, software should use large - /// "sample-after" value after clearing the counter configured to use - /// IN_TXCP and also always reset the counter even when no overflow - /// condition was reported. - /// - UINT32 IN_TXCP:1; - UINT32 Reserved2:30; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_IA32_PERFEVTSEL2_REGISTER; - - -/** - Thread. Last Branch Record Filtering Select Register (R/W). - - @param ECX MSR_HASWELL_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_LBR_SELECT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_LBR_SELECT_REGISTER. - - Example usage - @code - MSR_HASWELL_LBR_SELECT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_LBR_SELECT); - AsmWriteMsr64 (MSR_HASWELL_LBR_SELECT, Msr.Uint64); - @endcode - @note MSR_HASWELL_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_HASWELL_LBR_SELECT 0x000001C8 - -/** - MSR information returned for MSR index #MSR_HASWELL_LBR_SELECT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CPL_EQ_0. - /// - UINT32 CPL_EQ_0:1; - /// - /// [Bit 1] CPL_NEQ_0. - /// - UINT32 CPL_NEQ_0:1; - /// - /// [Bit 2] JCC. - /// - UINT32 JCC:1; - /// - /// [Bit 3] NEAR_REL_CALL. - /// - UINT32 NEAR_REL_CALL:1; - /// - /// [Bit 4] NEAR_IND_CALL. - /// - UINT32 NEAR_IND_CALL:1; - /// - /// [Bit 5] NEAR_RET. - /// - UINT32 NEAR_RET:1; - /// - /// [Bit 6] NEAR_IND_JMP. - /// - UINT32 NEAR_IND_JMP:1; - /// - /// [Bit 7] NEAR_REL_JMP. - /// - UINT32 NEAR_REL_JMP:1; - /// - /// [Bit 8] FAR_BRANCH. - /// - UINT32 FAR_BRANCH:1; - /// - /// [Bit 9] EN_CALL_STACK. - /// - UINT32 EN_CALL_STACK:1; - UINT32 Reserved1:22; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_LBR_SELECT_REGISTER; - - -/** - Package. Package C6/C7 Interrupt Response Limit 1 (R/W) This MSR defines - the interrupt response time limit used by the processor to manage transition - to package C6 or C7 state. The latency programmed in this register is for - the shorter-latency sub C-states used by an MWAIT hint to C6 or C7 state. - Note: C-state values are processor specific C-state code names, unrelated to - MWAIT extension C-state parameters or ACPI C-States. - - @param ECX MSR_HASWELL_PKGC_IRTL1 (0x0000060B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKGC_IRTL1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKGC_IRTL1_REGISTER. - - Example usage - @code - MSR_HASWELL_PKGC_IRTL1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKGC_IRTL1); - AsmWriteMsr64 (MSR_HASWELL_PKGC_IRTL1, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKGC_IRTL1 is defined as MSR_PKGC_IRTL1 in SDM. -**/ -#define MSR_HASWELL_PKGC_IRTL1 0x0000060B - -/** - MSR information returned for MSR index #MSR_HASWELL_PKGC_IRTL1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C6 or C7 state. - /// - UINT32 InterruptResponseTimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. See Table 35-18 for - /// supported time unit encodings. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKGC_IRTL1_REGISTER; - - -/** - Package. Package C6/C7 Interrupt Response Limit 2 (R/W) This MSR defines - the interrupt response time limit used by the processor to manage transition - to package C6 or C7 state. The latency programmed in this register is for - the longer-latency sub Cstates used by an MWAIT hint to C6 or C7 state. - Note: C-state values are processor specific C-state code names, unrelated to - MWAIT extension C-state parameters or ACPI C-States. - - @param ECX MSR_HASWELL_PKGC_IRTL2 (0x0000060C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKGC_IRTL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKGC_IRTL2_REGISTER. - - Example usage - @code - MSR_HASWELL_PKGC_IRTL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKGC_IRTL2); - AsmWriteMsr64 (MSR_HASWELL_PKGC_IRTL2, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKGC_IRTL2 is defined as MSR_PKGC_IRTL2 in SDM. -**/ -#define MSR_HASWELL_PKGC_IRTL2 0x0000060C - -/** - MSR information returned for MSR index #MSR_HASWELL_PKGC_IRTL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C6 or C7 state. - /// - UINT32 InterruptResponseTimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. See Table 35-18 for - /// supported time unit encodings. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKGC_IRTL2_REGISTER; - - -/** - Package. PKG Perf Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_HASWELL_PKG_PERF_STATUS (0x00000613) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_PKG_PERF_STATUS); - @endcode - @note MSR_HASWELL_PKG_PERF_STATUS is defined as MSR_PKG_PERF_STATUS in SDM. -**/ -#define MSR_HASWELL_PKG_PERF_STATUS 0x00000613 - - -/** - Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_HASWELL_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_DRAM_ENERGY_STATUS); - @endcode - @note MSR_HASWELL_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_HASWELL_DRAM_ENERGY_STATUS 0x00000619 - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_HASWELL_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_DRAM_PERF_STATUS); - @endcode - @note MSR_HASWELL_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_HASWELL_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. Base TDP Ratio (R/O). - - @param ECX MSR_HASWELL_CONFIG_TDP_NOMINAL (0x00000648) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_NOMINAL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_NOMINAL_REGISTER. - - Example usage - @code - MSR_HASWELL_CONFIG_TDP_NOMINAL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_NOMINAL); - @endcode - @note MSR_HASWELL_CONFIG_TDP_NOMINAL is defined as MSR_CONFIG_TDP_NOMINAL in SDM. -**/ -#define MSR_HASWELL_CONFIG_TDP_NOMINAL 0x00000648 - -/** - MSR information returned for MSR index #MSR_HASWELL_CONFIG_TDP_NOMINAL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Config_TDP_Base Base TDP level ratio to be used for this - /// specific processor (in units of 100 MHz). - /// - UINT32 Config_TDP_Base:8; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_CONFIG_TDP_NOMINAL_REGISTER; - - -/** - Package. ConfigTDP Level 1 ratio and power level (R/O). - - @param ECX MSR_HASWELL_CONFIG_TDP_LEVEL1 (0x00000649) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_LEVEL1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_LEVEL1_REGISTER. - - Example usage - @code - MSR_HASWELL_CONFIG_TDP_LEVEL1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_LEVEL1); - @endcode - @note MSR_HASWELL_CONFIG_TDP_LEVEL1 is defined as MSR_CONFIG_TDP_LEVEL1 in SDM. -**/ -#define MSR_HASWELL_CONFIG_TDP_LEVEL1 0x00000649 - -/** - MSR information returned for MSR index #MSR_HASWELL_CONFIG_TDP_LEVEL1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] PKG_TDP_LVL1. Power setting for ConfigTDP Level 1. - /// - UINT32 PKG_TDP_LVL1:15; - UINT32 Reserved1:1; - /// - /// [Bits 23:16] Config_TDP_LVL1_Ratio. ConfigTDP level 1 ratio to be used - /// for this specific processor. - /// - UINT32 Config_TDP_LVL1_Ratio:8; - UINT32 Reserved2:8; - /// - /// [Bits 46:32] PKG_MAX_PWR_LVL1. Max Power setting allowed for ConfigTDP - /// Level 1. - /// - UINT32 PKG_MAX_PWR_LVL1:15; - /// - /// [Bits 62:47] PKG_MIN_PWR_LVL1. MIN Power setting allowed for ConfigTDP - /// Level 1. - /// - UINT32 PKG_MIN_PWR_LVL1:16; - UINT32 Reserved3:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_CONFIG_TDP_LEVEL1_REGISTER; - - -/** - Package. ConfigTDP Level 2 ratio and power level (R/O). - - @param ECX MSR_HASWELL_CONFIG_TDP_LEVEL2 (0x0000064A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_LEVEL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_LEVEL2_REGISTER. - - Example usage - @code - MSR_HASWELL_CONFIG_TDP_LEVEL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_LEVEL2); - @endcode - @note MSR_HASWELL_CONFIG_TDP_LEVEL2 is defined as MSR_CONFIG_TDP_LEVEL2 in SDM. -**/ -#define MSR_HASWELL_CONFIG_TDP_LEVEL2 0x0000064A - -/** - MSR information returned for MSR index #MSR_HASWELL_CONFIG_TDP_LEVEL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] PKG_TDP_LVL2. Power setting for ConfigTDP Level 2. - /// - UINT32 PKG_TDP_LVL2:15; - UINT32 Reserved1:1; - /// - /// [Bits 23:16] Config_TDP_LVL2_Ratio. ConfigTDP level 2 ratio to be used - /// for this specific processor. - /// - UINT32 Config_TDP_LVL2_Ratio:8; - UINT32 Reserved2:8; - /// - /// [Bits 46:32] PKG_MAX_PWR_LVL2. Max Power setting allowed for ConfigTDP - /// Level 2. - /// - UINT32 PKG_MAX_PWR_LVL2:15; - /// - /// [Bits 62:47] PKG_MIN_PWR_LVL2. MIN Power setting allowed for ConfigTDP - /// Level 2. - /// - UINT32 PKG_MIN_PWR_LVL2:16; - UINT32 Reserved3:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_CONFIG_TDP_LEVEL2_REGISTER; - - -/** - Package. ConfigTDP Control (R/W). - - @param ECX MSR_HASWELL_CONFIG_TDP_CONTROL (0x0000064B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_CONFIG_TDP_CONTROL_REGISTER. - - Example usage - @code - MSR_HASWELL_CONFIG_TDP_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_CONTROL); - AsmWriteMsr64 (MSR_HASWELL_CONFIG_TDP_CONTROL, Msr.Uint64); - @endcode - @note MSR_HASWELL_CONFIG_TDP_CONTROL is defined as MSR_CONFIG_TDP_CONTROL in SDM. -**/ -#define MSR_HASWELL_CONFIG_TDP_CONTROL 0x0000064B - -/** - MSR information returned for MSR index #MSR_HASWELL_CONFIG_TDP_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] TDP_LEVEL (RW/L) System BIOS can program this field. - /// - UINT32 TDP_LEVEL:2; - UINT32 Reserved1:29; - /// - /// [Bit 31] Config_TDP_Lock (RW/L) When this bit is set, the content of - /// this register is locked until a reset. - /// - UINT32 Config_TDP_Lock:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_CONFIG_TDP_CONTROL_REGISTER; - - -/** - Package. ConfigTDP Control (R/W). - - @param ECX MSR_HASWELL_TURBO_ACTIVATION_RATIO (0x0000064C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_TURBO_ACTIVATION_RATIO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_TURBO_ACTIVATION_RATIO_REGISTER. - - Example usage - @code - MSR_HASWELL_TURBO_ACTIVATION_RATIO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_TURBO_ACTIVATION_RATIO); - AsmWriteMsr64 (MSR_HASWELL_TURBO_ACTIVATION_RATIO, Msr.Uint64); - @endcode - @note MSR_HASWELL_TURBO_ACTIVATION_RATIO is defined as MSR_TURBO_ACTIVATION_RATIO in SDM. -**/ -#define MSR_HASWELL_TURBO_ACTIVATION_RATIO 0x0000064C - -/** - MSR information returned for MSR index #MSR_HASWELL_TURBO_ACTIVATION_RATIO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] MAX_NON_TURBO_RATIO (RW/L) System BIOS can program this - /// field. - /// - UINT32 MAX_NON_TURBO_RATIO:8; - UINT32 Reserved1:23; - /// - /// [Bit 31] TURBO_ACTIVATION_RATIO_Lock (RW/L) When this bit is set, the - /// content of this register is locked until a reset. - /// - UINT32 TURBO_ACTIVATION_RATIO_Lock:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_TURBO_ACTIVATION_RATIO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are processor - specific C-state code names, unrelated to MWAIT extension C-state parameters - or ACPI Cstates. `See http://biosbits.org. `__. - - @param ECX MSR_HASWELL_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_HASWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_HASWELL_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_HASWELL_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_HASWELL_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power) for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 0000b: - /// C0/C1 (no package C-state support) 0001b: C2 0010b: C3 0011b: C6 - /// 0100b: C7 0101b: C7s Package C states C7 are not available to - /// processor with signature 06_3CH. - /// - UINT32 Limit:4; - UINT32 Reserved1:6; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W). - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO). - /// - UINT32 CFGLock:1; - UINT32 Reserved3:9; - /// - /// [Bit 25] C3 State Auto Demotion Enable (R/W). - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 State Auto Demotion Enable (R/W). - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 Undemotion (R/W). - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 Undemotion (R/W). - /// - UINT32 C1Undemotion:1; - UINT32 Reserved4:3; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - THREAD. Enhanced SMM Capabilities (SMM-RO) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_HASWELL_SMM_MCA_CAP (0x0000017D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_SMM_MCA_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_SMM_MCA_CAP_REGISTER. - - Example usage - @code - MSR_HASWELL_SMM_MCA_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_SMM_MCA_CAP); - AsmWriteMsr64 (MSR_HASWELL_SMM_MCA_CAP, Msr.Uint64); - @endcode - @note MSR_HASWELL_SMM_MCA_CAP is defined as MSR_SMM_MCA_CAP in SDM. -**/ -#define MSR_HASWELL_SMM_MCA_CAP 0x0000017D - -/** - MSR information returned for MSR index #MSR_HASWELL_SMM_MCA_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:26; - /// - /// [Bit 58] SMM_Code_Access_Chk (SMM-RO) If set to 1 indicates that the - /// SMM code access restriction is supported and the - /// MSR_SMM_FEATURE_CONTROL is supported. - /// - UINT32 SMM_Code_Access_Chk:1; - /// - /// [Bit 59] Long_Flow_Indication (SMM-RO) If set to 1 indicates that the - /// SMM long flow indicator is supported and the MSR_SMM_DELAYED is - /// supported. - /// - UINT32 Long_Flow_Indication:1; - UINT32 Reserved3:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_SMM_MCA_CAP_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_HASWELL_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_HASWELL_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_TURBO_RATIO_LIMIT); - @endcode - @note MSR_HASWELL_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_HASWELL_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_HASWELL_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. Uncore PMU global control. - - @param ECX MSR_HASWELL_UNC_PERF_GLOBAL_CTRL (0x00000391) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_GLOBAL_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_GLOBAL_CTRL_REGISTER. - - Example usage - @code - MSR_HASWELL_UNC_PERF_GLOBAL_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_HASWELL_UNC_PERF_GLOBAL_CTRL, Msr.Uint64); - @endcode - @note MSR_HASWELL_UNC_PERF_GLOBAL_CTRL is defined as MSR_UNC_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_HASWELL_UNC_PERF_GLOBAL_CTRL 0x00000391 - -/** - MSR information returned for MSR index #MSR_HASWELL_UNC_PERF_GLOBAL_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core 0 select. - /// - UINT32 PMI_Sel_Core0:1; - /// - /// [Bit 1] Core 1 select. - /// - UINT32 PMI_Sel_Core1:1; - /// - /// [Bit 2] Core 2 select. - /// - UINT32 PMI_Sel_Core2:1; - /// - /// [Bit 3] Core 3 select. - /// - UINT32 PMI_Sel_Core3:1; - UINT32 Reserved1:15; - UINT32 Reserved2:10; - /// - /// [Bit 29] Enable all uncore counters. - /// - UINT32 EN:1; - /// - /// [Bit 30] Enable wake on PMI. - /// - UINT32 WakePMI:1; - /// - /// [Bit 31] Enable Freezing counter when overflow. - /// - UINT32 FREEZE:1; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_UNC_PERF_GLOBAL_CTRL_REGISTER; - - -/** - Package. Uncore PMU main status. - - @param ECX MSR_HASWELL_UNC_PERF_GLOBAL_STATUS (0x00000392) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_HASWELL_UNC_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_HASWELL_UNC_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_HASWELL_UNC_PERF_GLOBAL_STATUS is defined as MSR_UNC_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_HASWELL_UNC_PERF_GLOBAL_STATUS 0x00000392 - -/** - MSR information returned for MSR index #MSR_HASWELL_UNC_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fixed counter overflowed. - /// - UINT32 Fixed:1; - /// - /// [Bit 1] An ARB counter overflowed. - /// - UINT32 ARB:1; - UINT32 Reserved1:1; - /// - /// [Bit 3] A CBox counter overflowed (on any slice). - /// - UINT32 CBox:1; - UINT32 Reserved2:28; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_UNC_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Package. Uncore fixed counter control (R/W). - - @param ECX MSR_HASWELL_UNC_PERF_FIXED_CTRL (0x00000394) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_FIXED_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_FIXED_CTRL_REGISTER. - - Example usage - @code - MSR_HASWELL_UNC_PERF_FIXED_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_PERF_FIXED_CTRL); - AsmWriteMsr64 (MSR_HASWELL_UNC_PERF_FIXED_CTRL, Msr.Uint64); - @endcode - @note MSR_HASWELL_UNC_PERF_FIXED_CTRL is defined as MSR_UNC_PERF_FIXED_CTRL in SDM. -**/ -#define MSR_HASWELL_UNC_PERF_FIXED_CTRL 0x00000394 - -/** - MSR information returned for MSR index #MSR_HASWELL_UNC_PERF_FIXED_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:20; - /// - /// [Bit 20] Enable overflow propagation. - /// - UINT32 EnableOverflow:1; - UINT32 Reserved2:1; - /// - /// [Bit 22] Enable counting. - /// - UINT32 EnableCounting:1; - UINT32 Reserved3:9; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_UNC_PERF_FIXED_CTRL_REGISTER; - - -/** - Package. Uncore fixed counter. - - @param ECX MSR_HASWELL_UNC_PERF_FIXED_CTR (0x00000395) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_FIXED_CTR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_PERF_FIXED_CTR_REGISTER. - - Example usage - @code - MSR_HASWELL_UNC_PERF_FIXED_CTR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_PERF_FIXED_CTR); - AsmWriteMsr64 (MSR_HASWELL_UNC_PERF_FIXED_CTR, Msr.Uint64); - @endcode - @note MSR_HASWELL_UNC_PERF_FIXED_CTR is defined as MSR_UNC_PERF_FIXED_CTR in SDM. -**/ -#define MSR_HASWELL_UNC_PERF_FIXED_CTR 0x00000395 - -/** - MSR information returned for MSR index #MSR_HASWELL_UNC_PERF_FIXED_CTR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Current count. - /// - UINT32 CurrentCount:32; - /// - /// [Bits 47:32] Current count. - /// - UINT32 CurrentCountHi:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_UNC_PERF_FIXED_CTR_REGISTER; - - -/** - Package. Uncore C-Box configuration information (R/O). - - @param ECX MSR_HASWELL_UNC_CBO_CONFIG (0x00000396) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_CBO_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_UNC_CBO_CONFIG_REGISTER. - - Example usage - @code - MSR_HASWELL_UNC_CBO_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_CONFIG); - @endcode - @note MSR_HASWELL_UNC_CBO_CONFIG is defined as MSR_UNC_CBO_CONFIG in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_CONFIG 0x00000396 - -/** - MSR information returned for MSR index #MSR_HASWELL_UNC_CBO_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Encoded number of C-Box, derive value by "-1". - /// - UINT32 CBox:4; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_UNC_CBO_CONFIG_REGISTER; - - -/** - Package. Uncore Arb unit, performance counter 0. - - @param ECX MSR_HASWELL_UNC_ARB_PERFCTR0 (0x000003B0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR0); - AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR0, Msr); - @endcode - @note MSR_HASWELL_UNC_ARB_PERFCTR0 is defined as MSR_UNC_ARB_PERFCTR0 in SDM. -**/ -#define MSR_HASWELL_UNC_ARB_PERFCTR0 0x000003B0 - - -/** - Package. Uncore Arb unit, performance counter 1. - - @param ECX MSR_HASWELL_UNC_ARB_PERFCTR1 (0x000003B1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR1); - AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR1, Msr); - @endcode - @note MSR_HASWELL_UNC_ARB_PERFCTR1 is defined as MSR_UNC_ARB_PERFCTR1 in SDM. -**/ -#define MSR_HASWELL_UNC_ARB_PERFCTR1 0x000003B1 - - -/** - Package. Uncore Arb unit, counter 0 event select MSR. - - @param ECX MSR_HASWELL_UNC_ARB_PERFEVTSEL0 (0x000003B2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL0, Msr); - @endcode - @note MSR_HASWELL_UNC_ARB_PERFEVTSEL0 is defined as MSR_UNC_ARB_PERFEVTSEL0 in SDM. -**/ -#define MSR_HASWELL_UNC_ARB_PERFEVTSEL0 0x000003B2 - - -/** - Package. Uncore Arb unit, counter 1 event select MSR. - - @param ECX MSR_HASWELL_UNC_ARB_PERFEVTSEL1 (0x000003B3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL1); - AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL1, Msr); - @endcode - @note MSR_HASWELL_UNC_ARB_PERFEVTSEL1 is defined as MSR_UNC_ARB_PERFEVTSEL1 in SDM. -**/ -#define MSR_HASWELL_UNC_ARB_PERFEVTSEL1 0x000003B3 - - -/** - Package. Enhanced SMM Feature Control (SMM-RW) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_HASWELL_SMM_FEATURE_CONTROL (0x000004E0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_SMM_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_SMM_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_HASWELL_SMM_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_SMM_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_HASWELL_SMM_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_HASWELL_SMM_FEATURE_CONTROL is defined as MSR_SMM_FEATURE_CONTROL in SDM. -**/ -#define MSR_HASWELL_SMM_FEATURE_CONTROL 0x000004E0 - -/** - MSR information returned for MSR index #MSR_HASWELL_SMM_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock (SMM-RWO) When set to '1' locks this register from - /// further changes. - /// - UINT32 Lock:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] SMM_Code_Chk_En (SMM-RW) This control bit is available only if - /// MSR_SMM_MCA_CAP[58] == 1. When set to '0' (default) none of the - /// logical processors are prevented from executing SMM code outside the - /// ranges defined by the SMRR. When set to '1' any logical processor in - /// the package that attempts to execute SMM code not within the ranges - /// defined by the SMRR will assert an unrecoverable MCE. - /// - UINT32 SMM_Code_Chk_En:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_SMM_FEATURE_CONTROL_REGISTER; - - -/** - Package. SMM Delayed (SMM-RO) Reports the interruptible state of all logical - processors in the package. Available only while in SMM and - MSR_SMM_MCA_CAP[LONG_FLOW_INDICATION] == 1. - - [Bits 31:0] LOG_PROC_STATE (SMM-RO) Each bit represents a logical - processor of its state in a long flow of internal operation which - delays servicing an interrupt. The corresponding bit will be set at - the start of long events such as: Microcode Update Load, C6, WBINVD, - Ratio Change, Throttle. The bit is automatically cleared at the end of - each long event. The reset value of this field is 0. Only bit - positions below N = CPUID.(EAX=0BH, ECX=PKG_LVL):EBX[15:0] can be - updated. - - [Bits 63:32] LOG_PROC_STATE (SMM-RO) Each bit represents a logical - processor of its state in a long flow of internal operation which - delays servicing an interrupt. The corresponding bit will be set at - the start of long events such as: Microcode Update Load, C6, WBINVD, - Ratio Change, Throttle. The bit is automatically cleared at the end of - each long event. The reset value of this field is 0. Only bit - positions below N = CPUID.(EAX=0BH, ECX=PKG_LVL):EBX[15:0] can be - updated. - - @param ECX MSR_HASWELL_SMM_DELAYED (0x000004E2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_SMM_DELAYED); - @endcode - @note MSR_HASWELL_SMM_DELAYED is defined as MSR_SMM_DELAYED in SDM. -**/ -#define MSR_HASWELL_SMM_DELAYED 0x000004E2 - - -/** - Package. SMM Blocked (SMM-RO) Reports the blocked state of all logical - processors in the package. Available only while in SMM. - - [Bits 31:0] LOG_PROC_STATE (SMM-RO) Each bit represents a logical - processor of its blocked state to service an SMI. The corresponding - bit will be set if the logical processor is in one of the following - states: Wait For SIPI or SENTER Sleep. The reset value of this field - is 0FFFH. Only bit positions below N = CPUID.(EAX=0BH, - ECX=PKG_LVL):EBX[15:0] can be updated. - - - [Bits 63:32] LOG_PROC_STATE (SMM-RO) Each bit represents a logical - processor of its blocked state to service an SMI. The corresponding - bit will be set if the logical processor is in one of the following - states: Wait For SIPI or SENTER Sleep. The reset value of this field - is 0FFFH. Only bit positions below N = CPUID.(EAX=0BH, - ECX=PKG_LVL):EBX[15:0] can be updated. - - @param ECX MSR_HASWELL_SMM_BLOCKED (0x000004E3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_SMM_BLOCKED); - @endcode - @note MSR_HASWELL_SMM_BLOCKED is defined as MSR_SMM_BLOCKED in SDM. -**/ -#define MSR_HASWELL_SMM_BLOCKED 0x000004E3 - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O). - - @param ECX MSR_HASWELL_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_HASWELL_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_RAPL_POWER_UNIT); - @endcode - @note MSR_HASWELL_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_HASWELL_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_HASWELL_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package. Power Units See Section 14.9.1, "RAPL Interfaces.". - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Package. Energy Status Units Energy related information - /// (in Joules) is based on the multiplier, 1/2^ESU; where ESU is an - /// unsigned integer represented by bits 12:8. Default value is 0EH (or 61 - /// micro-joules). - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Package. Time Units See Section 14.9.1, "RAPL - /// Interfaces.". - /// - UINT32 TimeUnits:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_HASWELL_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_PP0_ENERGY_STATUS); - @endcode - @note MSR_HASWELL_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_HASWELL_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. PP1 RAPL Power Limit Control (R/W) See Section 14.9.4, "PP0/PP1 - RAPL Domains.". - - @param ECX MSR_HASWELL_PP1_POWER_LIMIT (0x00000640) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_PP1_POWER_LIMIT); - AsmWriteMsr64 (MSR_HASWELL_PP1_POWER_LIMIT, Msr); - @endcode - @note MSR_HASWELL_PP1_POWER_LIMIT is defined as MSR_PP1_POWER_LIMIT in SDM. -**/ -#define MSR_HASWELL_PP1_POWER_LIMIT 0x00000640 - - -/** - Package. PP1 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_HASWELL_PP1_ENERGY_STATUS (0x00000641) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_PP1_ENERGY_STATUS); - @endcode - @note MSR_HASWELL_PP1_ENERGY_STATUS is defined as MSR_PP1_ENERGY_STATUS in SDM. -**/ -#define MSR_HASWELL_PP1_ENERGY_STATUS 0x00000641 - - -/** - Package. PP1 Balance Policy (R/W) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_HASWELL_PP1_POLICY (0x00000642) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_PP1_POLICY); - AsmWriteMsr64 (MSR_HASWELL_PP1_POLICY, Msr); - @endcode - @note MSR_HASWELL_PP1_POLICY is defined as MSR_PP1_POLICY in SDM. -**/ -#define MSR_HASWELL_PP1_POLICY 0x00000642 - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_HASWELL_CORE_PERF_LIMIT_REASONS (0x00000690) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_HASWELL_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_HASWELL_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_HASWELL_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_HASWELL_CORE_PERF_LIMIT_REASONS 0x00000690 - -/** - MSR information returned for MSR index #MSR_HASWELL_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, processor core frequency is - /// reduced below the operating system request due to assertion of - /// external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:2; - /// - /// [Bit 4] Graphics Driver Status (R0) When set, frequency is reduced - /// below the operating system request due to Processor Graphics driver - /// override. - /// - UINT32 GraphicsDriverStatus:1; - /// - /// [Bit 5] Autonomous Utilization-Based Frequency Control Status (R0) - /// When set, frequency is reduced below the operating system request - /// because the processor has detected that utilization is low. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - /// - /// [Bit 9] Core Power Limiting Status (R0) When set, frequency is reduced - /// below the operating system request due to domain-level power limiting. - /// - UINT32 PLStatus:1; - /// - /// [Bit 10] Package-Level Power Limiting PL1 Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL1. - /// - UINT32 PL1Status:1; - /// - /// [Bit 11] Package-Level PL2 Power Limiting Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL2. - /// - UINT32 PL2Status:1; - /// - /// [Bit 12] Max Turbo Limit Status (R0) When set, frequency is reduced - /// below the operating system request due to multi-core turbo limits. - /// - UINT32 MaxTurboLimitStatus:1; - /// - /// [Bit 13] Turbo Transition Attenuation Status (R0) When set, frequency - /// is reduced below the operating system request due to Turbo transition - /// attenuation. This prevents performance degradation due to frequent - /// operating ratio changes. - /// - UINT32 TurboTransitionAttenuationStatus:1; - UINT32 Reserved3:2; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved4:2; - /// - /// [Bit 20] Graphics Driver Log When set, indicates that the Graphics - /// Driver Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 GraphicsDriverLog:1; - /// - /// [Bit 21] Autonomous Utilization-Based Frequency Control Log When set, - /// indicates that the Autonomous Utilization-Based Frequency Control - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 24] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - /// - /// [Bit 25] Core Power Limiting Log When set, indicates that the Core - /// Power Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 PLLog:1; - /// - /// [Bit 26] Package-Level PL1 Power Limiting Log When set, indicates - /// that the Package Level PL1 Power Limiting Status bit has asserted - /// since the log bit was last cleared. This log bit will remain set until - /// cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package-Level PL2 Power Limiting Log When set, indicates that - /// the Package Level PL2 Power Limiting Status bit has asserted since the - /// log bit was last cleared. This log bit will remain set until cleared - /// by software writing 0. - /// - UINT32 PL2Log:1; - /// - /// [Bit 28] Max Turbo Limit Log When set, indicates that the Max Turbo - /// Limit Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MaxTurboLimitLog:1; - /// - /// [Bit 29] Turbo Transition Attenuation Log When set, indicates that the - /// Turbo Transition Attenuation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 TurboTransitionAttenuationLog:1; - UINT32 Reserved6:2; - UINT32 Reserved7:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_CORE_PERF_LIMIT_REASONS_REGISTER; - - -/** - Package. Indicator of Frequency Clipping in the Processor Graphics (R/W) - (frequency refers to processor graphics frequency). - - @param ECX MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS (0x000006B0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS is defined as MSR_GRAPHICS_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS 0x000006B0 - -/** - MSR information returned for MSR index - #MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, frequency is reduced below the - /// operating system request due to assertion of external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:2; - /// - /// [Bit 4] Graphics Driver Status (R0) When set, frequency is reduced - /// below the operating system request due to Processor Graphics driver - /// override. - /// - UINT32 GraphicsDriverStatus:1; - /// - /// [Bit 5] Autonomous Utilization-Based Frequency Control Status (R0) - /// When set, frequency is reduced below the operating system request - /// because the processor has detected that utilization is low. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - /// - /// [Bit 9] Graphics Power Limiting Status (R0) When set, frequency is - /// reduced below the operating system request due to domain-level power - /// limiting. - /// - UINT32 GraphicsPowerLimitingStatus:1; - /// - /// [Bit 10] Package-Level Power Limiting PL1 Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL1. - /// - UINT32 PL1STatus:1; - /// - /// [Bit 11] Package-Level PL2 Power Limiting Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL2. - /// - UINT32 PL2Status:1; - UINT32 Reserved3:4; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved4:2; - /// - /// [Bit 20] Graphics Driver Log When set, indicates that the Graphics - /// Driver Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 GraphicsDriverLog:1; - /// - /// [Bit 21] Autonomous Utilization-Based Frequency Control Log When set, - /// indicates that the Autonomous Utilization-Based Frequency Control - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 24] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - /// - /// [Bit 25] Core Power Limiting Log When set, indicates that the Core - /// Power Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CorePowerLimitingLog:1; - /// - /// [Bit 26] Package-Level PL1 Power Limiting Log When set, indicates - /// that the Package Level PL1 Power Limiting Status bit has asserted - /// since the log bit was last cleared. This log bit will remain set until - /// cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package-Level PL2 Power Limiting Log When set, indicates that - /// the Package Level PL2 Power Limiting Status bit has asserted since the - /// log bit was last cleared. This log bit will remain set until cleared - /// by software writing 0. - /// - UINT32 PL2Log:1; - /// - /// [Bit 28] Max Turbo Limit Log When set, indicates that the Max Turbo - /// Limit Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MaxTurboLimitLog:1; - /// - /// [Bit 29] Turbo Transition Attenuation Log When set, indicates that the - /// Turbo Transition Attenuation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 TurboTransitionAttenuationLog:1; - UINT32 Reserved6:2; - UINT32 Reserved7:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_GRAPHICS_PERF_LIMIT_REASONS_REGISTER; - - -/** - Package. Indicator of Frequency Clipping in the Ring Interconnect (R/W) - (frequency refers to ring interconnect in the uncore). - - @param ECX MSR_HASWELL_RING_PERF_LIMIT_REASONS (0x000006B1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_RING_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_RING_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_HASWELL_RING_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_RING_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_HASWELL_RING_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_HASWELL_RING_PERF_LIMIT_REASONS is defined as MSR_RING_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_HASWELL_RING_PERF_LIMIT_REASONS 0x000006B1 - -/** - MSR information returned for MSR index #MSR_HASWELL_RING_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, frequency is reduced below the - /// operating system request due to assertion of external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:4; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - UINT32 Reserved3:1; - /// - /// [Bit 10] Package-Level Power Limiting PL1 Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL1. - /// - UINT32 PL1STatus:1; - /// - /// [Bit 11] Package-Level PL2 Power Limiting Status (R0) When set, - /// frequency is reduced below the operating system request due to - /// package-level power limiting PL2. - /// - UINT32 PL2Status:1; - UINT32 Reserved4:4; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved5:2; - /// - /// [Bit 20] Graphics Driver Log When set, indicates that the Graphics - /// Driver Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 GraphicsDriverLog:1; - /// - /// [Bit 21] Autonomous Utilization-Based Frequency Control Log When set, - /// indicates that the Autonomous Utilization-Based Frequency Control - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - UINT32 Reserved6:1; - /// - /// [Bit 24] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - /// - /// [Bit 25] Core Power Limiting Log When set, indicates that the Core - /// Power Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CorePowerLimitingLog:1; - /// - /// [Bit 26] Package-Level PL1 Power Limiting Log When set, indicates - /// that the Package Level PL1 Power Limiting Status bit has asserted - /// since the log bit was last cleared. This log bit will remain set until - /// cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package-Level PL2 Power Limiting Log When set, indicates that - /// the Package Level PL2 Power Limiting Status bit has asserted since the - /// log bit was last cleared. This log bit will remain set until cleared - /// by software writing 0. - /// - UINT32 PL2Log:1; - /// - /// [Bit 28] Max Turbo Limit Log When set, indicates that the Max Turbo - /// Limit Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MaxTurboLimitLog:1; - /// - /// [Bit 29] Turbo Transition Attenuation Log When set, indicates that the - /// Turbo Transition Attenuation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 TurboTransitionAttenuationLog:1; - UINT32 Reserved7:2; - UINT32 Reserved8:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_RING_PERF_LIMIT_REASONS_REGISTER; - - -/** - Package. Uncore C-Box 0, counter 0 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0 (0x00000700) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0 is defined as MSR_UNC_CBO_0_PERFEVTSEL0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0 0x00000700 - - -/** - Package. Uncore C-Box 0, counter 1 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1 (0x00000701) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1 is defined as MSR_UNC_CBO_0_PERFEVTSEL1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1 0x00000701 - - -/** - Package. Uncore C-Box 0, performance counter 0. - - @param ECX MSR_HASWELL_UNC_CBO_0_PERFCTR0 (0x00000706) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_0_PERFCTR0 is defined as MSR_UNC_CBO_0_PERFCTR0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_0_PERFCTR0 0x00000706 - - -/** - Package. Uncore C-Box 0, performance counter 1. - - @param ECX MSR_HASWELL_UNC_CBO_0_PERFCTR1 (0x00000707) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_0_PERFCTR1 is defined as MSR_UNC_CBO_0_PERFCTR1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_0_PERFCTR1 0x00000707 - - -/** - Package. Uncore C-Box 1, counter 0 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0 (0x00000710) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0 is defined as MSR_UNC_CBO_1_PERFEVTSEL0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0 0x00000710 - - -/** - Package. Uncore C-Box 1, counter 1 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1 (0x00000711) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1 is defined as MSR_UNC_CBO_1_PERFEVTSEL1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1 0x00000711 - - -/** - Package. Uncore C-Box 1, performance counter 0. - - @param ECX MSR_HASWELL_UNC_CBO_1_PERFCTR0 (0x00000716) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_1_PERFCTR0 is defined as MSR_UNC_CBO_1_PERFCTR0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_1_PERFCTR0 0x00000716 - - -/** - Package. Uncore C-Box 1, performance counter 1. - - @param ECX MSR_HASWELL_UNC_CBO_1_PERFCTR1 (0x00000717) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_1_PERFCTR1 is defined as MSR_UNC_CBO_1_PERFCTR1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_1_PERFCTR1 0x00000717 - - -/** - Package. Uncore C-Box 2, counter 0 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0 (0x00000720) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0 is defined as MSR_UNC_CBO_2_PERFEVTSEL0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0 0x00000720 - - -/** - Package. Uncore C-Box 2, counter 1 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1 (0x00000721) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1 is defined as MSR_UNC_CBO_2_PERFEVTSEL1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1 0x00000721 - - -/** - Package. Uncore C-Box 2, performance counter 0. - - @param ECX MSR_HASWELL_UNC_CBO_2_PERFCTR0 (0x00000726) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_2_PERFCTR0 is defined as MSR_UNC_CBO_2_PERFCTR0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_2_PERFCTR0 0x00000726 - - -/** - Package. Uncore C-Box 2, performance counter 1. - - @param ECX MSR_HASWELL_UNC_CBO_2_PERFCTR1 (0x00000727) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_2_PERFCTR1 is defined as MSR_UNC_CBO_2_PERFCTR1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_2_PERFCTR1 0x00000727 - - -/** - Package. Uncore C-Box 3, counter 0 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0 (0x00000730) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0 is defined as MSR_UNC_CBO_3_PERFEVTSEL0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0 0x00000730 - - -/** - Package. Uncore C-Box 3, counter 1 event select MSR. - - @param ECX MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1 (0x00000731) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1 is defined as MSR_UNC_CBO_3_PERFEVTSEL1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1 0x00000731 - - -/** - Package. Uncore C-Box 3, performance counter 0. - - @param ECX MSR_HASWELL_UNC_CBO_3_PERFCTR0 (0x00000736) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR0); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR0, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_3_PERFCTR0 is defined as MSR_UNC_CBO_3_PERFCTR0 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_3_PERFCTR0 0x00000736 - - -/** - Package. Uncore C-Box 3, performance counter 1. - - @param ECX MSR_HASWELL_UNC_CBO_3_PERFCTR1 (0x00000737) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR1); - AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR1, Msr); - @endcode - @note MSR_HASWELL_UNC_CBO_3_PERFCTR1 is defined as MSR_UNC_CBO_3_PERFCTR1 in SDM. -**/ -#define MSR_HASWELL_UNC_CBO_3_PERFCTR1 0x00000737 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. - - @param ECX MSR_HASWELL_PKG_C8_RESIDENCY (0x00000630) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C8_RESIDENCY_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C8_RESIDENCY_REGISTER. - - Example usage - @code - MSR_HASWELL_PKG_C8_RESIDENCY_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKG_C8_RESIDENCY); - AsmWriteMsr64 (MSR_HASWELL_PKG_C8_RESIDENCY, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKG_C8_RESIDENCY is defined as MSR_PKG_C8_RESIDENCY in SDM. -**/ -#define MSR_HASWELL_PKG_C8_RESIDENCY 0x00000630 - -/** - MSR information returned for MSR index #MSR_HASWELL_PKG_C8_RESIDENCY -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Package C8 Residency Counter. (R/O) Value since last reset - /// that this package is in processor-specific C8 states. Count at the - /// same frequency as the TSC. - /// - UINT32 C8ResidencyCounter:32; - /// - /// [Bits 59:32] Package C8 Residency Counter. (R/O) Value since last - /// reset that this package is in processor-specific C8 states. Count at - /// the same frequency as the TSC. - /// - UINT32 C8ResidencyCounterHi:28; - UINT32 Reserved:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKG_C8_RESIDENCY_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. - - @param ECX MSR_HASWELL_PKG_C9_RESIDENCY (0x00000631) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C9_RESIDENCY_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C9_RESIDENCY_REGISTER. - - Example usage - @code - MSR_HASWELL_PKG_C9_RESIDENCY_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKG_C9_RESIDENCY); - AsmWriteMsr64 (MSR_HASWELL_PKG_C9_RESIDENCY, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKG_C9_RESIDENCY is defined as MSR_PKG_C9_RESIDENCY in SDM. -**/ -#define MSR_HASWELL_PKG_C9_RESIDENCY 0x00000631 - -/** - MSR information returned for MSR index #MSR_HASWELL_PKG_C9_RESIDENCY -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Package C9 Residency Counter. (R/O) Value since last reset - /// that this package is in processor-specific C9 states. Count at the - /// same frequency as the TSC. - /// - UINT32 C9ResidencyCounter:32; - /// - /// [Bits 59:32] Package C9 Residency Counter. (R/O) Value since last - /// reset that this package is in processor-specific C9 states. Count at - /// the same frequency as the TSC. - /// - UINT32 C9ResidencyCounterHi:28; - UINT32 Reserved:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKG_C9_RESIDENCY_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. - - @param ECX MSR_HASWELL_PKG_C10_RESIDENCY (0x00000632) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C10_RESIDENCY_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_HASWELL_PKG_C10_RESIDENCY_REGISTER. - - Example usage - @code - MSR_HASWELL_PKG_C10_RESIDENCY_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKG_C10_RESIDENCY); - AsmWriteMsr64 (MSR_HASWELL_PKG_C10_RESIDENCY, Msr.Uint64); - @endcode - @note MSR_HASWELL_PKG_C10_RESIDENCY is defined as MSR_PKG_C10_RESIDENCY in SDM. -**/ -#define MSR_HASWELL_PKG_C10_RESIDENCY 0x00000632 - -/** - MSR information returned for MSR index #MSR_HASWELL_PKG_C10_RESIDENCY -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Package C10 Residency Counter. (R/O) Value since last - /// reset that this package is in processor-specific C10 states. Count at - /// the same frequency as the TSC. - /// - UINT32 C10ResidencyCounter:32; - /// - /// [Bits 59:32] Package C10 Residency Counter. (R/O) Value since last - /// reset that this package is in processor-specific C10 states. Count at - /// the same frequency as the TSC. - /// - UINT32 C10ResidencyCounterHi:28; - UINT32 Reserved:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_HASWELL_PKG_C10_RESIDENCY_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h deleted file mode 100644 index 39b0d1af1..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h +++ /dev/null @@ -1,2893 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Ivy Bridge microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.10. - -**/ - -#ifndef __IVY_BRIDGE_MSR_H__ -#define __IVY_BRIDGE_MSR_H__ - -#include - -/** - Is Intel processors based on the Ivy Bridge microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_IVY_BRIDGE_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x3A || \ - DisplayModel == 0x3E \ - ) \ - ) - -/** - Package. See http://biosbits.org. - - @param ECX MSR_IVY_BRIDGE_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_IVY_BRIDGE_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - UINT32 Reserved3:2; - /// - /// [Bit 32] Package. Low Power Mode Support (LPM) (R/O) When set to 1, - /// indicates that LPM is supported, and when set to 0, indicates LPM is - /// not supported. - /// - UINT32 LowPowerModeSupport:1; - /// - /// [Bits 34:33] Package. Number of ConfigTDP Levels (R/O) 00: Only Base - /// TDP level available. 01: One additional TDP level available. 02: Two - /// additional TDP level available. 11: Reserved. - /// - UINT32 ConfigTDPLevels:2; - UINT32 Reserved4:5; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - /// - /// [Bits 55:48] Package. Minimum Operating Ratio (R/O) Contains the - /// minimum supported operating ratio in units of 100 MHz. - /// - UINT32 MinimumOperatingRatio:8; - UINT32 Reserved5:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_PLATFORM_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI C-States. See http://biosbits.org. - - @param ECX MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power). for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0/C1 (no package C-sate support) 001b: C2 010b: C6 no retention 011b: - /// C6 retention 100b: C7 101b: C7s 111: No package C-state limit. Note: - /// This field cannot be used to limit package C-state to C3. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W) When set, will map - /// IO_read instructions sent to IO register specified by - /// MSR_PMG_IO_CAPTURE_BASE to MWAIT instructions. - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO) When set, lock bits 15:0 of this register - /// until next reset. - /// - UINT32 CFGLock:1; - UINT32 Reserved3:9; - /// - /// [Bit 25] C3 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C6/C7 requests to C3 based on uncore - /// auto-demote information. - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C3/C6/C7 requests to C1 based on uncore - /// auto-demote information. - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 undemotion (R/W) When set, enables undemotion from - /// demoted C3. - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 undemotion (R/W) When set, enables undemotion from - /// demoted C1. - /// - UINT32 C1Undemotion:1; - UINT32 Reserved4:3; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_IVY_BRIDGE_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PP0_ENERGY_STATUS); - @endcode - @note MSR_IVY_BRIDGE_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. Base TDP Ratio (R/O). - - @param ECX MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL (0x00000648) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL); - @endcode - @note MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL is defined as MSR_CONFIG_TDP_NOMINAL in SDM. -**/ -#define MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL 0x00000648 - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Config_TDP_Base Base TDP level ratio to be used for this - /// specific processor (in units of 100 MHz). - /// - UINT32 Config_TDP_Base:8; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL_REGISTER; - - -/** - Package. ConfigTDP Level 1 ratio and power level (R/O). - - @param ECX MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1 (0x00000649) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1); - @endcode - @note MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1 is defined as MSR_CONFIG_TDP_LEVEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1 0x00000649 - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] PKG_TDP_LVL1. Power setting for ConfigTDP Level 1. - /// - UINT32 PKG_TDP_LVL1:15; - UINT32 Reserved1:1; - /// - /// [Bits 23:16] Config_TDP_LVL1_Ratio. ConfigTDP level 1 ratio to be used - /// for this specific processor. - /// - UINT32 Config_TDP_LVL1_Ratio:8; - UINT32 Reserved2:8; - /// - /// [Bits 46:32] PKG_MAX_PWR_LVL1. Max Power setting allowed for ConfigTDP - /// Level 1. - /// - UINT32 PKG_MAX_PWR_LVL1:15; - UINT32 Reserved3:1; - /// - /// [Bits 62:48] PKG_MIN_PWR_LVL1. MIN Power setting allowed for ConfigTDP - /// Level 1. - /// - UINT32 PKG_MIN_PWR_LVL1:15; - UINT32 Reserved4:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1_REGISTER; - - -/** - Package. ConfigTDP Level 2 ratio and power level (R/O). - - @param ECX MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2 (0x0000064A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2); - @endcode - @note MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2 is defined as MSR_CONFIG_TDP_LEVEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2 0x0000064A - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] PKG_TDP_LVL2. Power setting for ConfigTDP Level 2. - /// - UINT32 PKG_TDP_LVL2:15; - UINT32 Reserved1:1; - /// - /// [Bits 23:16] Config_TDP_LVL2_Ratio. ConfigTDP level 2 ratio to be used - /// for this specific processor. - /// - UINT32 Config_TDP_LVL2_Ratio:8; - UINT32 Reserved2:8; - /// - /// [Bits 46:32] PKG_MAX_PWR_LVL2. Max Power setting allowed for ConfigTDP - /// Level 2. - /// - UINT32 PKG_MAX_PWR_LVL2:15; - UINT32 Reserved3:1; - /// - /// [Bits 62:48] PKG_MIN_PWR_LVL2. MIN Power setting allowed for ConfigTDP - /// Level 2. - /// - UINT32 PKG_MIN_PWR_LVL2:15; - UINT32 Reserved4:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2_REGISTER; - - -/** - Package. ConfigTDP Control (R/W). - - @param ECX MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL (0x0000064B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL is defined as MSR_CONFIG_TDP_CONTROL in SDM. -**/ -#define MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL 0x0000064B - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] TDP_LEVEL (RW/L) System BIOS can program this field. - /// - UINT32 TDP_LEVEL:2; - UINT32 Reserved1:29; - /// - /// [Bit 31] Config_TDP_Lock (RW/L) When this bit is set, the content of - /// this register is locked until a reset. - /// - UINT32 Config_TDP_Lock:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_CONFIG_TDP_CONTROL_REGISTER; - - -/** - Package. ConfigTDP Control (R/W). - - @param ECX MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO (0x0000064C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO); - AsmWriteMsr64 (MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO is defined as MSR_TURBO_ACTIVATION_RATIO in SDM. -**/ -#define MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO 0x0000064C - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] MAX_NON_TURBO_RATIO (RW/L) System BIOS can program this - /// field. - /// - UINT32 MAX_NON_TURBO_RATIO:8; - UINT32 Reserved1:23; - /// - /// [Bit 31] TURBO_ACTIVATION_RATIO_Lock (RW/L) When this bit is set, the - /// content of this register is locked until a reset. - /// - UINT32 TURBO_ACTIVATION_RATIO_Lock:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_TURBO_ACTIVATION_RATIO_REGISTER; - - -/** - Package. Protected Processor Inventory Number Enable Control (R/W). - - @param ECX MSR_IVY_BRIDGE_PPIN_CTL (0x0000004E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PPIN_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PPIN_CTL_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_PPIN_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PPIN_CTL, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_PPIN_CTL is defined as MSR_PPIN_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_PPIN_CTL 0x0000004E - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_PPIN_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LockOut (R/WO) Set 1to prevent further writes to MSR_PPIN_CTL. - /// Writing 1 to MSR_PPINCTL[bit 0] is permitted only if MSR_PPIN_CTL[bit - /// 1] is clear, Default is 0. BIOS should provide an opt-in menu to - /// enable the user to turn on MSR_PPIN_CTL[bit 1] for privileged - /// inventory initialization agent to access MSR_PPIN. After reading - /// MSR_PPIN, the privileged inventory initialization agent should write - /// '01b' to MSR_PPIN_CTL to disable further access to MSR_PPIN and - /// prevent unauthorized modification to MSR_PPIN_CTL. - /// - UINT32 LockOut:1; - /// - /// [Bit 1] Enable_PPIN (R/W) If 1, enables MSR_PPIN to be accessible - /// using RDMSR. Once set, attempt to write 1 to MSR_PPIN_CTL[bit 0] will - /// cause #GP. If 0, an attempt to read MSR_PPIN will cause #GP. Default - /// is 0. - /// - UINT32 Enable_PPIN:1; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_PPIN_CTL_REGISTER; - - -/** - Package. Protected Processor Inventory Number (R/O). Protected Processor - Inventory Number (R/O) A unique value within a given CPUID - family/model/stepping signature that a privileged inventory initialization - agent can access to identify each physical processor, when access to - MSR_PPIN is enabled. Access to MSR_PPIN is permitted only if - MSR_PPIN_CTL[bits 1:0] = '10b'. - - @param ECX MSR_IVY_BRIDGE_PPIN (0x0000004F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN); - @endcode - @note MSR_IVY_BRIDGE_PPIN is defined as MSR_PPIN in SDM. -**/ -#define MSR_IVY_BRIDGE_PPIN 0x0000004F - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_IVY_BRIDGE_PLATFORM_INFO_1 (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO_1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO_1, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_PLATFORM_INFO_1 is defined as MSR_PLATFORM_INFO_1 in SDM. -**/ -#define MSR_IVY_BRIDGE_PLATFORM_INFO_1 0x000000CE - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_PLATFORM_INFO_1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:7; - /// - /// [Bit 23] Package. PPIN_CAP (R/O) When set to 1, indicates that - /// Protected Processor Inventory Number (PPIN) capability can be enabled - /// for privileged system inventory agent to read PPIN from MSR_PPIN. When - /// set to 0, PPIN capability is not supported. An attempt to access - /// MSR_PPIN_CTL or MSR_PPIN will cause #GP. - /// - UINT32 PPIN_CAP:1; - UINT32 Reserved3:4; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - /// - /// [Bit 30] Package. Programmable TJ OFFSET (R/O) When set to 1, - /// indicates that MSR_TEMPERATURE_TARGET.[27:24] is valid and writable to - /// specify an temperature offset. - /// - UINT32 TJOFFSET:1; - UINT32 Reserved4:1; - UINT32 Reserved5:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved6:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER; - - -/** - Package. MC Bank Error Configuration (R/W). - - @param ECX MSR_IVY_BRIDGE_ERROR_CONTROL (0x0000017F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_ERROR_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_ERROR_CONTROL_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_ERROR_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_ERROR_CONTROL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_ERROR_CONTROL, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_ERROR_CONTROL is defined as MSR_ERROR_CONTROL in SDM. -**/ -#define MSR_IVY_BRIDGE_ERROR_CONTROL 0x0000017F - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_ERROR_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] MemError Log Enable (R/W) When set, enables IMC status bank - /// to log additional info in bits 36:32. - /// - UINT32 MemErrorLogEnable:1; - UINT32 Reserved2:30; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_ERROR_CONTROL_REGISTER; - - -/** - Package. - - @param ECX MSR_IVY_BRIDGE_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_IVY_BRIDGE_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_IVY_BRIDGE_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (RO) The minimum temperature at which - /// PROCHOT# will be asserted. The value is degree C. - /// - UINT32 TemperatureTarget:8; - /// - /// [Bits 27:24] TCC Activation Offset (R/W) Specifies a temperature - /// offset in degrees C from the temperature target (bits 23:16). PROCHOT# - /// will assert at the offset target temperature. Write is permitted only - /// MSR_PLATFORM_INFO.[30] is set. - /// - UINT32 TCCActivationOffset:4; - UINT32 Reserved2:4; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_TEMPERATURE_TARGET_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1 (0x000001AE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1); - @endcode - @note MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1 is defined as MSR_TURBO_RATIO_LIMIT1 in SDM. -**/ -#define MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1 0x000001AE - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 9C Maximum turbo ratio - /// limit of 9 core active. - /// - UINT32 Maximum9C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 10C Maximum turbo ratio - /// limit of 10core active. - /// - UINT32 Maximum10C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 11C Maximum turbo ratio - /// limit of 11 core active. - /// - UINT32 Maximum11C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 12C Maximum turbo ratio - /// limit of 12 core active. - /// - UINT32 Maximum12C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 13C Maximum turbo ratio - /// limit of 13 core active. - /// - UINT32 Maximum13C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 14C Maximum turbo ratio - /// limit of 14 core active. - /// - UINT32 Maximum14C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 15C Maximum turbo ratio - /// limit of 15 core active. - /// - UINT32 Maximum15C:8; - UINT32 Reserved:7; - /// - /// [Bit 63] Package. Semaphore for Turbo Ratio Limit Configuration If 1, - /// the processor uses override configuration specified in - /// MSR_TURBO_RATIO_LIMIT and MSR_TURBO_RATIO_LIMIT1. If 0, the processor - /// uses factory-set configuration (Default). - /// - UINT32 TurboRatioLimitConfigurationSemaphore:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1_REGISTER; - - -/** - Package. Misc MAC information of Integrated I/O. (R/O) see Section 15.3.2.4. - - @param ECX MSR_IVY_BRIDGE_IA32_MC6_MISC (0x0000041B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_IA32_MC6_MISC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_IA32_MC6_MISC_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_IA32_MC6_MISC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC6_MISC); - @endcode - @note MSR_IVY_BRIDGE_IA32_MC6_MISC is defined as IA32_MC6_MISC in SDM. -**/ -#define MSR_IVY_BRIDGE_IA32_MC6_MISC 0x0000041B - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_IA32_MC6_MISC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 5:0] Recoverable Address LSB. - /// - UINT32 RecoverableAddressLSB:6; - /// - /// [Bits 8:6] Address Mode. - /// - UINT32 AddressMode:3; - UINT32 Reserved1:7; - /// - /// [Bits 31:16] PCI Express Requestor ID. - /// - UINT32 PCIExpressRequestorID:16; - /// - /// [Bits 39:32] PCI Express Segment Number. - /// - UINT32 PCIExpressSegmentNumber:8; - UINT32 Reserved2:24; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_IA32_MC6_MISC_REGISTER; - - -/** - Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section - 15.3.2.4, "IA32_MCi_MISC MSRs.". - - Bank MC29 through MC31 reports MC error from a specific CBo (core broadcast) - and its corresponding slice of L3. - - @param ECX MSR_IVY_BRIDGE_IA32_MCi_CTL - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC29_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_IA32_MC29_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_IA32_MC29_CTL is defined as IA32_MC29_CTL in SDM. - MSR_IVY_BRIDGE_IA32_MC30_CTL is defined as IA32_MC30_CTL in SDM. - MSR_IVY_BRIDGE_IA32_MC31_CTL is defined as IA32_MC31_CTL in SDM. - @{ -**/ -#define MSR_IVY_BRIDGE_IA32_MC29_CTL 0x00000474 -#define MSR_IVY_BRIDGE_IA32_MC30_CTL 0x00000478 -#define MSR_IVY_BRIDGE_IA32_MC31_CTL 0x0000047C -/// @} - - -/** - Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section - 15.3.2.4, "IA32_MCi_MISC MSRs.". - - Bank MC29 through MC31 reports MC error from a specific CBo (core broadcast) - and its corresponding slice of L3. - - @param ECX MSR_IVY_BRIDGE_IA32_MCi_STATUS - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC29_STATUS); - AsmWriteMsr64 (MSR_IVY_BRIDGE_IA32_MC29_STATUS, Msr); - @endcode - @note MSR_IVY_BRIDGE_IA32_MC29_STATUS is defined as IA32_MC29_STATUS in SDM. - MSR_IVY_BRIDGE_IA32_MC30_STATUS is defined as IA32_MC30_STATUS in SDM. - MSR_IVY_BRIDGE_IA32_MC31_STATUS is defined as IA32_MC31_STATUS in SDM. - @{ -**/ -#define MSR_IVY_BRIDGE_IA32_MC29_STATUS 0x00000475 -#define MSR_IVY_BRIDGE_IA32_MC30_STATUS 0x00000479 -#define MSR_IVY_BRIDGE_IA32_MC31_STATUS 0x0000047D -/// @} - - -/** - Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section - 15.3.2.4, "IA32_MCi_MISC MSRs.". - - Bank MC29 through MC31 reports MC error from a specific CBo (core broadcast) - and its corresponding slice of L3. - - @param ECX MSR_IVY_BRIDGE_IA32_MCi_ADDR - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC29_ADDR); - AsmWriteMsr64 (MSR_IVY_BRIDGE_IA32_MC29_ADDR, Msr); - @endcode - @note MSR_IVY_BRIDGE_IA32_MC29_ADDR is defined as IA32_MC29_ADDR in SDM. - MSR_IVY_BRIDGE_IA32_MC30_ADDR is defined as IA32_MC30_ADDR in SDM. - MSR_IVY_BRIDGE_IA32_MC31_ADDR is defined as IA32_MC31_ADDR in SDM. - @{ -**/ -#define MSR_IVY_BRIDGE_IA32_MC29_ADDR 0x00000476 -#define MSR_IVY_BRIDGE_IA32_MC30_ADDR 0x0000047A -#define MSR_IVY_BRIDGE_IA32_MC31_ADDR 0x0000047E -/// @} - - -/** - Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section - 15.3.2.4, "IA32_MCi_MISC MSRs.". - - Bank MC29 through MC31 reports MC error from a specific CBo (core broadcast) - and its corresponding slice of L3. - - @param ECX MSR_IVY_BRIDGE_IA32_MCi_MISC - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC29_MISC); - AsmWriteMsr64 (MSR_IVY_BRIDGE_IA32_MC29_MISC, Msr); - @endcode - @note MSR_IVY_BRIDGE_IA32_MC29_MISC is defined as IA32_MC29_MISC in SDM. - MSR_IVY_BRIDGE_IA32_MC30_MISC is defined as IA32_MC30_MISC in SDM. - MSR_IVY_BRIDGE_IA32_MC31_MISC is defined as IA32_MC31_MISC in SDM. - @{ -**/ -#define MSR_IVY_BRIDGE_IA32_MC29_MISC 0x00000477 -#define MSR_IVY_BRIDGE_IA32_MC30_MISC 0x0000047B -#define MSR_IVY_BRIDGE_IA32_MC31_MISC 0x0000047F -/// @} - - -/** - Package. Package RAPL Perf Status (R/O). - - @param ECX MSR_IVY_BRIDGE_PKG_PERF_STATUS (0x00000613) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PKG_PERF_STATUS); - @endcode - @note MSR_IVY_BRIDGE_PKG_PERF_STATUS is defined as MSR_PKG_PERF_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_PKG_PERF_STATUS 0x00000613 - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_IVY_BRIDGE_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_IVY_BRIDGE_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_IVY_BRIDGE_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_IVY_BRIDGE_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_ENERGY_STATUS); - @endcode - @note MSR_IVY_BRIDGE_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_DRAM_ENERGY_STATUS 0x00000619 - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_IVY_BRIDGE_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_PERF_STATUS); - @endcode - @note MSR_IVY_BRIDGE_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_IVY_BRIDGE_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_IVY_BRIDGE_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_IVY_BRIDGE_DRAM_POWER_INFO 0x0000061C - - -/** - Thread. See Section 18.8.1.1, "Precise Event Based Sampling (PEBS).". - - @param ECX MSR_IVY_BRIDGE_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_IVY_BRIDGE_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_IVY_BRIDGE_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PEBS_ENABLE); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_IVY_BRIDGE_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_IVY_BRIDGE_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_IVY_BRIDGE_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. (R/W). - /// - UINT32 PEBS_EN_PMC0:1; - /// - /// [Bit 1] Enable PEBS on IA32_PMC1. (R/W). - /// - UINT32 PEBS_EN_PMC1:1; - /// - /// [Bit 2] Enable PEBS on IA32_PMC2. (R/W). - /// - UINT32 PEBS_EN_PMC2:1; - /// - /// [Bit 3] Enable PEBS on IA32_PMC3. (R/W). - /// - UINT32 PEBS_EN_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Enable Load Latency on IA32_PMC0. (R/W). - /// - UINT32 LL_EN_PMC0:1; - /// - /// [Bit 33] Enable Load Latency on IA32_PMC1. (R/W). - /// - UINT32 LL_EN_PMC1:1; - /// - /// [Bit 34] Enable Load Latency on IA32_PMC2. (R/W). - /// - UINT32 LL_EN_PMC2:1; - /// - /// [Bit 35] Enable Load Latency on IA32_PMC3. (R/W). - /// - UINT32 LL_EN_PMC3:1; - UINT32 Reserved2:28; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_IVY_BRIDGE_PEBS_ENABLE_REGISTER; - - -/** - Package. Uncore perfmon per-socket global control. - - @param ECX MSR_IVY_BRIDGE_PMON_GLOBAL_CTL (0x00000C00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_PMON_GLOBAL_CTL is defined as MSR_PMON_GLOBAL_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_PMON_GLOBAL_CTL 0x00000C00 - - -/** - Package. Uncore perfmon per-socket global status. - - @param ECX MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS (0x00000C01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS, Msr); - @endcode - @note MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS is defined as MSR_PMON_GLOBAL_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS 0x00000C01 - - -/** - Package. Uncore perfmon per-socket global configuration. - - @param ECX MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG (0x00000C06) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG, Msr); - @endcode - @note MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG is defined as MSR_PMON_GLOBAL_CONFIG in SDM. -**/ -#define MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG 0x00000C06 - - -/** - Package. Uncore U-box perfmon U-box wide status. - - @param ECX MSR_IVY_BRIDGE_U_PMON_BOX_STATUS (0x00000C15) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_U_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_IVY_BRIDGE_U_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_IVY_BRIDGE_U_PMON_BOX_STATUS is defined as MSR_U_PMON_BOX_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_U_PMON_BOX_STATUS 0x00000C15 - - -/** - Package. Uncore PCU perfmon box wide status. - - @param ECX MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS (0x00000C35) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS is defined as MSR_PCU_PMON_BOX_STATUS in SDM. -**/ -#define MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS 0x00000C35 - - -/** - Package. Uncore C-box 0 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1 (0x00000D1A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1 is defined as MSR_C0_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1 0x00000D1A - - -/** - Package. Uncore C-box 1 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1 (0x00000D3A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1 is defined as MSR_C1_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1 0x00000D3A - - -/** - Package. Uncore C-box 2 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1 (0x00000D5A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1 is defined as MSR_C2_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1 0x00000D5A - - -/** - Package. Uncore C-box 3 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1 (0x00000D7A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1 is defined as MSR_C3_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1 0x00000D7A - - -/** - Package. Uncore C-box 4 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1 (0x00000D9A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1 is defined as MSR_C4_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1 0x00000D9A - - -/** - Package. Uncore C-box 5 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1 (0x00000DBA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1 is defined as MSR_C5_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1 0x00000DBA - - -/** - Package. Uncore C-box 6 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1 (0x00000DDA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1 is defined as MSR_C6_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1 0x00000DDA - - -/** - Package. Uncore C-box 7 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1 (0x00000DFA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1 is defined as MSR_C7_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1 0x00000DFA - - -/** - Package. Uncore C-box 8 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_BOX_CTL (0x00000E04) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_BOX_CTL is defined as MSR_C8_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_BOX_CTL 0x00000E04 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 0. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0 (0x00000E10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0 is defined as MSR_C8_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0 0x00000E10 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 1. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1 (0x00000E11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1 is defined as MSR_C8_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1 0x00000E11 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 2. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2 (0x00000E12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2 is defined as MSR_C8_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2 0x00000E12 - - -/** - Package. Uncore C-box 8 perfmon event select for C-box 8 counter 3. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3 (0x00000E13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3 is defined as MSR_C8_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3 0x00000E13 - - -/** - Package. Uncore C-box 8 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER (0x00000E14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER is defined as MSR_C8_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER 0x00000E14 - - -/** - Package. Uncore C-box 8 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_CTR0 (0x00000E16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_CTR0 is defined as MSR_C8_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_CTR0 0x00000E16 - - -/** - Package. Uncore C-box 8 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_CTR1 (0x00000E17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_CTR1 is defined as MSR_C8_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_CTR1 0x00000E17 - - -/** - Package. Uncore C-box 8 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_CTR2 (0x00000E18) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_CTR2 is defined as MSR_C8_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_CTR2 0x00000E18 - - -/** - Package. Uncore C-box 8 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_CTR3 (0x00000E19) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_CTR3 is defined as MSR_C8_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_CTR3 0x00000E19 - - -/** - Package. Uncore C-box 8 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1 (0x00000E1A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1 is defined as MSR_C8_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1 0x00000E1A - - -/** - Package. Uncore C-box 9 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_BOX_CTL (0x00000E24) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_BOX_CTL is defined as MSR_C9_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_BOX_CTL 0x00000E24 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 0. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0 (0x00000E30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0 is defined as MSR_C9_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0 0x00000E30 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 1. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1 (0x00000E31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1 is defined as MSR_C9_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1 0x00000E31 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 2. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2 (0x00000E32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2 is defined as MSR_C9_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2 0x00000E32 - - -/** - Package. Uncore C-box 9 perfmon event select for C-box 9 counter 3. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3 (0x00000E33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3 is defined as MSR_C9_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3 0x00000E33 - - -/** - Package. Uncore C-box 9 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER (0x00000E34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER is defined as MSR_C9_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER 0x00000E34 - - -/** - Package. Uncore C-box 9 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_CTR0 (0x00000E36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_CTR0 is defined as MSR_C9_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_CTR0 0x00000E36 - - -/** - Package. Uncore C-box 9 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_CTR1 (0x00000E37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_CTR1 is defined as MSR_C9_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_CTR1 0x00000E37 - - -/** - Package. Uncore C-box 9 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_CTR2 (0x00000E38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_CTR2 is defined as MSR_C9_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_CTR2 0x00000E38 - - -/** - Package. Uncore C-box 9 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_CTR3 (0x00000E39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_CTR3 is defined as MSR_C9_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_CTR3 0x00000E39 - - -/** - Package. Uncore C-box 9 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1 (0x00000E3A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1 is defined as MSR_C9_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1 0x00000E3A - - -/** - Package. Uncore C-box 10 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_BOX_CTL (0x00000E44) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_BOX_CTL is defined as MSR_C10_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_BOX_CTL 0x00000E44 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 0. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0 (0x00000E50) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0 is defined as MSR_C10_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0 0x00000E50 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 1. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1 (0x00000E51) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1 is defined as MSR_C10_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1 0x00000E51 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 2. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2 (0x00000E52) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2 is defined as MSR_C10_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2 0x00000E52 - - -/** - Package. Uncore C-box 10 perfmon event select for C-box 10 counter 3. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3 (0x00000E53) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3 is defined as MSR_C10_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3 0x00000E53 - - -/** - Package. Uncore C-box 10 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER (0x00000E54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER is defined as MSR_C10_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER 0x00000E54 - - -/** - Package. Uncore C-box 10 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_CTR0 (0x00000E56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_CTR0 is defined as MSR_C10_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_CTR0 0x00000E56 - - -/** - Package. Uncore C-box 10 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_CTR1 (0x00000E57) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_CTR1 is defined as MSR_C10_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_CTR1 0x00000E57 - - -/** - Package. Uncore C-box 10 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_CTR2 (0x00000E58) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_CTR2 is defined as MSR_C10_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_CTR2 0x00000E58 - - -/** - Package. Uncore C-box 10 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_CTR3 (0x00000E59) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_CTR3 is defined as MSR_C10_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_CTR3 0x00000E59 - - -/** - Package. Uncore C-box 10 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1 (0x00000E5A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1 is defined as MSR_C10_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1 0x00000E5A - - -/** - Package. Uncore C-box 11 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_BOX_CTL (0x00000E64) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_BOX_CTL is defined as MSR_C11_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_BOX_CTL 0x00000E64 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 0. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0 (0x00000E70) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0 is defined as MSR_C11_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0 0x00000E70 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 1. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1 (0x00000E71) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1 is defined as MSR_C11_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1 0x00000E71 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 2. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2 (0x00000E72) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2 is defined as MSR_C11_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2 0x00000E72 - - -/** - Package. Uncore C-box 11 perfmon event select for C-box 11 counter 3. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3 (0x00000E73) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3 is defined as MSR_C11_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3 0x00000E73 - - -/** - Package. Uncore C-box 11 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER (0x00000E74) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER is defined as MSR_C11_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER 0x00000E74 - - -/** - Package. Uncore C-box 11 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_CTR0 (0x00000E76) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_CTR0 is defined as MSR_C11_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_CTR0 0x00000E76 - - -/** - Package. Uncore C-box 11 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_CTR1 (0x00000E77) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_CTR1 is defined as MSR_C11_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_CTR1 0x00000E77 - - -/** - Package. Uncore C-box 11 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_CTR2 (0x00000E78) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_CTR2 is defined as MSR_C11_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_CTR2 0x00000E78 - - -/** - Package. Uncore C-box 11 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_CTR3 (0x00000E79) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_CTR3 is defined as MSR_C11_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_CTR3 0x00000E79 - - -/** - Package. Uncore C-box 11 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1 (0x00000E7A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1 is defined as MSR_C11_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1 0x00000E7A - - -/** - Package. Uncore C-box 12 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_BOX_CTL (0x00000E84) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_BOX_CTL is defined as MSR_C12_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_BOX_CTL 0x00000E84 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 0. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0 (0x00000E90) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0 is defined as MSR_C12_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0 0x00000E90 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 1. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1 (0x00000E91) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1 is defined as MSR_C12_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1 0x00000E91 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 2. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2 (0x00000E92) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2 is defined as MSR_C12_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2 0x00000E92 - - -/** - Package. Uncore C-box 12 perfmon event select for C-box 12 counter 3. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3 (0x00000E93) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3 is defined as MSR_C12_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3 0x00000E93 - - -/** - Package. Uncore C-box 12 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER (0x00000E94) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER is defined as MSR_C12_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER 0x00000E94 - - -/** - Package. Uncore C-box 12 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_CTR0 (0x00000E96) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_CTR0 is defined as MSR_C12_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_CTR0 0x00000E96 - - -/** - Package. Uncore C-box 12 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_CTR1 (0x00000E97) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_CTR1 is defined as MSR_C12_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_CTR1 0x00000E97 - - -/** - Package. Uncore C-box 12 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_CTR2 (0x00000E98) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_CTR2 is defined as MSR_C12_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_CTR2 0x00000E98 - - -/** - Package. Uncore C-box 12 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_CTR3 (0x00000E99) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_CTR3 is defined as MSR_C12_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_CTR3 0x00000E99 - - -/** - Package. Uncore C-box 12 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1 (0x00000E9A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1 is defined as MSR_C12_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1 0x00000E9A - - -/** - Package. Uncore C-box 13 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_BOX_CTL (0x00000EA4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_BOX_CTL is defined as MSR_C13_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_BOX_CTL 0x00000EA4 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 0. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0 (0x00000EB0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0 is defined as MSR_C13_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0 0x00000EB0 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 1. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1 (0x00000EB1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1 is defined as MSR_C13_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1 0x00000EB1 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 2. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2 (0x00000EB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2 is defined as MSR_C13_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2 0x00000EB2 - - -/** - Package. Uncore C-box 13 perfmon event select for C-box 13 counter 3. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3 (0x00000EB3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3 is defined as MSR_C13_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3 0x00000EB3 - - -/** - Package. Uncore C-box 13 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER (0x00000EB4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER is defined as MSR_C13_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER 0x00000EB4 - - -/** - Package. Uncore C-box 13 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_CTR0 (0x00000EB6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_CTR0 is defined as MSR_C13_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_CTR0 0x00000EB6 - - -/** - Package. Uncore C-box 13 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_CTR1 (0x00000EB7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_CTR1 is defined as MSR_C13_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_CTR1 0x00000EB7 - - -/** - Package. Uncore C-box 13 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_CTR2 (0x00000EB8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_CTR2 is defined as MSR_C13_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_CTR2 0x00000EB8 - - -/** - Package. Uncore C-box 13 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_CTR3 (0x00000EB9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_CTR3 is defined as MSR_C13_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_CTR3 0x00000EB9 - - -/** - Package. Uncore C-box 13 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1 (0x00000EBA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1 is defined as MSR_C13_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1 0x00000EBA - - -/** - Package. Uncore C-box 14 perfmon local box wide control. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_BOX_CTL (0x00000EC4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_CTL, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_BOX_CTL is defined as MSR_C14_PMON_BOX_CTL in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_BOX_CTL 0x00000EC4 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 0. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0 (0x00000ED0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0 is defined as MSR_C14_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0 0x00000ED0 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 1. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1 (0x00000ED1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1 is defined as MSR_C14_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1 0x00000ED1 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 2. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2 (0x00000ED2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2 is defined as MSR_C14_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2 0x00000ED2 - - -/** - Package. Uncore C-box 14 perfmon event select for C-box 14 counter 3. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3 (0x00000ED3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3 is defined as MSR_C14_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3 0x00000ED3 - - -/** - Package. Uncore C-box 14 perfmon box wide filter. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER (0x00000ED4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER is defined as MSR_C14_PMON_BOX_FILTER in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER 0x00000ED4 - - -/** - Package. Uncore C-box 14 perfmon counter 0. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_CTR0 (0x00000ED6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR0); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR0, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_CTR0 is defined as MSR_C14_PMON_CTR0 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_CTR0 0x00000ED6 - - -/** - Package. Uncore C-box 14 perfmon counter 1. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_CTR1 (0x00000ED7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_CTR1 is defined as MSR_C14_PMON_CTR1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_CTR1 0x00000ED7 - - -/** - Package. Uncore C-box 14 perfmon counter 2. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_CTR2 (0x00000ED8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR2); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR2, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_CTR2 is defined as MSR_C14_PMON_CTR2 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_CTR2 0x00000ED8 - - -/** - Package. Uncore C-box 14 perfmon counter 3. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_CTR3 (0x00000ED9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR3); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR3, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_CTR3 is defined as MSR_C14_PMON_CTR3 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_CTR3 0x00000ED9 - - -/** - Package. Uncore C-box 14 perfmon box wide filter1. - - @param ECX MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1 (0x00000EDA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1); - AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1, Msr); - @endcode - @note MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1 is defined as MSR_C14_PMON_BOX_FILTER1 in SDM. -**/ -#define MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1 0x00000EDA - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h deleted file mode 100644 index 94aebba4d..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h +++ /dev/null @@ -1,7430 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Nehalem microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.6. - -**/ - -#ifndef __NEHALEM_MSR_H__ -#define __NEHALEM_MSR_H__ - -#include - -/** - Is Intel processors based on the Nehalem microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_NEHALEM_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x1A || \ - DisplayModel == 0x1E || \ - DisplayModel == 0x1F || \ - DisplayModel == 0x2E \ - ) \ - ) - -/** - Package. Model Specific Platform ID (R). - - @param ECX MSR_NEHALEM_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_NEHALEM_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_ID); - @endcode - @note MSR_NEHALEM_PLATFORM_ID is defined as MSR_PLATFORM_ID in SDM. -**/ -#define MSR_NEHALEM_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:18; - /// - /// [Bits 52:50] See Table 35-2. - /// - UINT32 PlatformId:3; - UINT32 Reserved3:11; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PLATFORM_ID_REGISTER; - - -/** - Thread. SMI Counter (R/O). - - @param ECX MSR_NEHALEM_SMI_COUNT (0x00000034) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_SMI_COUNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_SMI_COUNT_REGISTER. - - Example usage - @code - MSR_NEHALEM_SMI_COUNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_SMI_COUNT); - @endcode - @note MSR_NEHALEM_SMI_COUNT is defined as MSR_SMI_COUNT in SDM. -**/ -#define MSR_NEHALEM_SMI_COUNT 0x00000034 - -/** - MSR information returned for MSR index #MSR_NEHALEM_SMI_COUNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] SMI Count (R/O) Running count of SMI events since last - /// RESET. - /// - UINT32 SMICount:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_SMI_COUNT_REGISTER; - - -/** - Package. see http://biosbits.org. - - @param ECX MSR_NEHALEM_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_NEHALEM_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_INFO); - AsmWriteMsr64 (MSR_NEHALEM_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_NEHALEM_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_NEHALEM_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. The invariant TSC - /// frequency can be computed by multiplying this ratio by 133.33 MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDC-TDP Limit for Turbo Mode (R/O) - /// When set to 1, indicates that TDC/TDP Limits for Turbo mode are - /// programmable, and when set to 0, indicates TDC and TDP Limits for - /// Turbo mode are not programmable. - /// - UINT32 TDC_TDPLimit:1; - UINT32 Reserved3:2; - UINT32 Reserved4:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 133.33MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved5:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PLATFORM_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. See http://biosbits.org. - - @param ECX MSR_NEHALEM_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_NEHALEM_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_NEHALEM_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_NEHALEM_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power). for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0 (no package C-sate support) 001b: C1 (Behavior is the same as 000b) - /// 010b: C3 011b: C6 100b: C7 101b and 110b: Reserved 111: No package - /// C-state limit. Note: This field cannot be used to limit package - /// C-state to C3. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W) When set, will map - /// IO_read instructions sent to IO register specified by - /// MSR_PMG_IO_CAPTURE_BASE to MWAIT instructions. - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO) When set, lock bits 15:0 of this register - /// until next reset. - /// - UINT32 CFGLock:1; - UINT32 Reserved3:8; - /// - /// [Bit 24] Interrupt filtering enable (R/W) When set, processor cores - /// in a deep C-State will wake only when the event message is destined - /// for that core. When 0, all processor cores in a deep C-State will wake - /// for an event message. - /// - UINT32 InterruptFiltering:1; - /// - /// [Bit 25] C3 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C6/C7 requests to C3 based on uncore - /// auto-demote information. - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C3/C6/C7 requests to C1 based on uncore - /// auto-demote information. - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 Undemotion (R/W). - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 Undemotion (R/W). - /// - UINT32 C1Undemotion:1; - /// - /// [Bit 29] Package C State Demotion Enable (R/W). - /// - UINT32 CStateDemotion:1; - /// - /// [Bit 30] Package C State UnDemotion Enable (R/W). - /// - UINT32 CStateUndemotion:1; - UINT32 Reserved4:1; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Core. Power Management IO Redirection in C-state (R/W) See - http://biosbits.org. - - @param ECX MSR_NEHALEM_PMG_IO_CAPTURE_BASE (0x000000E4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PMG_IO_CAPTURE_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PMG_IO_CAPTURE_BASE_REGISTER. - - Example usage - @code - MSR_NEHALEM_PMG_IO_CAPTURE_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PMG_IO_CAPTURE_BASE); - AsmWriteMsr64 (MSR_NEHALEM_PMG_IO_CAPTURE_BASE, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PMG_IO_CAPTURE_BASE is defined as MSR_PMG_IO_CAPTURE_BASE in SDM. -**/ -#define MSR_NEHALEM_PMG_IO_CAPTURE_BASE 0x000000E4 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PMG_IO_CAPTURE_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] LVL_2 Base Address (R/W) Specifies the base address - /// visible to software for IO redirection. If IO MWAIT Redirection is - /// enabled, reads to this address will be consumed by the power - /// management logic and decoded to MWAIT instructions. When IO port - /// address redirection is enabled, this is the IO port address reported - /// to the OS/software. - /// - UINT32 Lvl2Base:16; - /// - /// [Bits 18:16] C-state Range (R/W) Specifies the encoding value of the - /// maximum C-State code name to be included when IO read to MWAIT - /// redirection is enabled by MSR_PKG_CST_CONFIG_CONTROL[bit10]: 000b - C3 - /// is the max C-State to include 001b - C6 is the max C-State to include - /// 010b - C7 is the max C-State to include. - /// - UINT32 CStateRange:3; - UINT32 Reserved1:13; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PMG_IO_CAPTURE_BASE_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_NEHALEM_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_NEHALEM_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_NEHALEM_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_NEHALEM_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_NEHALEM_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_NEHALEM_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Thread. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. Default value is 1. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Thread. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:3; - /// - /// [Bit 11] Thread. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Thread. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - UINT32 Reserved4:3; - /// - /// [Bit 16] Package. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] Thread. ENABLE MONITOR FSM. (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved6:3; - /// - /// [Bit 22] Thread. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Thread. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] Thread. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved9:3; - /// - /// [Bit 38] Package. Turbo Mode Disable (R/W) When set to 1 on processors - /// that support Intel Turbo Boost Technology, the turbo mode feature is - /// disabled and the IDA_Enable feature flag will be clear (CPUID.06H: - /// EAX[1]=0). When set to a 0 on processors that support IDA, CPUID.06H: - /// EAX[1] reports the processor's support of turbo mode is enabled. Note: - /// the power-on default value is used by BIOS to detect hardware support - /// of turbo mode. If power-on default value is 1, turbo mode is available - /// in the processor. If power-on default value is 0, turbo mode is not - /// available. - /// - UINT32 TurboModeDisable:1; - UINT32 Reserved10:25; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_IA32_MISC_ENABLE_REGISTER; - - -/** - Thread. - - @param ECX MSR_NEHALEM_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_NEHALEM_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_NEHALEM_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_NEHALEM_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_NEHALEM_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_NEHALEM_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (R) The minimum temperature at which - /// PROCHOT# will be asserted. The value is degree C. - /// - UINT32 TemperatureTarget:8; - UINT32 Reserved2:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_TEMPERATURE_TARGET_REGISTER; - - -/** - Miscellaneous Feature Control (R/W). - - @param ECX MSR_NEHALEM_MISC_FEATURE_CONTROL (0x000001A4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_MISC_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_MISC_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_NEHALEM_MISC_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_MISC_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_NEHALEM_MISC_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_NEHALEM_MISC_FEATURE_CONTROL is defined as MSR_MISC_FEATURE_CONTROL in SDM. -**/ -#define MSR_NEHALEM_MISC_FEATURE_CONTROL 0x000001A4 - -/** - MSR information returned for MSR index #MSR_NEHALEM_MISC_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. L2 Hardware Prefetcher Disable (R/W) If 1, disables the - /// L2 hardware prefetcher, which fetches additional lines of code or data - /// into the L2 cache. - /// - UINT32 L2HardwarePrefetcherDisable:1; - /// - /// [Bit 1] Core. L2 Adjacent Cache Line Prefetcher Disable (R/W) If 1, - /// disables the adjacent cache line prefetcher, which fetches the cache - /// line that comprises a cache line pair (128 bytes). - /// - UINT32 L2AdjacentCacheLinePrefetcherDisable:1; - /// - /// [Bit 2] Core. DCU Hardware Prefetcher Disable (R/W) If 1, disables - /// the L1 data cache prefetcher, which fetches the next cache line into - /// L1 data cache. - /// - UINT32 DCUHardwarePrefetcherDisable:1; - /// - /// [Bit 3] Core. DCU IP Prefetcher Disable (R/W) If 1, disables the L1 - /// data cache IP prefetcher, which uses sequential load history (based on - /// instruction Pointer of previous loads) to determine whether to - /// prefetch additional lines. - /// - UINT32 DCUIPPrefetcherDisable:1; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_MISC_FEATURE_CONTROL_REGISTER; - - -/** - Thread. Offcore Response Event Select Register (R/W). - - @param ECX MSR_NEHALEM_OFFCORE_RSP_0 (0x000001A6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_OFFCORE_RSP_0); - AsmWriteMsr64 (MSR_NEHALEM_OFFCORE_RSP_0, Msr); - @endcode - @note MSR_NEHALEM_OFFCORE_RSP_0 is defined as MSR_OFFCORE_RSP_0 in SDM. -**/ -#define MSR_NEHALEM_OFFCORE_RSP_0 0x000001A6 - - -/** - See http://biosbits.org. - - @param ECX MSR_NEHALEM_MISC_PWR_MGMT (0x000001AA) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_MISC_PWR_MGMT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_MISC_PWR_MGMT_REGISTER. - - Example usage - @code - MSR_NEHALEM_MISC_PWR_MGMT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_MISC_PWR_MGMT); - AsmWriteMsr64 (MSR_NEHALEM_MISC_PWR_MGMT, Msr.Uint64); - @endcode - @note MSR_NEHALEM_MISC_PWR_MGMT is defined as MSR_MISC_PWR_MGMT in SDM. -**/ -#define MSR_NEHALEM_MISC_PWR_MGMT 0x000001AA - -/** - MSR information returned for MSR index #MSR_NEHALEM_MISC_PWR_MGMT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Package. EIST Hardware Coordination Disable (R/W) When 0, - /// enables hardware coordination of Enhanced Intel Speedstep Technology - /// request from processor cores; When 1, disables hardware coordination - /// of Enhanced Intel Speedstep Technology requests. - /// - UINT32 EISTHardwareCoordinationDisable:1; - /// - /// [Bit 1] Thread. Energy/Performance Bias Enable (R/W) This bit makes - /// the IA32_ENERGY_PERF_BIAS register (MSR 1B0h) visible to software with - /// Ring 0 privileges. This bit's status (1 or 0) is also reflected by - /// CPUID.(EAX=06h):ECX[3]. - /// - UINT32 EnergyPerformanceBiasEnable:1; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_MISC_PWR_MGMT_REGISTER; - - -/** - See http://biosbits.org. - - @param ECX MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT (0x000001AC) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT_REGISTER. - - Example usage - @code - MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT); - AsmWriteMsr64 (MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT, Msr.Uint64); - @endcode - @note MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT is defined as MSR_TURBO_POWER_CURRENT_LIMIT in SDM. -**/ -#define MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT 0x000001AC - -/** - MSR information returned for MSR index #MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Package. TDP Limit (R/W) TDP limit in 1/8 Watt - /// granularity. - /// - UINT32 TDPLimit:15; - /// - /// [Bit 15] Package. TDP Limit Override Enable (R/W) A value = 0 - /// indicates override is not active, and a value = 1 indicates active. - /// - UINT32 TDPLimitOverrideEnable:1; - /// - /// [Bits 30:16] Package. TDC Limit (R/W) TDC limit in 1/8 Amp - /// granularity. - /// - UINT32 TDCLimit:15; - /// - /// [Bit 31] Package. TDC Limit Override Enable (R/W) A value = 0 - /// indicates override is not active, and a value = 1 indicates active. - /// - UINT32 TDCLimitOverrideEnable:1; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_TURBO_POWER_CURRENT_LIMIT_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_NEHALEM_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TURBO_RATIO_LIMIT); - @endcode - @note MSR_NEHALEM_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_NEHALEM_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Core. Last Branch Record Filtering Select Register (R/W) See Section - 17.7.2, "Filtering of Last Branch Records.". - - @param ECX MSR_NEHALEM_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_LBR_SELECT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_LBR_SELECT_REGISTER. - - Example usage - @code - MSR_NEHALEM_LBR_SELECT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_LBR_SELECT); - AsmWriteMsr64 (MSR_NEHALEM_LBR_SELECT, Msr.Uint64); - @endcode - @note MSR_NEHALEM_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_NEHALEM_LBR_SELECT 0x000001C8 - -/** - MSR information returned for MSR index #MSR_NEHALEM_LBR_SELECT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CPL_EQ_0. - /// - UINT32 CPL_EQ_0:1; - /// - /// [Bit 1] CPL_NEQ_0. - /// - UINT32 CPL_NEQ_0:1; - /// - /// [Bit 2] JCC. - /// - UINT32 JCC:1; - /// - /// [Bit 3] NEAR_REL_CALL. - /// - UINT32 NEAR_REL_CALL:1; - /// - /// [Bit 4] NEAR_IND_CALL. - /// - UINT32 NEAR_IND_CALL:1; - /// - /// [Bit 5] NEAR_RET. - /// - UINT32 NEAR_RET:1; - /// - /// [Bit 6] NEAR_IND_JMP. - /// - UINT32 NEAR_IND_JMP:1; - /// - /// [Bit 7] NEAR_REL_JMP. - /// - UINT32 NEAR_REL_JMP:1; - /// - /// [Bit 8] FAR_BRANCH. - /// - UINT32 FAR_BRANCH:1; - UINT32 Reserved1:23; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_LBR_SELECT_REGISTER; - - -/** - Thread. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-3) - that points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP (at 680H). - - @param ECX MSR_NEHALEM_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_NEHALEM_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_NEHALEM_LASTBRANCH_TOS 0x000001C9 - - -/** - Thread. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_NEHALEM_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_LER_FROM_LIP); - @endcode - @note MSR_NEHALEM_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_NEHALEM_LER_FROM_LIP 0x000001DD - - -/** - Thread. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_NEHALEM_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_LER_TO_LIP); - @endcode - @note MSR_NEHALEM_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_NEHALEM_LER_TO_LIP 0x000001DE - - -/** - Core. Power Control Register. See http://biosbits.org. - - @param ECX MSR_NEHALEM_POWER_CTL (0x000001FC) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_POWER_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_POWER_CTL_REGISTER. - - Example usage - @code - MSR_NEHALEM_POWER_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_POWER_CTL); - AsmWriteMsr64 (MSR_NEHALEM_POWER_CTL, Msr.Uint64); - @endcode - @note MSR_NEHALEM_POWER_CTL is defined as MSR_POWER_CTL in SDM. -**/ -#define MSR_NEHALEM_POWER_CTL 0x000001FC - -/** - MSR information returned for MSR index #MSR_NEHALEM_POWER_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Package. C1E Enable (R/W) When set to '1', will enable the - /// CPU to switch to the Minimum Enhanced Intel SpeedStep Technology - /// operating point when all execution cores enter MWAIT (C1). - /// - UINT32 C1EEnable:1; - UINT32 Reserved2:30; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_POWER_CTL_REGISTER; - - -/** - Thread. (RO). - - @param ECX MSR_NEHALEM_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_NEHALEM_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PERF_GLOBAL_STATUS); - @endcode - @note MSR_NEHALEM_PERF_GLOBAL_STATUS is defined as MSR_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_NEHALEM_PERF_GLOBAL_STATUS 0x0000038E - -/** - MSR information returned for MSR index #MSR_NEHALEM_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:29; - /// - /// [Bit 61] UNC_Ovf Uncore overflowed if 1. - /// - UINT32 Ovf_Uncore:1; - UINT32 Reserved3:2; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Thread. (R/W). - - @param ECX MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL_REGISTER. - - Example usage - @code - MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL is defined as MSR_PERF_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL 0x00000390 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:29; - /// - /// [Bit 61] CLR_UNC_Ovf Set 1 to clear UNC_Ovf. - /// - UINT32 Ovf_Uncore:1; - UINT32 Reserved3:2; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PERF_GLOBAL_OVF_CTRL_REGISTER; - - -/** - Thread. See Section 18.8.1.1, "Processor Event Based Sampling (PEBS).". - - @param ECX MSR_NEHALEM_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_NEHALEM_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PEBS_ENABLE); - AsmWriteMsr64 (MSR_NEHALEM_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_NEHALEM_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. (R/W). - /// - UINT32 PEBS_EN_PMC0:1; - /// - /// [Bit 1] Enable PEBS on IA32_PMC1. (R/W). - /// - UINT32 PEBS_EN_PMC1:1; - /// - /// [Bit 2] Enable PEBS on IA32_PMC2. (R/W). - /// - UINT32 PEBS_EN_PMC2:1; - /// - /// [Bit 3] Enable PEBS on IA32_PMC3. (R/W). - /// - UINT32 PEBS_EN_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Enable Load Latency on IA32_PMC0. (R/W). - /// - UINT32 LL_EN_PMC0:1; - /// - /// [Bit 33] Enable Load Latency on IA32_PMC1. (R/W). - /// - UINT32 LL_EN_PMC1:1; - /// - /// [Bit 34] Enable Load Latency on IA32_PMC2. (R/W). - /// - UINT32 LL_EN_PMC2:1; - /// - /// [Bit 35] Enable Load Latency on IA32_PMC3. (R/W). - /// - UINT32 LL_EN_PMC3:1; - UINT32 Reserved2:28; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PEBS_ENABLE_REGISTER; - - -/** - Thread. See Section 18.8.1.2, "Load Latency Performance Monitoring - Facility.". - - @param ECX MSR_NEHALEM_PEBS_LD_LAT (0x000003F6) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_PEBS_LD_LAT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_PEBS_LD_LAT_REGISTER. - - Example usage - @code - MSR_NEHALEM_PEBS_LD_LAT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PEBS_LD_LAT); - AsmWriteMsr64 (MSR_NEHALEM_PEBS_LD_LAT, Msr.Uint64); - @endcode - @note MSR_NEHALEM_PEBS_LD_LAT is defined as MSR_PEBS_LD_LAT in SDM. -**/ -#define MSR_NEHALEM_PEBS_LD_LAT 0x000003F6 - -/** - MSR information returned for MSR index #MSR_NEHALEM_PEBS_LD_LAT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Minimum threshold latency value of tagged load operation - /// that will be counted. (R/W). - /// - UINT32 MinimumThreshold:16; - UINT32 Reserved1:16; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_PEBS_LD_LAT_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C3 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_NEHALEM_PKG_C3_RESIDENCY (0x000003F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C3_RESIDENCY); - AsmWriteMsr64 (MSR_NEHALEM_PKG_C3_RESIDENCY, Msr); - @endcode - @note MSR_NEHALEM_PKG_C3_RESIDENCY is defined as MSR_PKG_C3_RESIDENCY in SDM. -**/ -#define MSR_NEHALEM_PKG_C3_RESIDENCY 0x000003F8 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C6 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C6 states. Count at the same frequency as the TSC. - - @param ECX MSR_NEHALEM_PKG_C6_RESIDENCY (0x000003F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_NEHALEM_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_NEHALEM_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_NEHALEM_PKG_C6_RESIDENCY 0x000003F9 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C7 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C7 states. Count at the same frequency as the TSC. - - @param ECX MSR_NEHALEM_PKG_C7_RESIDENCY (0x000003FA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C7_RESIDENCY); - AsmWriteMsr64 (MSR_NEHALEM_PKG_C7_RESIDENCY, Msr); - @endcode - @note MSR_NEHALEM_PKG_C7_RESIDENCY is defined as MSR_PKG_C7_RESIDENCY in SDM. -**/ -#define MSR_NEHALEM_PKG_C7_RESIDENCY 0x000003FA - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C3 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_NEHALEM_CORE_C3_RESIDENCY (0x000003FC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_CORE_C3_RESIDENCY); - AsmWriteMsr64 (MSR_NEHALEM_CORE_C3_RESIDENCY, Msr); - @endcode - @note MSR_NEHALEM_CORE_C3_RESIDENCY is defined as MSR_CORE_C3_RESIDENCY in SDM. -**/ -#define MSR_NEHALEM_CORE_C3_RESIDENCY 0x000003FC - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C6 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C6 states. Count at the same frequency as the TSC. - - @param ECX MSR_NEHALEM_CORE_C6_RESIDENCY (0x000003FD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_CORE_C6_RESIDENCY); - AsmWriteMsr64 (MSR_NEHALEM_CORE_C6_RESIDENCY, Msr); - @endcode - @note MSR_NEHALEM_CORE_C6_RESIDENCY is defined as MSR_CORE_C6_RESIDENCY in SDM. -**/ -#define MSR_NEHALEM_CORE_C6_RESIDENCY 0x000003FD - - -/** - Thread. Last Branch Record n From IP (R/W) One of sixteen pairs of last - branch record registers on the last branch record stack. The From_IP part of - the stack contains pointers to the source instruction. See also: - Last - Branch Record Stack TOS at 1C9H - Section 17.7.1 and record format in - Section 17.4.8.1. - - @param ECX MSR_NEHALEM_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_NEHALEM_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_8_FROM_IP is defined as MSR_LASTBRANCH_8_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_9_FROM_IP is defined as MSR_LASTBRANCH_9_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_10_FROM_IP is defined as MSR_LASTBRANCH_10_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_11_FROM_IP is defined as MSR_LASTBRANCH_11_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_12_FROM_IP is defined as MSR_LASTBRANCH_12_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_13_FROM_IP is defined as MSR_LASTBRANCH_13_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_14_FROM_IP is defined as MSR_LASTBRANCH_14_FROM_IP in SDM. - MSR_NEHALEM_LASTBRANCH_15_FROM_IP is defined as MSR_LASTBRANCH_15_FROM_IP in SDM. - @{ -**/ -#define MSR_NEHALEM_LASTBRANCH_0_FROM_IP 0x00000680 -#define MSR_NEHALEM_LASTBRANCH_1_FROM_IP 0x00000681 -#define MSR_NEHALEM_LASTBRANCH_2_FROM_IP 0x00000682 -#define MSR_NEHALEM_LASTBRANCH_3_FROM_IP 0x00000683 -#define MSR_NEHALEM_LASTBRANCH_4_FROM_IP 0x00000684 -#define MSR_NEHALEM_LASTBRANCH_5_FROM_IP 0x00000685 -#define MSR_NEHALEM_LASTBRANCH_6_FROM_IP 0x00000686 -#define MSR_NEHALEM_LASTBRANCH_7_FROM_IP 0x00000687 -#define MSR_NEHALEM_LASTBRANCH_8_FROM_IP 0x00000688 -#define MSR_NEHALEM_LASTBRANCH_9_FROM_IP 0x00000689 -#define MSR_NEHALEM_LASTBRANCH_10_FROM_IP 0x0000068A -#define MSR_NEHALEM_LASTBRANCH_11_FROM_IP 0x0000068B -#define MSR_NEHALEM_LASTBRANCH_12_FROM_IP 0x0000068C -#define MSR_NEHALEM_LASTBRANCH_13_FROM_IP 0x0000068D -#define MSR_NEHALEM_LASTBRANCH_14_FROM_IP 0x0000068E -#define MSR_NEHALEM_LASTBRANCH_15_FROM_IP 0x0000068F -/// @} - - -/** - Thread. Last Branch Record n To IP (R/W) One of sixteen pairs of last branch - record registers on the last branch record stack. This part of the stack - contains pointers to the destination instruction. - - @param ECX MSR_NEHALEM_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_NEHALEM_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_8_TO_IP is defined as MSR_LASTBRANCH_8_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_9_TO_IP is defined as MSR_LASTBRANCH_9_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_10_TO_IP is defined as MSR_LASTBRANCH_10_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_11_TO_IP is defined as MSR_LASTBRANCH_11_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_12_TO_IP is defined as MSR_LASTBRANCH_12_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_13_TO_IP is defined as MSR_LASTBRANCH_13_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_14_TO_IP is defined as MSR_LASTBRANCH_14_TO_IP in SDM. - MSR_NEHALEM_LASTBRANCH_15_TO_IP is defined as MSR_LASTBRANCH_15_TO_IP in SDM. - @{ -**/ -#define MSR_NEHALEM_LASTBRANCH_0_TO_IP 0x000006C0 -#define MSR_NEHALEM_LASTBRANCH_1_TO_IP 0x000006C1 -#define MSR_NEHALEM_LASTBRANCH_2_TO_IP 0x000006C2 -#define MSR_NEHALEM_LASTBRANCH_3_TO_IP 0x000006C3 -#define MSR_NEHALEM_LASTBRANCH_4_TO_IP 0x000006C4 -#define MSR_NEHALEM_LASTBRANCH_5_TO_IP 0x000006C5 -#define MSR_NEHALEM_LASTBRANCH_6_TO_IP 0x000006C6 -#define MSR_NEHALEM_LASTBRANCH_7_TO_IP 0x000006C7 -#define MSR_NEHALEM_LASTBRANCH_8_TO_IP 0x000006C8 -#define MSR_NEHALEM_LASTBRANCH_9_TO_IP 0x000006C9 -#define MSR_NEHALEM_LASTBRANCH_10_TO_IP 0x000006CA -#define MSR_NEHALEM_LASTBRANCH_11_TO_IP 0x000006CB -#define MSR_NEHALEM_LASTBRANCH_12_TO_IP 0x000006CC -#define MSR_NEHALEM_LASTBRANCH_13_TO_IP 0x000006CD -#define MSR_NEHALEM_LASTBRANCH_14_TO_IP 0x000006CE -#define MSR_NEHALEM_LASTBRANCH_15_TO_IP 0x000006CF -/// @} - - -/** - Package. - - @param ECX MSR_NEHALEM_GQ_SNOOP_MESF (0x00000301) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_NEHALEM_GQ_SNOOP_MESF_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_NEHALEM_GQ_SNOOP_MESF_REGISTER. - - Example usage - @code - MSR_NEHALEM_GQ_SNOOP_MESF_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_GQ_SNOOP_MESF); - AsmWriteMsr64 (MSR_NEHALEM_GQ_SNOOP_MESF, Msr.Uint64); - @endcode - @note MSR_NEHALEM_GQ_SNOOP_MESF is defined as MSR_GQ_SNOOP_MESF in SDM. -**/ -#define MSR_NEHALEM_GQ_SNOOP_MESF 0x00000301 - -/** - MSR information returned for MSR index #MSR_NEHALEM_GQ_SNOOP_MESF -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] From M to S (R/W). - /// - UINT32 FromMtoS:1; - /// - /// [Bit 1] From E to S (R/W). - /// - UINT32 FromEtoS:1; - /// - /// [Bit 2] From S to S (R/W). - /// - UINT32 FromStoS:1; - /// - /// [Bit 3] From F to S (R/W). - /// - UINT32 FromFtoS:1; - /// - /// [Bit 4] From M to I (R/W). - /// - UINT32 FromMtoI:1; - /// - /// [Bit 5] From E to I (R/W). - /// - UINT32 FromEtoI:1; - /// - /// [Bit 6] From S to I (R/W). - /// - UINT32 FromStoI:1; - /// - /// [Bit 7] From F to I (R/W). - /// - UINT32 FromFtoI:1; - UINT32 Reserved1:24; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_NEHALEM_GQ_SNOOP_MESF_REGISTER; - - -/** - Package. See Section 18.8.2.1, "Uncore Performance Monitoring Management - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL (0x00000391) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL is defined as MSR_UNCORE_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL 0x00000391 - - -/** - Package. See Section 18.8.2.1, "Uncore Performance Monitoring Management - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS (0x00000392) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS is defined as MSR_UNCORE_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS 0x00000392 - - -/** - Package. See Section 18.8.2.1, "Uncore Performance Monitoring Management - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL (0x00000393) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL is defined as MSR_UNCORE_PERF_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL 0x00000393 - - -/** - Package. See Section 18.8.2.1, "Uncore Performance Monitoring Management - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_FIXED_CTR0 (0x00000394) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR0, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_FIXED_CTR0 is defined as MSR_UNCORE_FIXED_CTR0 in SDM. -**/ -#define MSR_NEHALEM_UNCORE_FIXED_CTR0 0x00000394 - - -/** - Package. See Section 18.8.2.1, "Uncore Performance Monitoring Management - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL (0x00000395) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL is defined as MSR_UNCORE_FIXED_CTR_CTRL in SDM. -**/ -#define MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL 0x00000395 - - -/** - Package. See Section 18.8.2.3, "Uncore Address/Opcode Match MSR.". - - @param ECX MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH (0x00000396) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH is defined as MSR_UNCORE_ADDR_OPCODE_MATCH in SDM. -**/ -#define MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH 0x00000396 - - -/** - Package. See Section 18.8.2.2, "Uncore Performance Event Configuration - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_PMCi - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PMC0); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PMC0, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_PMC0 is defined as MSR_UNCORE_PMC0 in SDM. - MSR_NEHALEM_UNCORE_PMC1 is defined as MSR_UNCORE_PMC1 in SDM. - MSR_NEHALEM_UNCORE_PMC2 is defined as MSR_UNCORE_PMC2 in SDM. - MSR_NEHALEM_UNCORE_PMC3 is defined as MSR_UNCORE_PMC3 in SDM. - MSR_NEHALEM_UNCORE_PMC4 is defined as MSR_UNCORE_PMC4 in SDM. - MSR_NEHALEM_UNCORE_PMC5 is defined as MSR_UNCORE_PMC5 in SDM. - MSR_NEHALEM_UNCORE_PMC6 is defined as MSR_UNCORE_PMC6 in SDM. - MSR_NEHALEM_UNCORE_PMC7 is defined as MSR_UNCORE_PMC7 in SDM. - @{ -**/ -#define MSR_NEHALEM_UNCORE_PMC0 0x000003B0 -#define MSR_NEHALEM_UNCORE_PMC1 0x000003B1 -#define MSR_NEHALEM_UNCORE_PMC2 0x000003B2 -#define MSR_NEHALEM_UNCORE_PMC3 0x000003B3 -#define MSR_NEHALEM_UNCORE_PMC4 0x000003B4 -#define MSR_NEHALEM_UNCORE_PMC5 0x000003B5 -#define MSR_NEHALEM_UNCORE_PMC6 0x000003B6 -#define MSR_NEHALEM_UNCORE_PMC7 0x000003B7 -/// @} - -/** - Package. See Section 18.8.2.2, "Uncore Performance Event Configuration - Facility.". - - @param ECX MSR_NEHALEM_UNCORE_PERFEVTSELi - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERFEVTSEL0); - AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERFEVTSEL0, Msr); - @endcode - @note MSR_NEHALEM_UNCORE_PERFEVTSEL0 is defined as MSR_UNCORE_PERFEVTSEL0 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL1 is defined as MSR_UNCORE_PERFEVTSEL1 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL2 is defined as MSR_UNCORE_PERFEVTSEL2 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL3 is defined as MSR_UNCORE_PERFEVTSEL3 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL4 is defined as MSR_UNCORE_PERFEVTSEL4 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL5 is defined as MSR_UNCORE_PERFEVTSEL5 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL6 is defined as MSR_UNCORE_PERFEVTSEL6 in SDM. - MSR_NEHALEM_UNCORE_PERFEVTSEL7 is defined as MSR_UNCORE_PERFEVTSEL7 in SDM. - @{ -**/ -#define MSR_NEHALEM_UNCORE_PERFEVTSEL0 0x000003C0 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL1 0x000003C1 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL2 0x000003C2 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL3 0x000003C3 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL4 0x000003C4 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL5 0x000003C5 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL6 0x000003C6 -#define MSR_NEHALEM_UNCORE_PERFEVTSEL7 0x000003C7 -/// @} - - -/** - Package. Uncore W-box perfmon fixed counter. - - @param ECX MSR_NEHALEM_W_PMON_FIXED_CTR (0x00000394) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_FIXED_CTR is defined as MSR_W_PMON_FIXED_CTR in SDM. -**/ -#define MSR_NEHALEM_W_PMON_FIXED_CTR 0x00000394 - - -/** - Package. Uncore U-box perfmon fixed counter control MSR. - - @param ECX MSR_NEHALEM_W_PMON_FIXED_CTR_CTL (0x00000395) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR_CTL); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR_CTL, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_FIXED_CTR_CTL is defined as MSR_W_PMON_FIXED_CTR_CTL in SDM. -**/ -#define MSR_NEHALEM_W_PMON_FIXED_CTR_CTL 0x00000395 - - -/** - Package. Uncore U-box perfmon global control MSR. - - @param ECX MSR_NEHALEM_U_PMON_GLOBAL_CTRL (0x00000C00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_CTRL, Msr); - @endcode - @note MSR_NEHALEM_U_PMON_GLOBAL_CTRL is defined as MSR_U_PMON_GLOBAL_CTRL in SDM. -**/ -#define MSR_NEHALEM_U_PMON_GLOBAL_CTRL 0x00000C00 - - -/** - Package. Uncore U-box perfmon global status MSR. - - @param ECX MSR_NEHALEM_U_PMON_GLOBAL_STATUS (0x00000C01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_STATUS, Msr); - @endcode - @note MSR_NEHALEM_U_PMON_GLOBAL_STATUS is defined as MSR_U_PMON_GLOBAL_STATUS in SDM. -**/ -#define MSR_NEHALEM_U_PMON_GLOBAL_STATUS 0x00000C01 - - -/** - Package. Uncore U-box perfmon global overflow control MSR. - - @param ECX MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL (0x00000C02) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL is defined as MSR_U_PMON_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL 0x00000C02 - - -/** - Package. Uncore U-box perfmon event select MSR. - - @param ECX MSR_NEHALEM_U_PMON_EVNT_SEL (0x00000C10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_EVNT_SEL); - AsmWriteMsr64 (MSR_NEHALEM_U_PMON_EVNT_SEL, Msr); - @endcode - @note MSR_NEHALEM_U_PMON_EVNT_SEL is defined as MSR_U_PMON_EVNT_SEL in SDM. -**/ -#define MSR_NEHALEM_U_PMON_EVNT_SEL 0x00000C10 - - -/** - Package. Uncore U-box perfmon counter MSR. - - @param ECX MSR_NEHALEM_U_PMON_CTR (0x00000C11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_CTR); - AsmWriteMsr64 (MSR_NEHALEM_U_PMON_CTR, Msr); - @endcode - @note MSR_NEHALEM_U_PMON_CTR is defined as MSR_U_PMON_CTR in SDM. -**/ -#define MSR_NEHALEM_U_PMON_CTR 0x00000C11 - - -/** - Package. Uncore B-box 0 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_B0_PMON_BOX_CTRL (0x00000C20) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_BOX_CTRL is defined as MSR_B0_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_BOX_CTRL 0x00000C20 - - -/** - Package. Uncore B-box 0 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_B0_PMON_BOX_STATUS (0x00000C21) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_BOX_STATUS is defined as MSR_B0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_BOX_STATUS 0x00000C21 - - -/** - Package. Uncore B-box 0 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL (0x00000C22) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL is defined as MSR_B0_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL 0x00000C22 - - -/** - Package. Uncore B-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B0_PMON_EVNT_SEL0 (0x00000C30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_EVNT_SEL0 is defined as MSR_B0_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_EVNT_SEL0 0x00000C30 - - -/** - Package. Uncore B-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B0_PMON_CTR0 (0x00000C31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_CTR0 is defined as MSR_B0_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_CTR0 0x00000C31 - - -/** - Package. Uncore B-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B0_PMON_EVNT_SEL1 (0x00000C32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_EVNT_SEL1 is defined as MSR_B0_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_EVNT_SEL1 0x00000C32 - - -/** - Package. Uncore B-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B0_PMON_CTR1 (0x00000C33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_CTR1 is defined as MSR_B0_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_CTR1 0x00000C33 - - -/** - Package. Uncore B-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B0_PMON_EVNT_SEL2 (0x00000C34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_EVNT_SEL2 is defined as MSR_B0_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_EVNT_SEL2 0x00000C34 - - -/** - Package. Uncore B-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B0_PMON_CTR2 (0x00000C35) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_CTR2 is defined as MSR_B0_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_CTR2 0x00000C35 - - -/** - Package. Uncore B-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B0_PMON_EVNT_SEL3 (0x00000C36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_EVNT_SEL3 is defined as MSR_B0_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_EVNT_SEL3 0x00000C36 - - -/** - Package. Uncore B-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B0_PMON_CTR3 (0x00000C37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_CTR3 is defined as MSR_B0_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_CTR3 0x00000C37 - - -/** - Package. Uncore S-box 0 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_S0_PMON_BOX_CTRL (0x00000C40) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_BOX_CTRL is defined as MSR_S0_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_BOX_CTRL 0x00000C40 - - -/** - Package. Uncore S-box 0 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_S0_PMON_BOX_STATUS (0x00000C41) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_BOX_STATUS is defined as MSR_S0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_BOX_STATUS 0x00000C41 - - -/** - Package. Uncore S-box 0 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL (0x00000C42) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL is defined as MSR_S0_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL 0x00000C42 - - -/** - Package. Uncore S-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S0_PMON_EVNT_SEL0 (0x00000C50) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_EVNT_SEL0 is defined as MSR_S0_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_EVNT_SEL0 0x00000C50 - - -/** - Package. Uncore S-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S0_PMON_CTR0 (0x00000C51) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_CTR0 is defined as MSR_S0_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_CTR0 0x00000C51 - - -/** - Package. Uncore S-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S0_PMON_EVNT_SEL1 (0x00000C52) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_EVNT_SEL1 is defined as MSR_S0_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_EVNT_SEL1 0x00000C52 - - -/** - Package. Uncore S-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S0_PMON_CTR1 (0x00000C53) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_CTR1 is defined as MSR_S0_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_CTR1 0x00000C53 - - -/** - Package. Uncore S-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S0_PMON_EVNT_SEL2 (0x00000C54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_EVNT_SEL2 is defined as MSR_S0_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_EVNT_SEL2 0x00000C54 - - -/** - Package. Uncore S-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S0_PMON_CTR2 (0x00000C55) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_CTR2 is defined as MSR_S0_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_CTR2 0x00000C55 - - -/** - Package. Uncore S-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S0_PMON_EVNT_SEL3 (0x00000C56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_EVNT_SEL3 is defined as MSR_S0_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_EVNT_SEL3 0x00000C56 - - -/** - Package. Uncore S-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S0_PMON_CTR3 (0x00000C57) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_CTR3 is defined as MSR_S0_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_CTR3 0x00000C57 - - -/** - Package. Uncore B-box 1 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_B1_PMON_BOX_CTRL (0x00000C60) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_BOX_CTRL is defined as MSR_B1_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_BOX_CTRL 0x00000C60 - - -/** - Package. Uncore B-box 1 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_B1_PMON_BOX_STATUS (0x00000C61) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_BOX_STATUS is defined as MSR_B1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_BOX_STATUS 0x00000C61 - - -/** - Package. Uncore B-box 1 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL (0x00000C62) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL is defined as MSR_B1_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL 0x00000C62 - - -/** - Package. Uncore B-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B1_PMON_EVNT_SEL0 (0x00000C70) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_EVNT_SEL0 is defined as MSR_B1_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_EVNT_SEL0 0x00000C70 - - -/** - Package. Uncore B-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B1_PMON_CTR0 (0x00000C71) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_CTR0 is defined as MSR_B1_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_CTR0 0x00000C71 - - -/** - Package. Uncore B-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B1_PMON_EVNT_SEL1 (0x00000C72) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_EVNT_SEL1 is defined as MSR_B1_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_EVNT_SEL1 0x00000C72 - - -/** - Package. Uncore B-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B1_PMON_CTR1 (0x00000C73) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_CTR1 is defined as MSR_B1_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_CTR1 0x00000C73 - - -/** - Package. Uncore B-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_B1_PMON_EVNT_SEL2 (0x00000C74) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_EVNT_SEL2 is defined as MSR_B1_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_EVNT_SEL2 0x00000C74 - - -/** - Package. Uncore B-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B1_PMON_CTR2 (0x00000C75) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_CTR2 is defined as MSR_B1_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_CTR2 0x00000C75 - - -/** - Package. Uncore B-box 1vperfmon event select MSR. - - @param ECX MSR_NEHALEM_B1_PMON_EVNT_SEL3 (0x00000C76) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_EVNT_SEL3 is defined as MSR_B1_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_EVNT_SEL3 0x00000C76 - - -/** - Package. Uncore B-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_B1_PMON_CTR3 (0x00000C77) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_CTR3 is defined as MSR_B1_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_CTR3 0x00000C77 - - -/** - Package. Uncore W-box perfmon local box control MSR. - - @param ECX MSR_NEHALEM_W_PMON_BOX_CTRL (0x00000C80) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_BOX_CTRL is defined as MSR_W_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_W_PMON_BOX_CTRL 0x00000C80 - - -/** - Package. Uncore W-box perfmon local box status MSR. - - @param ECX MSR_NEHALEM_W_PMON_BOX_STATUS (0x00000C81) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_BOX_STATUS is defined as MSR_W_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_W_PMON_BOX_STATUS 0x00000C81 - - -/** - Package. Uncore W-box perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_W_PMON_BOX_OVF_CTRL (0x00000C82) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_BOX_OVF_CTRL is defined as MSR_W_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_W_PMON_BOX_OVF_CTRL 0x00000C82 - - -/** - Package. Uncore W-box perfmon event select MSR. - - @param ECX MSR_NEHALEM_W_PMON_EVNT_SEL0 (0x00000C90) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_EVNT_SEL0 is defined as MSR_W_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_EVNT_SEL0 0x00000C90 - - -/** - Package. Uncore W-box perfmon counter MSR. - - @param ECX MSR_NEHALEM_W_PMON_CTR0 (0x00000C91) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_CTR0 is defined as MSR_W_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_CTR0 0x00000C91 - - -/** - Package. Uncore W-box perfmon event select MSR. - - @param ECX MSR_NEHALEM_W_PMON_EVNT_SEL1 (0x00000C92) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_EVNT_SEL1 is defined as MSR_W_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_EVNT_SEL1 0x00000C92 - - -/** - Package. Uncore W-box perfmon counter MSR. - - @param ECX MSR_NEHALEM_W_PMON_CTR1 (0x00000C93) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_CTR1 is defined as MSR_W_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_CTR1 0x00000C93 - - -/** - Package. Uncore W-box perfmon event select MSR. - - @param ECX MSR_NEHALEM_W_PMON_EVNT_SEL2 (0x00000C94) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_EVNT_SEL2 is defined as MSR_W_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_EVNT_SEL2 0x00000C94 - - -/** - Package. Uncore W-box perfmon counter MSR. - - @param ECX MSR_NEHALEM_W_PMON_CTR2 (0x00000C95) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_CTR2 is defined as MSR_W_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_CTR2 0x00000C95 - - -/** - Package. Uncore W-box perfmon event select MSR. - - @param ECX MSR_NEHALEM_W_PMON_EVNT_SEL3 (0x00000C96) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_EVNT_SEL3 is defined as MSR_W_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_EVNT_SEL3 0x00000C96 - - -/** - Package. Uncore W-box perfmon counter MSR. - - @param ECX MSR_NEHALEM_W_PMON_CTR3 (0x00000C97) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_W_PMON_CTR3 is defined as MSR_W_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_W_PMON_CTR3 0x00000C97 - - -/** - Package. Uncore M-box 0 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_M0_PMON_BOX_CTRL (0x00000CA0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_BOX_CTRL is defined as MSR_M0_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_BOX_CTRL 0x00000CA0 - - -/** - Package. Uncore M-box 0 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_M0_PMON_BOX_STATUS (0x00000CA1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_BOX_STATUS is defined as MSR_M0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_BOX_STATUS 0x00000CA1 - - -/** - Package. Uncore M-box 0 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL (0x00000CA2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL is defined as MSR_M0_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL 0x00000CA2 - - -/** - Package. Uncore M-box 0 perfmon time stamp unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_TIMESTAMP (0x00000CA4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_TIMESTAMP); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_TIMESTAMP, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_TIMESTAMP is defined as MSR_M0_PMON_TIMESTAMP in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_TIMESTAMP 0x00000CA4 - - -/** - Package. Uncore M-box 0 perfmon DSP unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_DSP (0x00000CA5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_DSP); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_DSP, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_DSP is defined as MSR_M0_PMON_DSP in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_DSP 0x00000CA5 - - -/** - Package. Uncore M-box 0 perfmon ISS unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_ISS (0x00000CA6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ISS); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ISS, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_ISS is defined as MSR_M0_PMON_ISS in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_ISS 0x00000CA6 - - -/** - Package. Uncore M-box 0 perfmon MAP unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_MAP (0x00000CA7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MAP); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MAP, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_MAP is defined as MSR_M0_PMON_MAP in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_MAP 0x00000CA7 - - -/** - Package. Uncore M-box 0 perfmon MIC THR select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_MSC_THR (0x00000CA8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MSC_THR); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MSC_THR, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_MSC_THR is defined as MSR_M0_PMON_MSC_THR in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_MSC_THR 0x00000CA8 - - -/** - Package. Uncore M-box 0 perfmon PGT unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_PGT (0x00000CA9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_PGT); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_PGT, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_PGT is defined as MSR_M0_PMON_PGT in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_PGT 0x00000CA9 - - -/** - Package. Uncore M-box 0 perfmon PLD unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_PLD (0x00000CAA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_PLD); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_PLD, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_PLD is defined as MSR_M0_PMON_PLD in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_PLD 0x00000CAA - - -/** - Package. Uncore M-box 0 perfmon ZDP unit select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_ZDP (0x00000CAB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ZDP); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ZDP, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_ZDP is defined as MSR_M0_PMON_ZDP in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_ZDP 0x00000CAB - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL0 (0x00000CB0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL0 is defined as MSR_M0_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL0 0x00000CB0 - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR0 (0x00000CB1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR0 is defined as MSR_M0_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR0 0x00000CB1 - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL1 (0x00000CB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL1 is defined as MSR_M0_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL1 0x00000CB2 - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR1 (0x00000CB3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR1 is defined as MSR_M0_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR1 0x00000CB3 - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL2 (0x00000CB4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL2 is defined as MSR_M0_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL2 0x00000CB4 - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR2 (0x00000CB5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR2 is defined as MSR_M0_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR2 0x00000CB5 - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL3 (0x00000CB6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL3 is defined as MSR_M0_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL3 0x00000CB6 - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR3 (0x00000CB7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR3 is defined as MSR_M0_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR3 0x00000CB7 - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL4 (0x00000CB8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL4 is defined as MSR_M0_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL4 0x00000CB8 - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR4 (0x00000CB9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR4 is defined as MSR_M0_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR4 0x00000CB9 - - -/** - Package. Uncore M-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M0_PMON_EVNT_SEL5 (0x00000CBA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_EVNT_SEL5 is defined as MSR_M0_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_EVNT_SEL5 0x00000CBA - - -/** - Package. Uncore M-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M0_PMON_CTR5 (0x00000CBB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_CTR5 is defined as MSR_M0_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_CTR5 0x00000CBB - - -/** - Package. Uncore S-box 1 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_S1_PMON_BOX_CTRL (0x00000CC0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_BOX_CTRL is defined as MSR_S1_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_BOX_CTRL 0x00000CC0 - - -/** - Package. Uncore S-box 1 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_S1_PMON_BOX_STATUS (0x00000CC1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_BOX_STATUS is defined as MSR_S1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_BOX_STATUS 0x00000CC1 - - -/** - Package. Uncore S-box 1 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL (0x00000CC2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL is defined as MSR_S1_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL 0x00000CC2 - - -/** - Package. Uncore S-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S1_PMON_EVNT_SEL0 (0x00000CD0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_EVNT_SEL0 is defined as MSR_S1_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_EVNT_SEL0 0x00000CD0 - - -/** - Package. Uncore S-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S1_PMON_CTR0 (0x00000CD1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_CTR0 is defined as MSR_S1_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_CTR0 0x00000CD1 - - -/** - Package. Uncore S-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S1_PMON_EVNT_SEL1 (0x00000CD2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_EVNT_SEL1 is defined as MSR_S1_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_EVNT_SEL1 0x00000CD2 - - -/** - Package. Uncore S-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S1_PMON_CTR1 (0x00000CD3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_CTR1 is defined as MSR_S1_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_CTR1 0x00000CD3 - - -/** - Package. Uncore S-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S1_PMON_EVNT_SEL2 (0x00000CD4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_EVNT_SEL2 is defined as MSR_S1_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_EVNT_SEL2 0x00000CD4 - - -/** - Package. Uncore S-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S1_PMON_CTR2 (0x00000CD5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_CTR2 is defined as MSR_S1_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_CTR2 0x00000CD5 - - -/** - Package. Uncore S-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_S1_PMON_EVNT_SEL3 (0x00000CD6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_EVNT_SEL3 is defined as MSR_S1_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_EVNT_SEL3 0x00000CD6 - - -/** - Package. Uncore S-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_S1_PMON_CTR3 (0x00000CD7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_CTR3 is defined as MSR_S1_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_CTR3 0x00000CD7 - - -/** - Package. Uncore M-box 1 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_M1_PMON_BOX_CTRL (0x00000CE0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_BOX_CTRL is defined as MSR_M1_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_BOX_CTRL 0x00000CE0 - - -/** - Package. Uncore M-box 1 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_M1_PMON_BOX_STATUS (0x00000CE1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_BOX_STATUS is defined as MSR_M1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_BOX_STATUS 0x00000CE1 - - -/** - Package. Uncore M-box 1 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL (0x00000CE2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL is defined as MSR_M1_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL 0x00000CE2 - - -/** - Package. Uncore M-box 1 perfmon time stamp unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_TIMESTAMP (0x00000CE4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_TIMESTAMP); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_TIMESTAMP, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_TIMESTAMP is defined as MSR_M1_PMON_TIMESTAMP in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_TIMESTAMP 0x00000CE4 - - -/** - Package. Uncore M-box 1 perfmon DSP unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_DSP (0x00000CE5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_DSP); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_DSP, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_DSP is defined as MSR_M1_PMON_DSP in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_DSP 0x00000CE5 - - -/** - Package. Uncore M-box 1 perfmon ISS unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_ISS (0x00000CE6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ISS); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ISS, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_ISS is defined as MSR_M1_PMON_ISS in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_ISS 0x00000CE6 - - -/** - Package. Uncore M-box 1 perfmon MAP unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_MAP (0x00000CE7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MAP); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MAP, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_MAP is defined as MSR_M1_PMON_MAP in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_MAP 0x00000CE7 - - -/** - Package. Uncore M-box 1 perfmon MIC THR select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_MSC_THR (0x00000CE8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MSC_THR); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MSC_THR, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_MSC_THR is defined as MSR_M1_PMON_MSC_THR in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_MSC_THR 0x00000CE8 - - -/** - Package. Uncore M-box 1 perfmon PGT unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_PGT (0x00000CE9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_PGT); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_PGT, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_PGT is defined as MSR_M1_PMON_PGT in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_PGT 0x00000CE9 - - -/** - Package. Uncore M-box 1 perfmon PLD unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_PLD (0x00000CEA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_PLD); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_PLD, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_PLD is defined as MSR_M1_PMON_PLD in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_PLD 0x00000CEA - - -/** - Package. Uncore M-box 1 perfmon ZDP unit select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_ZDP (0x00000CEB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ZDP); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ZDP, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_ZDP is defined as MSR_M1_PMON_ZDP in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_ZDP 0x00000CEB - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL0 (0x00000CF0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL0 is defined as MSR_M1_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL0 0x00000CF0 - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR0 (0x00000CF1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR0 is defined as MSR_M1_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR0 0x00000CF1 - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL1 (0x00000CF2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL1 is defined as MSR_M1_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL1 0x00000CF2 - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR1 (0x00000CF3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR1 is defined as MSR_M1_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR1 0x00000CF3 - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL2 (0x00000CF4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL2 is defined as MSR_M1_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL2 0x00000CF4 - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR2 (0x00000CF5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR2 is defined as MSR_M1_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR2 0x00000CF5 - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL3 (0x00000CF6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL3 is defined as MSR_M1_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL3 0x00000CF6 - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR3 (0x00000CF7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR3 is defined as MSR_M1_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR3 0x00000CF7 - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL4 (0x00000CF8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL4 is defined as MSR_M1_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL4 0x00000CF8 - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR4 (0x00000CF9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR4 is defined as MSR_M1_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR4 0x00000CF9 - - -/** - Package. Uncore M-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_M1_PMON_EVNT_SEL5 (0x00000CFA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_EVNT_SEL5 is defined as MSR_M1_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_EVNT_SEL5 0x00000CFA - - -/** - Package. Uncore M-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_M1_PMON_CTR5 (0x00000CFB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_CTR5 is defined as MSR_M1_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_CTR5 0x00000CFB - - -/** - Package. Uncore C-box 0 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C0_PMON_BOX_CTRL (0x00000D00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_BOX_CTRL is defined as MSR_C0_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_BOX_CTRL 0x00000D00 - - -/** - Package. Uncore C-box 0 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C0_PMON_BOX_STATUS (0x00000D01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_BOX_STATUS is defined as MSR_C0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_BOX_STATUS 0x00000D01 - - -/** - Package. Uncore C-box 0 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL (0x00000D02) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL is defined as MSR_C0_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL 0x00000D02 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL0 (0x00000D10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL0 is defined as MSR_C0_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL0 0x00000D10 - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR0 (0x00000D11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR0 is defined as MSR_C0_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR0 0x00000D11 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL1 (0x00000D12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL1 is defined as MSR_C0_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL1 0x00000D12 - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR1 (0x00000D13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR1 is defined as MSR_C0_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR1 0x00000D13 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL2 (0x00000D14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL2 is defined as MSR_C0_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL2 0x00000D14 - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR2 (0x00000D15) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR2 is defined as MSR_C0_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR2 0x00000D15 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL3 (0x00000D16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL3 is defined as MSR_C0_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL3 0x00000D16 - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR3 (0x00000D17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR3 is defined as MSR_C0_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR3 0x00000D17 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL4 (0x00000D18) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL4 is defined as MSR_C0_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL4 0x00000D18 - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR4 (0x00000D19) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR4 is defined as MSR_C0_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR4 0x00000D19 - - -/** - Package. Uncore C-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C0_PMON_EVNT_SEL5 (0x00000D1A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_EVNT_SEL5 is defined as MSR_C0_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_EVNT_SEL5 0x00000D1A - - -/** - Package. Uncore C-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C0_PMON_CTR5 (0x00000D1B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C0_PMON_CTR5 is defined as MSR_C0_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C0_PMON_CTR5 0x00000D1B - - -/** - Package. Uncore C-box 4 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C4_PMON_BOX_CTRL (0x00000D20) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_BOX_CTRL is defined as MSR_C4_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_BOX_CTRL 0x00000D20 - - -/** - Package. Uncore C-box 4 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C4_PMON_BOX_STATUS (0x00000D21) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_BOX_STATUS is defined as MSR_C4_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_BOX_STATUS 0x00000D21 - - -/** - Package. Uncore C-box 4 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL (0x00000D22) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL is defined as MSR_C4_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL 0x00000D22 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL0 (0x00000D30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL0 is defined as MSR_C4_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL0 0x00000D30 - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR0 (0x00000D31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR0 is defined as MSR_C4_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR0 0x00000D31 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL1 (0x00000D32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL1 is defined as MSR_C4_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL1 0x00000D32 - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR1 (0x00000D33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR1 is defined as MSR_C4_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR1 0x00000D33 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL2 (0x00000D34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL2 is defined as MSR_C4_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL2 0x00000D34 - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR2 (0x00000D35) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR2 is defined as MSR_C4_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR2 0x00000D35 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL3 (0x00000D36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL3 is defined as MSR_C4_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL3 0x00000D36 - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR3 (0x00000D37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR3 is defined as MSR_C4_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR3 0x00000D37 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL4 (0x00000D38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL4 is defined as MSR_C4_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL4 0x00000D38 - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR4 (0x00000D39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR4 is defined as MSR_C4_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR4 0x00000D39 - - -/** - Package. Uncore C-box 4 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C4_PMON_EVNT_SEL5 (0x00000D3A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_EVNT_SEL5 is defined as MSR_C4_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_EVNT_SEL5 0x00000D3A - - -/** - Package. Uncore C-box 4 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C4_PMON_CTR5 (0x00000D3B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C4_PMON_CTR5 is defined as MSR_C4_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C4_PMON_CTR5 0x00000D3B - - -/** - Package. Uncore C-box 2 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C2_PMON_BOX_CTRL (0x00000D40) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_BOX_CTRL is defined as MSR_C2_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_BOX_CTRL 0x00000D40 - - -/** - Package. Uncore C-box 2 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C2_PMON_BOX_STATUS (0x00000D41) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_BOX_STATUS is defined as MSR_C2_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_BOX_STATUS 0x00000D41 - - -/** - Package. Uncore C-box 2 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL (0x00000D42) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL is defined as MSR_C2_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL 0x00000D42 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL0 (0x00000D50) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL0 is defined as MSR_C2_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL0 0x00000D50 - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR0 (0x00000D51) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR0 is defined as MSR_C2_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR0 0x00000D51 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL1 (0x00000D52) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL1 is defined as MSR_C2_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL1 0x00000D52 - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR1 (0x00000D53) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR1 is defined as MSR_C2_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR1 0x00000D53 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL2 (0x00000D54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL2 is defined as MSR_C2_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL2 0x00000D54 - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR2 (0x00000D55) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR2 is defined as MSR_C2_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR2 0x00000D55 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL3 (0x00000D56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL3 is defined as MSR_C2_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL3 0x00000D56 - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR3 (0x00000D57) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR3 is defined as MSR_C2_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR3 0x00000D57 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL4 (0x00000D58) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL4 is defined as MSR_C2_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL4 0x00000D58 - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR4 (0x00000D59) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR4 is defined as MSR_C2_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR4 0x00000D59 - - -/** - Package. Uncore C-box 2 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C2_PMON_EVNT_SEL5 (0x00000D5A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_EVNT_SEL5 is defined as MSR_C2_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_EVNT_SEL5 0x00000D5A - - -/** - Package. Uncore C-box 2 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C2_PMON_CTR5 (0x00000D5B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C2_PMON_CTR5 is defined as MSR_C2_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C2_PMON_CTR5 0x00000D5B - - -/** - Package. Uncore C-box 6 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C6_PMON_BOX_CTRL (0x00000D60) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_BOX_CTRL is defined as MSR_C6_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_BOX_CTRL 0x00000D60 - - -/** - Package. Uncore C-box 6 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C6_PMON_BOX_STATUS (0x00000D61) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_BOX_STATUS is defined as MSR_C6_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_BOX_STATUS 0x00000D61 - - -/** - Package. Uncore C-box 6 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL (0x00000D62) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL is defined as MSR_C6_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL 0x00000D62 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL0 (0x00000D70) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL0 is defined as MSR_C6_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL0 0x00000D70 - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR0 (0x00000D71) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR0 is defined as MSR_C6_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR0 0x00000D71 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL1 (0x00000D72) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL1 is defined as MSR_C6_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL1 0x00000D72 - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR1 (0x00000D73) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR1 is defined as MSR_C6_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR1 0x00000D73 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL2 (0x00000D74) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL2 is defined as MSR_C6_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL2 0x00000D74 - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR2 (0x00000D75) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR2 is defined as MSR_C6_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR2 0x00000D75 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL3 (0x00000D76) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL3 is defined as MSR_C6_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL3 0x00000D76 - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR3 (0x00000D77) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR3 is defined as MSR_C6_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR3 0x00000D77 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL4 (0x00000D78) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL4 is defined as MSR_C6_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL4 0x00000D78 - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR4 (0x00000D79) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR4 is defined as MSR_C6_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR4 0x00000D79 - - -/** - Package. Uncore C-box 6 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C6_PMON_EVNT_SEL5 (0x00000D7A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_EVNT_SEL5 is defined as MSR_C6_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_EVNT_SEL5 0x00000D7A - - -/** - Package. Uncore C-box 6 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C6_PMON_CTR5 (0x00000D7B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C6_PMON_CTR5 is defined as MSR_C6_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C6_PMON_CTR5 0x00000D7B - - -/** - Package. Uncore C-box 1 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C1_PMON_BOX_CTRL (0x00000D80) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_BOX_CTRL is defined as MSR_C1_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_BOX_CTRL 0x00000D80 - - -/** - Package. Uncore C-box 1 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C1_PMON_BOX_STATUS (0x00000D81) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_BOX_STATUS is defined as MSR_C1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_BOX_STATUS 0x00000D81 - - -/** - Package. Uncore C-box 1 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL (0x00000D82) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL is defined as MSR_C1_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL 0x00000D82 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL0 (0x00000D90) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL0 is defined as MSR_C1_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL0 0x00000D90 - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR0 (0x00000D91) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR0 is defined as MSR_C1_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR0 0x00000D91 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL1 (0x00000D92) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL1 is defined as MSR_C1_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL1 0x00000D92 - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR1 (0x00000D93) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR1 is defined as MSR_C1_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR1 0x00000D93 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL2 (0x00000D94) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL2 is defined as MSR_C1_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL2 0x00000D94 - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR2 (0x00000D95) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR2 is defined as MSR_C1_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR2 0x00000D95 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL3 (0x00000D96) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL3 is defined as MSR_C1_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL3 0x00000D96 - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR3 (0x00000D97) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR3 is defined as MSR_C1_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR3 0x00000D97 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL4 (0x00000D98) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL4 is defined as MSR_C1_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL4 0x00000D98 - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR4 (0x00000D99) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR4 is defined as MSR_C1_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR4 0x00000D99 - - -/** - Package. Uncore C-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C1_PMON_EVNT_SEL5 (0x00000D9A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_EVNT_SEL5 is defined as MSR_C1_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_EVNT_SEL5 0x00000D9A - - -/** - Package. Uncore C-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C1_PMON_CTR5 (0x00000D9B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C1_PMON_CTR5 is defined as MSR_C1_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C1_PMON_CTR5 0x00000D9B - - -/** - Package. Uncore C-box 5 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C5_PMON_BOX_CTRL (0x00000DA0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_BOX_CTRL is defined as MSR_C5_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_BOX_CTRL 0x00000DA0 - - -/** - Package. Uncore C-box 5 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C5_PMON_BOX_STATUS (0x00000DA1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_BOX_STATUS is defined as MSR_C5_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_BOX_STATUS 0x00000DA1 - - -/** - Package. Uncore C-box 5 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL (0x00000DA2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL is defined as MSR_C5_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL 0x00000DA2 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL0 (0x00000DB0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL0 is defined as MSR_C5_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL0 0x00000DB0 - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR0 (0x00000DB1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR0 is defined as MSR_C5_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR0 0x00000DB1 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL1 (0x00000DB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL1 is defined as MSR_C5_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL1 0x00000DB2 - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR1 (0x00000DB3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR1 is defined as MSR_C5_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR1 0x00000DB3 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL2 (0x00000DB4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL2 is defined as MSR_C5_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL2 0x00000DB4 - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR2 (0x00000DB5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR2 is defined as MSR_C5_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR2 0x00000DB5 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL3 (0x00000DB6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL3 is defined as MSR_C5_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL3 0x00000DB6 - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR3 (0x00000DB7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR3 is defined as MSR_C5_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR3 0x00000DB7 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL4 (0x00000DB8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL4 is defined as MSR_C5_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL4 0x00000DB8 - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR4 (0x00000DB9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR4 is defined as MSR_C5_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR4 0x00000DB9 - - -/** - Package. Uncore C-box 5 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C5_PMON_EVNT_SEL5 (0x00000DBA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_EVNT_SEL5 is defined as MSR_C5_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_EVNT_SEL5 0x00000DBA - - -/** - Package. Uncore C-box 5 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C5_PMON_CTR5 (0x00000DBB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C5_PMON_CTR5 is defined as MSR_C5_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C5_PMON_CTR5 0x00000DBB - - -/** - Package. Uncore C-box 3 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C3_PMON_BOX_CTRL (0x00000DC0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_BOX_CTRL is defined as MSR_C3_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_BOX_CTRL 0x00000DC0 - - -/** - Package. Uncore C-box 3 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C3_PMON_BOX_STATUS (0x00000DC1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_BOX_STATUS is defined as MSR_C3_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_BOX_STATUS 0x00000DC1 - - -/** - Package. Uncore C-box 3 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL (0x00000DC2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL is defined as MSR_C3_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL 0x00000DC2 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL0 (0x00000DD0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL0 is defined as MSR_C3_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL0 0x00000DD0 - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR0 (0x00000DD1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR0 is defined as MSR_C3_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR0 0x00000DD1 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL1 (0x00000DD2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL1 is defined as MSR_C3_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL1 0x00000DD2 - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR1 (0x00000DD3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR1 is defined as MSR_C3_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR1 0x00000DD3 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL2 (0x00000DD4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL2 is defined as MSR_C3_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL2 0x00000DD4 - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR2 (0x00000DD5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR2 is defined as MSR_C3_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR2 0x00000DD5 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL3 (0x00000DD6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL3 is defined as MSR_C3_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL3 0x00000DD6 - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR3 (0x00000DD7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR3 is defined as MSR_C3_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR3 0x00000DD7 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL4 (0x00000DD8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL4 is defined as MSR_C3_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL4 0x00000DD8 - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR4 (0x00000DD9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR4 is defined as MSR_C3_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR4 0x00000DD9 - - -/** - Package. Uncore C-box 3 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C3_PMON_EVNT_SEL5 (0x00000DDA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_EVNT_SEL5 is defined as MSR_C3_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_EVNT_SEL5 0x00000DDA - - -/** - Package. Uncore C-box 3 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C3_PMON_CTR5 (0x00000DDB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C3_PMON_CTR5 is defined as MSR_C3_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C3_PMON_CTR5 0x00000DDB - - -/** - Package. Uncore C-box 7 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_C7_PMON_BOX_CTRL (0x00000DE0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_BOX_CTRL is defined as MSR_C7_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_BOX_CTRL 0x00000DE0 - - -/** - Package. Uncore C-box 7 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_C7_PMON_BOX_STATUS (0x00000DE1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_BOX_STATUS is defined as MSR_C7_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_BOX_STATUS 0x00000DE1 - - -/** - Package. Uncore C-box 7 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL (0x00000DE2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL is defined as MSR_C7_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL 0x00000DE2 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL0 (0x00000DF0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL0 is defined as MSR_C7_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL0 0x00000DF0 - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR0 (0x00000DF1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR0 is defined as MSR_C7_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR0 0x00000DF1 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL1 (0x00000DF2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL1 is defined as MSR_C7_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL1 0x00000DF2 - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR1 (0x00000DF3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR1 is defined as MSR_C7_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR1 0x00000DF3 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL2 (0x00000DF4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL2 is defined as MSR_C7_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL2 0x00000DF4 - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR2 (0x00000DF5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR2 is defined as MSR_C7_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR2 0x00000DF5 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL3 (0x00000DF6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL3 is defined as MSR_C7_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL3 0x00000DF6 - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR3 (0x00000DF7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR3 is defined as MSR_C7_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR3 0x00000DF7 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL4 (0x00000DF8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL4 is defined as MSR_C7_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL4 0x00000DF8 - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR4 (0x00000DF9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR4 is defined as MSR_C7_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR4 0x00000DF9 - - -/** - Package. Uncore C-box 7 perfmon event select MSR. - - @param ECX MSR_NEHALEM_C7_PMON_EVNT_SEL5 (0x00000DFA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_EVNT_SEL5 is defined as MSR_C7_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_EVNT_SEL5 0x00000DFA - - -/** - Package. Uncore C-box 7 perfmon counter MSR. - - @param ECX MSR_NEHALEM_C7_PMON_CTR5 (0x00000DFB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_C7_PMON_CTR5 is defined as MSR_C7_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_C7_PMON_CTR5 0x00000DFB - - -/** - Package. Uncore R-box 0 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_R0_PMON_BOX_CTRL (0x00000E00) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_BOX_CTRL is defined as MSR_R0_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_BOX_CTRL 0x00000E00 - - -/** - Package. Uncore R-box 0 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_R0_PMON_BOX_STATUS (0x00000E01) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_BOX_STATUS is defined as MSR_R0_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_BOX_STATUS 0x00000E01 - - -/** - Package. Uncore R-box 0 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL (0x00000E02) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL is defined as MSR_R0_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL 0x00000E02 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 0 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P0 (0x00000E04) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P0); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P0, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P0 is defined as MSR_R0_PMON_IPERF0_P0 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P0 0x00000E04 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 1 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P1 (0x00000E05) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P1); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P1, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P1 is defined as MSR_R0_PMON_IPERF0_P1 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P1 0x00000E05 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 2 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P2 (0x00000E06) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P2); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P2, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P2 is defined as MSR_R0_PMON_IPERF0_P2 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P2 0x00000E06 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 3 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P3 (0x00000E07) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P3); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P3, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P3 is defined as MSR_R0_PMON_IPERF0_P3 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P3 0x00000E07 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 4 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P4 (0x00000E08) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P4); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P4, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P4 is defined as MSR_R0_PMON_IPERF0_P4 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P4 0x00000E08 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 5 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P5 (0x00000E09) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P5); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P5, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P5 is defined as MSR_R0_PMON_IPERF0_P5 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P5 0x00000E09 - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 6 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P6 (0x00000E0A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P6); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P6, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P6 is defined as MSR_R0_PMON_IPERF0_P6 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P6 0x00000E0A - - -/** - Package. Uncore R-box 0 perfmon IPERF0 unit Port 7 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_IPERF0_P7 (0x00000E0B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P7); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P7, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_IPERF0_P7 is defined as MSR_R0_PMON_IPERF0_P7 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_IPERF0_P7 0x00000E0B - - -/** - Package. Uncore R-box 0 perfmon QLX unit Port 0 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_QLX_P0 (0x00000E0C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P0); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P0, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_QLX_P0 is defined as MSR_R0_PMON_QLX_P0 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_QLX_P0 0x00000E0C - - -/** - Package. Uncore R-box 0 perfmon QLX unit Port 1 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_QLX_P1 (0x00000E0D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P1); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P1, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_QLX_P1 is defined as MSR_R0_PMON_QLX_P1 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_QLX_P1 0x00000E0D - - -/** - Package. Uncore R-box 0 perfmon QLX unit Port 2 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_QLX_P2 (0x00000E0E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P2); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P2, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_QLX_P2 is defined as MSR_R0_PMON_QLX_P2 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_QLX_P2 0x00000E0E - - -/** - Package. Uncore R-box 0 perfmon QLX unit Port 3 select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_QLX_P3 (0x00000E0F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P3); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P3, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_QLX_P3 is defined as MSR_R0_PMON_QLX_P3 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_QLX_P3 0x00000E0F - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL0 (0x00000E10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL0 is defined as MSR_R0_PMON_EVNT_SEL0 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL0 0x00000E10 - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR0 (0x00000E11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR0); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR0, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR0 is defined as MSR_R0_PMON_CTR0 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR0 0x00000E11 - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL1 (0x00000E12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL1); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL1, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL1 is defined as MSR_R0_PMON_EVNT_SEL1 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL1 0x00000E12 - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR1 (0x00000E13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR1); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR1, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR1 is defined as MSR_R0_PMON_CTR1 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR1 0x00000E13 - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL2 (0x00000E14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL2); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL2, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL2 is defined as MSR_R0_PMON_EVNT_SEL2 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL2 0x00000E14 - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR2 (0x00000E15) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR2); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR2, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR2 is defined as MSR_R0_PMON_CTR2 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR2 0x00000E15 - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL3 (0x00000E16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL3); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL3, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL3 is defined as MSR_R0_PMON_EVNT_SEL3 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL3 0x00000E16 - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR3 (0x00000E17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR3); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR3, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR3 is defined as MSR_R0_PMON_CTR3 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR3 0x00000E17 - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL4 (0x00000E18) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL4); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL4, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL4 is defined as MSR_R0_PMON_EVNT_SEL4 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL4 0x00000E18 - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR4 (0x00000E19) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR4); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR4, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR4 is defined as MSR_R0_PMON_CTR4 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR4 0x00000E19 - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL5 (0x00000E1A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL5); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL5, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL5 is defined as MSR_R0_PMON_EVNT_SEL5 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL5 0x00000E1A - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR5 (0x00000E1B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR5); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR5, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR5 is defined as MSR_R0_PMON_CTR5 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR5 0x00000E1B - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL6 (0x00000E1C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL6); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL6, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL6 is defined as MSR_R0_PMON_EVNT_SEL6 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL6 0x00000E1C - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR6 (0x00000E1D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR6); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR6, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR6 is defined as MSR_R0_PMON_CTR6 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR6 0x00000E1D - - -/** - Package. Uncore R-box 0 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R0_PMON_EVNT_SEL7 (0x00000E1E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL7); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL7, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_EVNT_SEL7 is defined as MSR_R0_PMON_EVNT_SEL7 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_EVNT_SEL7 0x00000E1E - - -/** - Package. Uncore R-box 0 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R0_PMON_CTR7 (0x00000E1F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR7); - AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR7, Msr); - @endcode - @note MSR_NEHALEM_R0_PMON_CTR7 is defined as MSR_R0_PMON_CTR7 in SDM. -**/ -#define MSR_NEHALEM_R0_PMON_CTR7 0x00000E1F - - -/** - Package. Uncore R-box 1 perfmon local box control MSR. - - @param ECX MSR_NEHALEM_R1_PMON_BOX_CTRL (0x00000E20) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_BOX_CTRL is defined as MSR_R1_PMON_BOX_CTRL in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_BOX_CTRL 0x00000E20 - - -/** - Package. Uncore R-box 1 perfmon local box status MSR. - - @param ECX MSR_NEHALEM_R1_PMON_BOX_STATUS (0x00000E21) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_BOX_STATUS is defined as MSR_R1_PMON_BOX_STATUS in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_BOX_STATUS 0x00000E21 - - -/** - Package. Uncore R-box 1 perfmon local box overflow control MSR. - - @param ECX MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL (0x00000E22) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL is defined as MSR_R1_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL 0x00000E22 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 8 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P8 (0x00000E24) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P8); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P8, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P8 is defined as MSR_R1_PMON_IPERF1_P8 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P8 0x00000E24 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 9 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P9 (0x00000E25) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P9); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P9, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P9 is defined as MSR_R1_PMON_IPERF1_P9 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P9 0x00000E25 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 10 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P10 (0x00000E26) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P10); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P10, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P10 is defined as MSR_R1_PMON_IPERF1_P10 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P10 0x00000E26 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 11 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P11 (0x00000E27) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P11); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P11, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P11 is defined as MSR_R1_PMON_IPERF1_P11 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P11 0x00000E27 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 12 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P12 (0x00000E28) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P12); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P12, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P12 is defined as MSR_R1_PMON_IPERF1_P12 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P12 0x00000E28 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 13 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P13 (0x00000E29) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P13); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P13, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P13 is defined as MSR_R1_PMON_IPERF1_P13 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P13 0x00000E29 - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 14 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P14 (0x00000E2A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P14); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P14, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P14 is defined as MSR_R1_PMON_IPERF1_P14 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P14 0x00000E2A - - -/** - Package. Uncore R-box 1 perfmon IPERF1 unit Port 15 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_IPERF1_P15 (0x00000E2B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P15); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P15, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_IPERF1_P15 is defined as MSR_R1_PMON_IPERF1_P15 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_IPERF1_P15 0x00000E2B - - -/** - Package. Uncore R-box 1 perfmon QLX unit Port 4 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_QLX_P4 (0x00000E2C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P4); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P4, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_QLX_P4 is defined as MSR_R1_PMON_QLX_P4 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_QLX_P4 0x00000E2C - - -/** - Package. Uncore R-box 1 perfmon QLX unit Port 5 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_QLX_P5 (0x00000E2D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P5); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P5, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_QLX_P5 is defined as MSR_R1_PMON_QLX_P5 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_QLX_P5 0x00000E2D - - -/** - Package. Uncore R-box 1 perfmon QLX unit Port 6 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_QLX_P6 (0x00000E2E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P6); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P6, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_QLX_P6 is defined as MSR_R1_PMON_QLX_P6 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_QLX_P6 0x00000E2E - - -/** - Package. Uncore R-box 1 perfmon QLX unit Port 7 select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_QLX_P7 (0x00000E2F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P7); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P7, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_QLX_P7 is defined as MSR_R1_PMON_QLX_P7 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_QLX_P7 0x00000E2F - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL8 (0x00000E30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL8); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL8, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL8 is defined as MSR_R1_PMON_EVNT_SEL8 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL8 0x00000E30 - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR8 (0x00000E31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR8); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR8, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR8 is defined as MSR_R1_PMON_CTR8 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR8 0x00000E31 - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL9 (0x00000E32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL9); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL9, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL9 is defined as MSR_R1_PMON_EVNT_SEL9 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL9 0x00000E32 - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR9 (0x00000E33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR9); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR9, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR9 is defined as MSR_R1_PMON_CTR9 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR9 0x00000E33 - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL10 (0x00000E34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL10); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL10, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL10 is defined as MSR_R1_PMON_EVNT_SEL10 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL10 0x00000E34 - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR10 (0x00000E35) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR10); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR10, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR10 is defined as MSR_R1_PMON_CTR10 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR10 0x00000E35 - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL11 (0x00000E36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL11); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL11, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL11 is defined as MSR_R1_PMON_EVNT_SEL11 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL11 0x00000E36 - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR11 (0x00000E37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR11); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR11, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR11 is defined as MSR_R1_PMON_CTR11 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR11 0x00000E37 - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL12 (0x00000E38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL12); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL12, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL12 is defined as MSR_R1_PMON_EVNT_SEL12 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL12 0x00000E38 - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR12 (0x00000E39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR12); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR12, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR12 is defined as MSR_R1_PMON_CTR12 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR12 0x00000E39 - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL13 (0x00000E3A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL13); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL13, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL13 is defined as MSR_R1_PMON_EVNT_SEL13 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL13 0x00000E3A - - -/** - Package. Uncore R-box 1perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR13 (0x00000E3B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR13); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR13, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR13 is defined as MSR_R1_PMON_CTR13 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR13 0x00000E3B - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL14 (0x00000E3C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL14); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL14, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL14 is defined as MSR_R1_PMON_EVNT_SEL14 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL14 0x00000E3C - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR14 (0x00000E3D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR14); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR14, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR14 is defined as MSR_R1_PMON_CTR14 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR14 0x00000E3D - - -/** - Package. Uncore R-box 1 perfmon event select MSR. - - @param ECX MSR_NEHALEM_R1_PMON_EVNT_SEL15 (0x00000E3E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL15); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL15, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_EVNT_SEL15 is defined as MSR_R1_PMON_EVNT_SEL15 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_EVNT_SEL15 0x00000E3E - - -/** - Package. Uncore R-box 1 perfmon counter MSR. - - @param ECX MSR_NEHALEM_R1_PMON_CTR15 (0x00000E3F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR15); - AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR15, Msr); - @endcode - @note MSR_NEHALEM_R1_PMON_CTR15 is defined as MSR_R1_PMON_CTR15 in SDM. -**/ -#define MSR_NEHALEM_R1_PMON_CTR15 0x00000E3F - - -/** - Package. Uncore B-box 0 perfmon local box match MSR. - - @param ECX MSR_NEHALEM_B0_PMON_MATCH (0x00000E45) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_MATCH, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_MATCH is defined as MSR_B0_PMON_MATCH in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_MATCH 0x00000E45 - - -/** - Package. Uncore B-box 0 perfmon local box mask MSR. - - @param ECX MSR_NEHALEM_B0_PMON_MASK (0x00000E46) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_MASK); - AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_MASK, Msr); - @endcode - @note MSR_NEHALEM_B0_PMON_MASK is defined as MSR_B0_PMON_MASK in SDM. -**/ -#define MSR_NEHALEM_B0_PMON_MASK 0x00000E46 - - -/** - Package. Uncore S-box 0 perfmon local box match MSR. - - @param ECX MSR_NEHALEM_S0_PMON_MATCH (0x00000E49) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_MATCH, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_MATCH is defined as MSR_S0_PMON_MATCH in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_MATCH 0x00000E49 - - -/** - Package. Uncore S-box 0 perfmon local box mask MSR. - - @param ECX MSR_NEHALEM_S0_PMON_MASK (0x00000E4A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_MASK); - AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_MASK, Msr); - @endcode - @note MSR_NEHALEM_S0_PMON_MASK is defined as MSR_S0_PMON_MASK in SDM. -**/ -#define MSR_NEHALEM_S0_PMON_MASK 0x00000E4A - - -/** - Package. Uncore B-box 1 perfmon local box match MSR. - - @param ECX MSR_NEHALEM_B1_PMON_MATCH (0x00000E4D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_MATCH, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_MATCH is defined as MSR_B1_PMON_MATCH in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_MATCH 0x00000E4D - - -/** - Package. Uncore B-box 1 perfmon local box mask MSR. - - @param ECX MSR_NEHALEM_B1_PMON_MASK (0x00000E4E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_MASK); - AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_MASK, Msr); - @endcode - @note MSR_NEHALEM_B1_PMON_MASK is defined as MSR_B1_PMON_MASK in SDM. -**/ -#define MSR_NEHALEM_B1_PMON_MASK 0x00000E4E - - -/** - Package. Uncore M-box 0 perfmon local box address match/mask config MSR. - - @param ECX MSR_NEHALEM_M0_PMON_MM_CONFIG (0x00000E54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MM_CONFIG); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MM_CONFIG, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_MM_CONFIG is defined as MSR_M0_PMON_MM_CONFIG in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_MM_CONFIG 0x00000E54 - - -/** - Package. Uncore M-box 0 perfmon local box address match MSR. - - @param ECX MSR_NEHALEM_M0_PMON_ADDR_MATCH (0x00000E55) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MATCH, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_ADDR_MATCH is defined as MSR_M0_PMON_ADDR_MATCH in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_ADDR_MATCH 0x00000E55 - - -/** - Package. Uncore M-box 0 perfmon local box address mask MSR. - - @param ECX MSR_NEHALEM_M0_PMON_ADDR_MASK (0x00000E56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MASK); - AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MASK, Msr); - @endcode - @note MSR_NEHALEM_M0_PMON_ADDR_MASK is defined as MSR_M0_PMON_ADDR_MASK in SDM. -**/ -#define MSR_NEHALEM_M0_PMON_ADDR_MASK 0x00000E56 - - -/** - Package. Uncore S-box 1 perfmon local box match MSR. - - @param ECX MSR_NEHALEM_S1_PMON_MATCH (0x00000E59) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_MATCH, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_MATCH is defined as MSR_S1_PMON_MATCH in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_MATCH 0x00000E59 - - -/** - Package. Uncore S-box 1 perfmon local box mask MSR. - - @param ECX MSR_NEHALEM_S1_PMON_MASK (0x00000E5A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_MASK); - AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_MASK, Msr); - @endcode - @note MSR_NEHALEM_S1_PMON_MASK is defined as MSR_S1_PMON_MASK in SDM. -**/ -#define MSR_NEHALEM_S1_PMON_MASK 0x00000E5A - - -/** - Package. Uncore M-box 1 perfmon local box address match/mask config MSR. - - @param ECX MSR_NEHALEM_M1_PMON_MM_CONFIG (0x00000E5C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MM_CONFIG); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MM_CONFIG, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_MM_CONFIG is defined as MSR_M1_PMON_MM_CONFIG in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_MM_CONFIG 0x00000E5C - - -/** - Package. Uncore M-box 1 perfmon local box address match MSR. - - @param ECX MSR_NEHALEM_M1_PMON_ADDR_MATCH (0x00000E5D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MATCH); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MATCH, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_ADDR_MATCH is defined as MSR_M1_PMON_ADDR_MATCH in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_ADDR_MATCH 0x00000E5D - - -/** - Package. Uncore M-box 1 perfmon local box address mask MSR. - - @param ECX MSR_NEHALEM_M1_PMON_ADDR_MASK (0x00000E5E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MASK); - AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MASK, Msr); - @endcode - @note MSR_NEHALEM_M1_PMON_ADDR_MASK is defined as MSR_M1_PMON_ADDR_MASK in SDM. -**/ -#define MSR_NEHALEM_M1_PMON_ADDR_MASK 0x00000E5E - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/P6Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/P6Msr.h deleted file mode 100644 index aec2e2c86..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/P6Msr.h +++ /dev/null @@ -1,1712 +0,0 @@ -/** @file - MSR Definitions for P6 Family Processors. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.21. - -**/ - -#ifndef __P6_MSR_H__ -#define __P6_MSR_H__ - -#include - -/** - Is P6 Family Processors? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_P6_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x03 || \ - DisplayModel == 0x05 || \ - DisplayModel == 0x07 || \ - DisplayModel == 0x08 || \ - DisplayModel == 0x0A || \ - DisplayModel == 0x0B \ - ) \ - ) - -/** - See Section 35.22, "MSRs in Pentium Processors.". - - @param ECX MSR_P6_P5_MC_ADDR (0x00000000) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_P5_MC_ADDR); - AsmWriteMsr64 (MSR_P6_P5_MC_ADDR, Msr); - @endcode - @note MSR_P6_P5_MC_ADDR is defined as P5_MC_ADDR in SDM. -**/ -#define MSR_P6_P5_MC_ADDR 0x00000000 - - -/** - See Section 35.22, "MSRs in Pentium Processors.". - - @param ECX MSR_P6_P5_MC_TYPE (0x00000001) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_P5_MC_TYPE); - AsmWriteMsr64 (MSR_P6_P5_MC_TYPE, Msr); - @endcode - @note MSR_P6_P5_MC_TYPE is defined as P5_MC_TYPE in SDM. -**/ -#define MSR_P6_P5_MC_TYPE 0x00000001 - - -/** - See Section 17.14, "Time-Stamp Counter.". - - @param ECX MSR_P6_TSC (0x00000010) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_TSC); - AsmWriteMsr64 (MSR_P6_TSC, Msr); - @endcode - @note MSR_P6_TSC is defined as TSC in SDM. -**/ -#define MSR_P6_TSC 0x00000010 - - -/** - Platform ID (R) The operating system can use this MSR to determine "slot" - information for the processor and the proper microcode update to load. - - @param ECX MSR_P6_IA32_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_IA32_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_IA32_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_P6_IA32_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_IA32_PLATFORM_ID); - @endcode - @note MSR_P6_IA32_PLATFORM_ID is defined as IA32_PLATFORM_ID in SDM. -**/ -#define MSR_P6_IA32_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_P6_IA32_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:18; - /// - /// [Bits 52:50] Platform Id (R) Contains information concerning the - /// intended platform for the processor. - /// - /// 52 51 50 - /// 0 0 0 Processor Flag 0. - /// 0 0 1 Processor Flag 1 - /// 0 1 0 Processor Flag 2 - /// 0 1 1 Processor Flag 3 - /// 1 0 0 Processor Flag 4 - /// 1 0 1 Processor Flag 5 - /// 1 1 0 Processor Flag 6 - /// 1 1 1 Processor Flag 7 - /// - UINT32 PlatformId:3; - /// - /// [Bits 56:53] L2 Cache Latency Read. - /// - UINT32 L2CacheLatencyRead:4; - UINT32 Reserved3:3; - /// - /// [Bit 60] Clock Frequency Ratio Read. - /// - UINT32 ClockFrequencyRatioRead:1; - UINT32 Reserved4:3; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_IA32_PLATFORM_ID_REGISTER; - - -/** - Section 10.4.4, "Local APIC Status and Location.". - - @param ECX MSR_P6_APIC_BASE (0x0000001B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_APIC_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_APIC_BASE_REGISTER. - - Example usage - @code - MSR_P6_APIC_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_APIC_BASE); - AsmWriteMsr64 (MSR_P6_APIC_BASE, Msr.Uint64); - @endcode - @note MSR_P6_APIC_BASE is defined as APIC_BASE in SDM. -**/ -#define MSR_P6_APIC_BASE 0x0000001B - -/** - MSR information returned for MSR index #MSR_P6_APIC_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bit 8] Boot Strap Processor indicator Bit 1 = BSP. - /// - UINT32 BSP:1; - UINT32 Reserved2:2; - /// - /// [Bit 11] APIC Global Enable Bit - Permanent till reset 1 = Enabled 0 = - /// Disabled. - /// - UINT32 EN:1; - /// - /// [Bits 31:12] APIC Base Address. - /// - UINT32 ApicBase:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_APIC_BASE_REGISTER; - - -/** - Processor Hard Power-On Configuration (R/W) Enables and disables processor - features; (R) indicates current processor configuration. - - @param ECX MSR_P6_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_P6_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_P6_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_P6_EBL_CR_POWERON is defined as EBL_CR_POWERON in SDM. -**/ -#define MSR_P6_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_P6_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Data Error Checking Enable (R/W) 1 = Enabled 0 = Disabled. - /// - UINT32 DataErrorCheckingEnable:1; - /// - /// [Bit 2] Response Error Checking Enable FRCERR Observation Enable (R/W) - /// 1 = Enabled 0 = Disabled. - /// - UINT32 ResponseErrorCheckingEnable:1; - /// - /// [Bit 3] AERR# Drive Enable (R/W) 1 = Enabled 0 = Disabled. - /// - UINT32 AERR_DriveEnable:1; - /// - /// [Bit 4] BERR# Enable for Initiator Bus Requests (R/W) 1 = Enabled 0 = - /// Disabled. - /// - UINT32 BERR_Enable:1; - UINT32 Reserved2:1; - /// - /// [Bit 6] BERR# Driver Enable for Initiator Internal Errors (R/W) 1 = - /// Enabled 0 = Disabled. - /// - UINT32 BERR_DriverEnable:1; - /// - /// [Bit 7] BINIT# Driver Enable (R/W) 1 = Enabled 0 = Disabled. - /// - UINT32 BINIT_DriverEnable:1; - /// - /// [Bit 8] Output Tri-state Enabled (R) 1 = Enabled 0 = Disabled. - /// - UINT32 OutputTriStateEnable:1; - /// - /// [Bit 9] Execute BIST (R) 1 = Enabled 0 = Disabled. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 10] AERR# Observation Enabled (R) 1 = Enabled 0 = Disabled. - /// - UINT32 AERR_ObservationEnabled:1; - UINT32 Reserved3:1; - /// - /// [Bit 12] BINIT# Observation Enabled (R) 1 = Enabled 0 = Disabled. - /// - UINT32 BINIT_ObservationEnabled:1; - /// - /// [Bit 13] In Order Queue Depth (R) 1 = 1 0 = 8. - /// - UINT32 InOrderQueueDepth:1; - /// - /// [Bit 14] 1-MByte Power on Reset Vector (R) 1 = 1MByte 0 = 4GBytes. - /// - UINT32 ResetVector:1; - /// - /// [Bit 15] FRC Mode Enable (R) 1 = Enabled 0 = Disabled. - /// - UINT32 FRCModeEnable:1; - /// - /// [Bits 17:16] APIC Cluster ID (R). - /// - UINT32 APICClusterID:2; - /// - /// [Bits 19:18] System Bus Frequency (R) 00 = 66MHz 10 = 100Mhz 01 = - /// 133MHz 11 = Reserved. - /// - UINT32 SystemBusFrequency:2; - /// - /// [Bits 21:20] Symmetric Arbitration ID (R). - /// - UINT32 SymmetricArbitrationID:2; - /// - /// [Bits 25:22] Clock Frequency Ratio (R). - /// - UINT32 ClockFrequencyRatio:4; - /// - /// [Bit 26] Low Power Mode Enable (R/W). - /// - UINT32 LowPowerModeEnable:1; - /// - /// [Bit 27] Clock Frequency Ratio. - /// - UINT32 ClockFrequencyRatio1:1; - UINT32 Reserved4:4; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_EBL_CR_POWERON_REGISTER; - - -/** - Test Control Register. - - @param ECX MSR_P6_TEST_CTL (0x00000033) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_TEST_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_TEST_CTL_REGISTER. - - Example usage - @code - MSR_P6_TEST_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_TEST_CTL); - AsmWriteMsr64 (MSR_P6_TEST_CTL, Msr.Uint64); - @endcode - @note MSR_P6_TEST_CTL is defined as TEST_CTL in SDM. -**/ -#define MSR_P6_TEST_CTL 0x00000033 - -/** - MSR information returned for MSR index #MSR_P6_TEST_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:30; - /// - /// [Bit 30] Streaming Buffer Disable. - /// - UINT32 StreamingBufferDisable:1; - /// - /// [Bit 31] Disable LOCK# Assertion for split locked access. - /// - UINT32 Disable_LOCK:1; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_TEST_CTL_REGISTER; - - -/** - BIOS Update Trigger Register. - - @param ECX MSR_P6_BIOS_UPDT_TRIG (0x00000079) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BIOS_UPDT_TRIG); - AsmWriteMsr64 (MSR_P6_BIOS_UPDT_TRIG, Msr); - @endcode - @note MSR_P6_BIOS_UPDT_TRIG is defined as BIOS_UPDT_TRIG in SDM. -**/ -#define MSR_P6_BIOS_UPDT_TRIG 0x00000079 - - -/** - Chunk n data register D[63:0]: used to write to and read from the L2. - - @param ECX MSR_P6_BBL_CR_Dn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BBL_CR_D0); - AsmWriteMsr64 (MSR_P6_BBL_CR_D0, Msr); - @endcode - @note MSR_P6_BBL_CR_D0 is defined as BBL_CR_D0 in SDM. - MSR_P6_BBL_CR_D1 is defined as BBL_CR_D1 in SDM. - MSR_P6_BBL_CR_D2 is defined as BBL_CR_D2 in SDM. - @{ -**/ -#define MSR_P6_BBL_CR_D0 0x00000088 -#define MSR_P6_BBL_CR_D1 0x00000089 -#define MSR_P6_BBL_CR_D2 0x0000008A -/// @} - - -/** - BIOS Update Signature Register or Chunk 3 data register D[63:0] Used to - write to and read from the L2 depending on the usage model. - - @param ECX MSR_P6_BIOS_SIGN (0x0000008B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BIOS_SIGN); - AsmWriteMsr64 (MSR_P6_BIOS_SIGN, Msr); - @endcode - @note MSR_P6_BIOS_SIGN is defined as BIOS_SIGN in SDM. -**/ -#define MSR_P6_BIOS_SIGN 0x0000008B - - -/** - - - @param ECX MSR_P6_PERFCTR0 (0x000000C1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_PERFCTR0); - AsmWriteMsr64 (MSR_P6_PERFCTR0, Msr); - @endcode - @note MSR_P6_PERFCTR0 is defined as PERFCTR0 in SDM. - MSR_P6_PERFCTR1 is defined as PERFCTR1 in SDM. - @{ -**/ -#define MSR_P6_PERFCTR0 0x000000C1 -#define MSR_P6_PERFCTR1 0x000000C2 -/// @} - - -/** - - - @param ECX MSR_P6_MTRRCAP (0x000000FE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRCAP); - AsmWriteMsr64 (MSR_P6_MTRRCAP, Msr); - @endcode - @note MSR_P6_MTRRCAP is defined as MTRRCAP in SDM. -**/ -#define MSR_P6_MTRRCAP 0x000000FE - - -/** - Address register: used to send specified address (A31-A3) to L2 during cache - initialization accesses. - - @param ECX MSR_P6_BBL_CR_ADDR (0x00000116) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_ADDR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_ADDR_REGISTER. - - Example usage - @code - MSR_P6_BBL_CR_ADDR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_BBL_CR_ADDR); - AsmWriteMsr64 (MSR_P6_BBL_CR_ADDR, Msr.Uint64); - @endcode - @note MSR_P6_BBL_CR_ADDR is defined as BBL_CR_ADDR in SDM. -**/ -#define MSR_P6_BBL_CR_ADDR 0x00000116 - -/** - MSR information returned for MSR index #MSR_P6_BBL_CR_ADDR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:3; - /// - /// [Bits 31:3] Address bits - /// - UINT32 Address:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_BBL_CR_ADDR_REGISTER; - - -/** - Data ECC register D[7:0]: used to write ECC and read ECC to/from L2. - - @param ECX MSR_P6_BBL_CR_DECC (0x00000118) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BBL_CR_DECC); - AsmWriteMsr64 (MSR_P6_BBL_CR_DECC, Msr); - @endcode - @note MSR_P6_BBL_CR_DECC is defined as BBL_CR_DECC in SDM. -**/ -#define MSR_P6_BBL_CR_DECC 0x00000118 - - -/** - Control register: used to program L2 commands to be issued via cache - configuration accesses mechanism. Also receives L2 lookup response. - - @param ECX MSR_P6_BBL_CR_CTL (0x00000119) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_CTL_REGISTER. - - Example usage - @code - MSR_P6_BBL_CR_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_BBL_CR_CTL); - AsmWriteMsr64 (MSR_P6_BBL_CR_CTL, Msr.Uint64); - @endcode - @note MSR_P6_BBL_CR_CTL is defined as BBL_CR_CTL in SDM. -**/ -#define MSR_P6_BBL_CR_CTL 0x00000119 - -/** - MSR information returned for MSR index #MSR_P6_BBL_CR_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 4:0] L2 Command - /// Data Read w/ LRU update (RLU) - /// Tag Read w/ Data Read (TRR) - /// Tag Inquire (TI) - /// L2 Control Register Read (CR) - /// L2 Control Register Write (CW) - /// Tag Write w/ Data Read (TWR) - /// Tag Write w/ Data Write (TWW) - /// Tag Write (TW). - /// - UINT32 L2Command:5; - /// - /// [Bits 6:5] State to L2 - /// - UINT32 StateToL2:2; - UINT32 Reserved:1; - /// - /// [Bits 9:8] Way to L2. - /// - UINT32 WayToL2:2; - /// - /// [Bits 11:10] Way 0 - 00, Way 1 - 01, Way 2 - 10, Way 3 - 11. - /// - UINT32 Way:2; - /// - /// [Bits 13:12] Modified - 11,Exclusive - 10, Shared - 01, Invalid - 00. - /// - UINT32 MESI:2; - /// - /// [Bits 15:14] State from L2. - /// - UINT32 StateFromL2:2; - UINT32 Reserved2:1; - /// - /// [Bit 17] L2 Hit. - /// - UINT32 L2Hit:1; - UINT32 Reserved3:1; - /// - /// [Bits 20:19] User supplied ECC. - /// - UINT32 UserEcc:2; - /// - /// [Bit 21] Processor number Disable = 1 Enable = 0 Reserved. - /// - UINT32 ProcessorNumber:1; - UINT32 Reserved4:10; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_BBL_CR_CTL_REGISTER; - - -/** - Trigger register: used to initiate a cache configuration accesses access, - Write only with Data = 0. - - @param ECX MSR_P6_BBL_CR_TRIG (0x0000011A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BBL_CR_TRIG); - AsmWriteMsr64 (MSR_P6_BBL_CR_TRIG, Msr); - @endcode - @note MSR_P6_BBL_CR_TRIG is defined as BBL_CR_TRIG in SDM. -**/ -#define MSR_P6_BBL_CR_TRIG 0x0000011A - - -/** - Busy register: indicates when a cache configuration accesses L2 command is - in progress. D[0] = 1 = BUSY. - - @param ECX MSR_P6_BBL_CR_BUSY (0x0000011B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_BBL_CR_BUSY); - AsmWriteMsr64 (MSR_P6_BBL_CR_BUSY, Msr); - @endcode - @note MSR_P6_BBL_CR_BUSY is defined as BBL_CR_BUSY in SDM. -**/ -#define MSR_P6_BBL_CR_BUSY 0x0000011B - - -/** - Control register 3: used to configure the L2 Cache. - - @param ECX MSR_P6_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_P6_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_P6_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_P6_BBL_CR_CTL3 is defined as BBL_CR_CTL3 in SDM. -**/ -#define MSR_P6_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_P6_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Configured (read/write ). - /// - UINT32 L2Configured:1; - /// - /// [Bits 4:1] L2 Cache Latency (read/write). - /// - UINT32 L2CacheLatency:4; - /// - /// [Bit 5] ECC Check Enable (read/write). - /// - UINT32 ECCCheckEnable:1; - /// - /// [Bit 6] Address Parity Check Enable (read/write). - /// - UINT32 AddressParityCheckEnable:1; - /// - /// [Bit 7] CRTN Parity Check Enable (read/write). - /// - UINT32 CRTNParityCheckEnable:1; - /// - /// [Bit 8] L2 Enabled (read/write). - /// - UINT32 L2Enabled:1; - /// - /// [Bits 10:9] L2 Associativity (read only) Direct Mapped 2 Way 4 Way - /// Reserved. - /// - UINT32 L2Associativity:2; - /// - /// [Bits 12:11] Number of L2 banks (read only). - /// - UINT32 L2Banks:2; - /// - /// [Bits 17:13] Cache size per bank (read/write) 256KBytes 512KBytes - /// 1MByte 2MByte 4MBytes. - /// - UINT32 CacheSizePerBank:5; - /// - /// [Bit 18] Cache State error checking enable (read/write). - /// - UINT32 CacheStateErrorEnable:1; - UINT32 Reserved1:1; - /// - /// [Bits 22:20] L2 Physical Address Range support 64GBytes 32GBytes - /// 16GBytes 8GBytes 4GBytes 2GBytes 1GBytes 512MBytes. - /// - UINT32 L2AddressRange:3; - /// - /// [Bit 23] L2 Hardware Disable (read only). - /// - UINT32 L2HardwareDisable:1; - UINT32 Reserved2:1; - /// - /// [Bit 25] Cache bus fraction (read only). - /// - UINT32 CacheBusFraction:1; - UINT32 Reserved3:6; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_BBL_CR_CTL3_REGISTER; - - -/** - CS register target for CPL 0 code. - - @param ECX MSR_P6_SYSENTER_CS_MSR (0x00000174) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_SYSENTER_CS_MSR); - AsmWriteMsr64 (MSR_P6_SYSENTER_CS_MSR, Msr); - @endcode - @note MSR_P6_SYSENTER_CS_MSR is defined as SYSENTER_CS_MSR in SDM. -**/ -#define MSR_P6_SYSENTER_CS_MSR 0x00000174 - - -/** - Stack pointer for CPL 0 stack. - - @param ECX MSR_P6_SYSENTER_ESP_MSR (0x00000175) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_SYSENTER_ESP_MSR); - AsmWriteMsr64 (MSR_P6_SYSENTER_ESP_MSR, Msr); - @endcode - @note MSR_P6_SYSENTER_ESP_MSR is defined as SYSENTER_ESP_MSR in SDM. -**/ -#define MSR_P6_SYSENTER_ESP_MSR 0x00000175 - - -/** - CPL 0 code entry point. - - @param ECX MSR_P6_SYSENTER_EIP_MSR (0x00000176) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_SYSENTER_EIP_MSR); - AsmWriteMsr64 (MSR_P6_SYSENTER_EIP_MSR, Msr); - @endcode - @note MSR_P6_SYSENTER_EIP_MSR is defined as SYSENTER_EIP_MSR in SDM. -**/ -#define MSR_P6_SYSENTER_EIP_MSR 0x00000176 - - -/** - - - @param ECX MSR_P6_MCG_CAP (0x00000179) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MCG_CAP); - AsmWriteMsr64 (MSR_P6_MCG_CAP, Msr); - @endcode - @note MSR_P6_MCG_CAP is defined as MCG_CAP in SDM. -**/ -#define MSR_P6_MCG_CAP 0x00000179 - - -/** - - - @param ECX MSR_P6_MCG_STATUS (0x0000017A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MCG_STATUS); - AsmWriteMsr64 (MSR_P6_MCG_STATUS, Msr); - @endcode - @note MSR_P6_MCG_STATUS is defined as MCG_STATUS in SDM. -**/ -#define MSR_P6_MCG_STATUS 0x0000017A - - -/** - - - @param ECX MSR_P6_MCG_CTL (0x0000017B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MCG_CTL); - AsmWriteMsr64 (MSR_P6_MCG_CTL, Msr); - @endcode - @note MSR_P6_MCG_CTL is defined as MCG_CTL in SDM. -**/ -#define MSR_P6_MCG_CTL 0x0000017B - - -/** - - - @param ECX MSR_P6_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_PERFEVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_PERFEVTSEL_REGISTER. - - Example usage - @code - MSR_P6_PERFEVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_PERFEVTSEL0); - AsmWriteMsr64 (MSR_P6_PERFEVTSEL0, Msr.Uint64); - @endcode - @note MSR_P6_PERFEVTSEL0 is defined as PERFEVTSEL0 in SDM. - MSR_P6_PERFEVTSEL1 is defined as PERFEVTSEL1 in SDM. - @{ -**/ -#define MSR_P6_PERFEVTSEL0 0x00000186 -#define MSR_P6_PERFEVTSEL1 0x00000187 -/// @} - -/** - MSR information returned for MSR indexes #MSR_P6_PERFEVTSEL0 and - #MSR_P6_PERFEVTSEL1. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Event Select Refer to Performance Counter section for a - /// list of event encodings. - /// - UINT32 EventSelect:8; - /// - /// [Bits 15:8] UMASK (Unit Mask) Unit mask register set to 0 to enable - /// all count options. - /// - UINT32 UMASK:8; - /// - /// [Bit 16] USER Controls the counting of events at Privilege levels of - /// 1, 2, and 3. - /// - UINT32 USR:1; - /// - /// [Bit 17] OS Controls the counting of events at Privilege level of 0. - /// - UINT32 OS:1; - /// - /// [Bit 18] E Occurrence/Duration Mode Select 1 = Occurrence 0 = Duration. - /// - UINT32 E:1; - /// - /// [Bit 19] PC Enabled the signaling of performance counter overflow via - /// BP0 pin. - /// - UINT32 PC:1; - /// - /// [Bit 20] INT Enables the signaling of counter overflow via input to - /// APIC 1 = Enable 0 = Disable. - /// - UINT32 INT:1; - UINT32 Reserved1:1; - /// - /// [Bit 22] ENABLE Enables the counting of performance events in both - /// counters 1 = Enable 0 = Disable. - /// - UINT32 EN:1; - /// - /// [Bit 23] INV Inverts the result of the CMASK condition 1 = Inverted 0 - /// = Non-Inverted. - /// - UINT32 INV:1; - /// - /// [Bits 31:24] CMASK (Counter Mask). - /// - UINT32 CMASK:8; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_PERFEVTSEL_REGISTER; - - -/** - - - @param ECX MSR_P6_DEBUGCTLMSR (0x000001D9) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_DEBUGCTLMSR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_DEBUGCTLMSR_REGISTER. - - Example usage - @code - MSR_P6_DEBUGCTLMSR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_DEBUGCTLMSR); - AsmWriteMsr64 (MSR_P6_DEBUGCTLMSR, Msr.Uint64); - @endcode - @note MSR_P6_DEBUGCTLMSR is defined as DEBUGCTLMSR in SDM. -**/ -#define MSR_P6_DEBUGCTLMSR 0x000001D9 - -/** - MSR information returned for MSR index #MSR_P6_DEBUGCTLMSR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable/Disable Last Branch Records. - /// - UINT32 LBR:1; - /// - /// [Bit 1] Branch Trap Flag. - /// - UINT32 BTF:1; - /// - /// [Bit 2] Performance Monitoring/Break Point Pins. - /// - UINT32 PB0:1; - /// - /// [Bit 3] Performance Monitoring/Break Point Pins. - /// - UINT32 PB1:1; - /// - /// [Bit 4] Performance Monitoring/Break Point Pins. - /// - UINT32 PB2:1; - /// - /// [Bit 5] Performance Monitoring/Break Point Pins. - /// - UINT32 PB3:1; - /// - /// [Bit 6] Enable/Disable Execution Trace Messages. - /// - UINT32 TR:1; - UINT32 Reserved1:25; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_DEBUGCTLMSR_REGISTER; - - -/** - - - @param ECX MSR_P6_LASTBRANCHFROMIP (0x000001DB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_LASTBRANCHFROMIP); - AsmWriteMsr64 (MSR_P6_LASTBRANCHFROMIP, Msr); - @endcode - @note MSR_P6_LASTBRANCHFROMIP is defined as LASTBRANCHFROMIP in SDM. -**/ -#define MSR_P6_LASTBRANCHFROMIP 0x000001DB - - -/** - - - @param ECX MSR_P6_LASTBRANCHTOIP (0x000001DC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_LASTBRANCHTOIP); - AsmWriteMsr64 (MSR_P6_LASTBRANCHTOIP, Msr); - @endcode - @note MSR_P6_LASTBRANCHTOIP is defined as LASTBRANCHTOIP in SDM. -**/ -#define MSR_P6_LASTBRANCHTOIP 0x000001DC - - -/** - - - @param ECX MSR_P6_LASTINTFROMIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_LASTINTFROMIP); - AsmWriteMsr64 (MSR_P6_LASTINTFROMIP, Msr); - @endcode - @note MSR_P6_LASTINTFROMIP is defined as LASTINTFROMIP in SDM. -**/ -#define MSR_P6_LASTINTFROMIP 0x000001DD - - -/** - - - @param ECX MSR_P6_LASTINTTOIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_LASTINTTOIP); - AsmWriteMsr64 (MSR_P6_LASTINTTOIP, Msr); - @endcode - @note MSR_P6_LASTINTTOIP is defined as LASTINTTOIP in SDM. -**/ -#define MSR_P6_LASTINTTOIP 0x000001DE - - -/** - - - @param ECX MSR_P6_ROB_CR_BKUPTMPDR6 (0x000001E0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_ROB_CR_BKUPTMPDR6_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_ROB_CR_BKUPTMPDR6_REGISTER. - - Example usage - @code - MSR_P6_ROB_CR_BKUPTMPDR6_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_ROB_CR_BKUPTMPDR6); - AsmWriteMsr64 (MSR_P6_ROB_CR_BKUPTMPDR6, Msr.Uint64); - @endcode - @note MSR_P6_ROB_CR_BKUPTMPDR6 is defined as ROB_CR_BKUPTMPDR6 in SDM. -**/ -#define MSR_P6_ROB_CR_BKUPTMPDR6 0x000001E0 - -/** - MSR information returned for MSR index #MSR_P6_ROB_CR_BKUPTMPDR6 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:2; - /// - /// [Bit 2] Fast Strings Enable bit. Default is enabled. - /// - UINT32 FastStrings:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_ROB_CR_BKUPTMPDR6_REGISTER; - - -/** - - - @param ECX MSR_P6_MTRRPHYSBASEn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRPHYSBASE0); - AsmWriteMsr64 (MSR_P6_MTRRPHYSBASE0, Msr); - @endcode - @note MSR_P6_MTRRPHYSBASE0 is defined as MTRRPHYSBASE0 in SDM. - MSR_P6_MTRRPHYSBASE1 is defined as MTRRPHYSBASE1 in SDM. - MSR_P6_MTRRPHYSBASE2 is defined as MTRRPHYSBASE2 in SDM. - MSR_P6_MTRRPHYSBASE3 is defined as MTRRPHYSBASE3 in SDM. - MSR_P6_MTRRPHYSBASE4 is defined as MTRRPHYSBASE4 in SDM. - MSR_P6_MTRRPHYSBASE5 is defined as MTRRPHYSBASE5 in SDM. - MSR_P6_MTRRPHYSBASE6 is defined as MTRRPHYSBASE6 in SDM. - MSR_P6_MTRRPHYSBASE7 is defined as MTRRPHYSBASE7 in SDM. - @{ -**/ -#define MSR_P6_MTRRPHYSBASE0 0x00000200 -#define MSR_P6_MTRRPHYSBASE1 0x00000202 -#define MSR_P6_MTRRPHYSBASE2 0x00000204 -#define MSR_P6_MTRRPHYSBASE3 0x00000206 -#define MSR_P6_MTRRPHYSBASE4 0x00000208 -#define MSR_P6_MTRRPHYSBASE5 0x0000020A -#define MSR_P6_MTRRPHYSBASE6 0x0000020C -#define MSR_P6_MTRRPHYSBASE7 0x0000020E -/// @} - - -/** - - - @param ECX MSR_P6_MTRRPHYSMASKn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRPHYSMASK0); - AsmWriteMsr64 (MSR_P6_MTRRPHYSMASK0, Msr); - @endcode - @note MSR_P6_MTRRPHYSMASK0 is defined as MTRRPHYSMASK0 in SDM. - MSR_P6_MTRRPHYSMASK1 is defined as MTRRPHYSMASK1 in SDM. - MSR_P6_MTRRPHYSMASK2 is defined as MTRRPHYSMASK2 in SDM. - MSR_P6_MTRRPHYSMASK3 is defined as MTRRPHYSMASK3 in SDM. - MSR_P6_MTRRPHYSMASK4 is defined as MTRRPHYSMASK4 in SDM. - MSR_P6_MTRRPHYSMASK5 is defined as MTRRPHYSMASK5 in SDM. - MSR_P6_MTRRPHYSMASK6 is defined as MTRRPHYSMASK6 in SDM. - MSR_P6_MTRRPHYSMASK7 is defined as MTRRPHYSMASK7 in SDM. - @{ -**/ -#define MSR_P6_MTRRPHYSMASK0 0x00000201 -#define MSR_P6_MTRRPHYSMASK1 0x00000203 -#define MSR_P6_MTRRPHYSMASK2 0x00000205 -#define MSR_P6_MTRRPHYSMASK3 0x00000207 -#define MSR_P6_MTRRPHYSMASK4 0x00000209 -#define MSR_P6_MTRRPHYSMASK5 0x0000020B -#define MSR_P6_MTRRPHYSMASK6 0x0000020D -#define MSR_P6_MTRRPHYSMASK7 0x0000020F -/// @} - - -/** - - - @param ECX MSR_P6_MTRRFIX64K_00000 (0x00000250) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX64K_00000); - AsmWriteMsr64 (MSR_P6_MTRRFIX64K_00000, Msr); - @endcode - @note MSR_P6_MTRRFIX64K_00000 is defined as MTRRFIX64K_00000 in SDM. -**/ -#define MSR_P6_MTRRFIX64K_00000 0x00000250 - - -/** - - - @param ECX MSR_P6_MTRRFIX16K_80000 (0x00000258) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX16K_80000); - AsmWriteMsr64 (MSR_P6_MTRRFIX16K_80000, Msr); - @endcode - @note MSR_P6_MTRRFIX16K_80000 is defined as MTRRFIX16K_80000 in SDM. -**/ -#define MSR_P6_MTRRFIX16K_80000 0x00000258 - - -/** - - - @param ECX MSR_P6_MTRRFIX16K_A0000 (0x00000259) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX16K_A0000); - AsmWriteMsr64 (MSR_P6_MTRRFIX16K_A0000, Msr); - @endcode - @note MSR_P6_MTRRFIX16K_A0000 is defined as MTRRFIX16K_A0000 in SDM. -**/ -#define MSR_P6_MTRRFIX16K_A0000 0x00000259 - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_C0000 (0x00000268) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_C0000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_C0000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_C0000 is defined as MTRRFIX4K_C0000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_C0000 0x00000268 - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_C8000 (0x00000269) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_C8000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_C8000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_C8000 is defined as MTRRFIX4K_C8000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_C8000 0x00000269 - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_D0000 (0x0000026A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_D0000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_D0000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_D0000 is defined as MTRRFIX4K_D0000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_D0000 0x0000026A - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_D8000 (0x0000026B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_D8000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_D8000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_D8000 is defined as MTRRFIX4K_D8000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_D8000 0x0000026B - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_E0000 (0x0000026C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_E0000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_E0000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_E0000 is defined as MTRRFIX4K_E0000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_E0000 0x0000026C - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_E8000 (0x0000026D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_E8000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_E8000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_E8000 is defined as MTRRFIX4K_E8000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_E8000 0x0000026D - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_F0000 (0x0000026E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_F0000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_F0000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_F0000 is defined as MTRRFIX4K_F0000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_F0000 0x0000026E - - -/** - - - @param ECX MSR_P6_MTRRFIX4K_F8000 (0x0000026F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_F8000); - AsmWriteMsr64 (MSR_P6_MTRRFIX4K_F8000, Msr); - @endcode - @note MSR_P6_MTRRFIX4K_F8000 is defined as MTRRFIX4K_F8000 in SDM. -**/ -#define MSR_P6_MTRRFIX4K_F8000 0x0000026F - - -/** - - - @param ECX MSR_P6_MTRRDEFTYPE (0x000002FF) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_MTRRDEFTYPE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_MTRRDEFTYPE_REGISTER. - - Example usage - @code - MSR_P6_MTRRDEFTYPE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_MTRRDEFTYPE); - AsmWriteMsr64 (MSR_P6_MTRRDEFTYPE, Msr.Uint64); - @endcode - @note MSR_P6_MTRRDEFTYPE is defined as MTRRDEFTYPE in SDM. -**/ -#define MSR_P6_MTRRDEFTYPE 0x000002FF - -/** - MSR information returned for MSR index #MSR_P6_MTRRDEFTYPE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Default memory type. - /// - UINT32 Type:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] Fixed MTRR enable. - /// - UINT32 FE:1; - /// - /// [Bit 11] MTRR Enable. - /// - UINT32 E:1; - UINT32 Reserved2:20; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_MTRRDEFTYPE_REGISTER; - - -/** - - - @param ECX MSR_P6_MC0_CTL (0x00000400) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MC0_CTL); - AsmWriteMsr64 (MSR_P6_MC0_CTL, Msr); - @endcode - @note MSR_P6_MC0_CTL is defined as MC0_CTL in SDM. - MSR_P6_MC1_CTL is defined as MC1_CTL in SDM. - MSR_P6_MC2_CTL is defined as MC2_CTL in SDM. - MSR_P6_MC3_CTL is defined as MC3_CTL in SDM. - MSR_P6_MC4_CTL is defined as MC4_CTL in SDM. - @{ -**/ -#define MSR_P6_MC0_CTL 0x00000400 -#define MSR_P6_MC1_CTL 0x00000404 -#define MSR_P6_MC2_CTL 0x00000408 -#define MSR_P6_MC3_CTL 0x00000410 -#define MSR_P6_MC4_CTL 0x0000040C -/// @} - - -/** - - Bit definitions for MSR_P6_MC4_STATUS are the same as MSR_P6_MC0_STATUS, - except bits 0, 4, 57, and 61 are hardcoded to 1. - - @param ECX MSR_P6_MCn_STATUS - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_P6_MC_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_P6_MC_STATUS_REGISTER. - - Example usage - @code - MSR_P6_MC_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_P6_MC0_STATUS); - AsmWriteMsr64 (MSR_P6_MC0_STATUS, Msr.Uint64); - @endcode - @note MSR_P6_MC0_STATUS is defined as MC0_STATUS in SDM. - MSR_P6_MC1_STATUS is defined as MC1_STATUS in SDM. - MSR_P6_MC2_STATUS is defined as MC2_STATUS in SDM. - MSR_P6_MC3_STATUS is defined as MC3_STATUS in SDM. - MSR_P6_MC4_STATUS is defined as MC4_STATUS in SDM. - @{ -**/ -#define MSR_P6_MC0_STATUS 0x00000401 -#define MSR_P6_MC1_STATUS 0x00000405 -#define MSR_P6_MC2_STATUS 0x00000409 -#define MSR_P6_MC3_STATUS 0x00000411 -#define MSR_P6_MC4_STATUS 0x0000040D -/// @} - -/** - MSR information returned for MSR index #MSR_P6_MC0_STATUS to - #MSR_P6_MC4_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] MC_STATUS_MCACOD. - /// - UINT32 MC_STATUS_MCACOD:16; - /// - /// [Bits 31:16] MC_STATUS_MSCOD. - /// - UINT32 MC_STATUS_MSCOD:16; - UINT32 Reserved:25; - /// - /// [Bit 57] MC_STATUS_DAM. - /// - UINT32 MC_STATUS_DAM:1; - /// - /// [Bit 58] MC_STATUS_ADDRV. - /// - UINT32 MC_STATUS_ADDRV:1; - /// - /// [Bit 59] MC_STATUS_MISCV. - /// - UINT32 MC_STATUS_MISCV:1; - /// - /// [Bit 60] MC_STATUS_EN. (Note: For MC0_STATUS only, this bit is - /// hardcoded to 1.). - /// - UINT32 MC_STATUS_EN:1; - /// - /// [Bit 61] MC_STATUS_UC. - /// - UINT32 MC_STATUS_UC:1; - /// - /// [Bit 62] MC_STATUS_O. - /// - UINT32 MC_STATUS_O:1; - /// - /// [Bit 63] MC_STATUS_V. - /// - UINT32 MC_STATUS_V:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_P6_MC_STATUS_REGISTER; - - -/** - - MSR_P6_MC4_ADDR is defined in MCA architecture but not implemented in P6 Family processors. - - @param ECX MSR_P6_MC0_ADDR (0x00000402) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MC0_ADDR); - AsmWriteMsr64 (MSR_P6_MC0_ADDR, Msr); - @endcode - @note MSR_P6_MC0_ADDR is defined as MC0_ADDR in SDM. - MSR_P6_MC1_ADDR is defined as MC1_ADDR in SDM. - MSR_P6_MC2_ADDR is defined as MC2_ADDR in SDM. - MSR_P6_MC3_ADDR is defined as MC3_ADDR in SDM. - MSR_P6_MC4_ADDR is defined as MC4_ADDR in SDM. - @{ -**/ -#define MSR_P6_MC0_ADDR 0x00000402 -#define MSR_P6_MC1_ADDR 0x00000406 -#define MSR_P6_MC2_ADDR 0x0000040A -#define MSR_P6_MC3_ADDR 0x00000412 -#define MSR_P6_MC4_ADDR 0x0000040E -/// @} - - -/** - Defined in MCA architecture but not implemented in the P6 family processors. - - @param ECX MSR_P6_MC0_MISC (0x00000403) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_P6_MC0_MISC); - AsmWriteMsr64 (MSR_P6_MC0_MISC, Msr); - @endcode - @note MSR_P6_MC0_MISC is defined as MC0_MISC in SDM. - MSR_P6_MC1_MISC is defined as MC1_MISC in SDM. - MSR_P6_MC2_MISC is defined as MC2_MISC in SDM. - MSR_P6_MC3_MISC is defined as MC3_MISC in SDM. - MSR_P6_MC4_MISC is defined as MC4_MISC in SDM. - @{ -**/ -#define MSR_P6_MC0_MISC 0x00000403 -#define MSR_P6_MC1_MISC 0x00000407 -#define MSR_P6_MC2_MISC 0x0000040B -#define MSR_P6_MC3_MISC 0x00000413 -#define MSR_P6_MC4_MISC 0x0000040F -/// @} - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h deleted file mode 100644 index 8922d56e2..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h +++ /dev/null @@ -1,2730 +0,0 @@ -/** @file - MSR Definitions for Pentium(R) 4 Processors. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.18. - -**/ - -#ifndef __PENTIUM_4_MSR_H__ -#define __PENTIUM_4_MSR_H__ - -#include - -/** - Is Pentium(R) 4 Processors? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_PENTIUM_4_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x0F \ - ) - -/** - 3, 4, 6. Shared. See Section 8.10.5, "Monitor/Mwait Address Range - Determination.". - - @param ECX MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE (0x00000006) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE); - AsmWriteMsr64 (MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE, Msr); - @endcode - @note MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE is defined as IA32_MONITOR_FILTER_LINE_SIZE in SDM. -**/ -#define MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE 0x00000006 - - -/** - 0, 1, 2, 3, 4, 6. Shared. Processor Hard Power-On Configuration (R/W) - Enables and disables processor features; (R) indicates current processor - configuration. - - @param ECX MSR_PENTIUM_4_EBC_HARD_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_HARD_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_HARD_POWERON_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_EBC_HARD_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_HARD_POWERON); - AsmWriteMsr64 (MSR_PENTIUM_4_EBC_HARD_POWERON, Msr.Uint64); - @endcode - @note MSR_PENTIUM_4_EBC_HARD_POWERON is defined as MSR_EBC_HARD_POWERON in SDM. -**/ -#define MSR_PENTIUM_4_EBC_HARD_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_EBC_HARD_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Output Tri-state Enabled (R) Indicates whether tri-state - /// output is enabled (1) or disabled (0) as set by the strapping of SMI#. - /// The value in this bit is written on the deassertion of RESET#; the bit - /// is set to 1 when the address bus signal is asserted. - /// - UINT32 OutputTriStateEnabled:1; - /// - /// [Bit 1] Execute BIST (R) Indicates whether the execution of the BIST - /// is enabled (1) or disabled (0) as set by the strapping of INIT#. The - /// value in this bit is written on the deassertion of RESET#; the bit is - /// set to 1 when the address bus signal is asserted. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 2] In Order Queue Depth (R) Indicates whether the in order queue - /// depth for the system bus is 1 (1) or up to 12 (0) as set by the - /// strapping of A7#. The value in this bit is written on the deassertion - /// of RESET#; the bit is set to 1 when the address bus signal is asserted. - /// - UINT32 InOrderQueueDepth:1; - /// - /// [Bit 3] MCERR# Observation Disabled (R) Indicates whether MCERR# - /// observation is enabled (0) or disabled (1) as determined by the - /// strapping of A9#. The value in this bit is written on the deassertion - /// of RESET#; the bit is set to 1 when the address bus signal is asserted. - /// - UINT32 MCERR_ObservationDisabled:1; - /// - /// [Bit 4] BINIT# Observation Enabled (R) Indicates whether BINIT# - /// observation is enabled (0) or disabled (1) as determined by the - /// strapping of A10#. The value in this bit is written on the deassertion - /// of RESET#; the bit is set to 1 when the address bus signal is asserted. - /// - UINT32 BINIT_ObservationEnabled:1; - /// - /// [Bits 6:5] APIC Cluster ID (R) Contains the logical APIC cluster ID - /// value as set by the strapping of A12# and A11#. The logical cluster ID - /// value is written into the field on the deassertion of RESET#; the - /// field is set to 1 when the address bus signal is asserted. - /// - UINT32 APICClusterID:2; - /// - /// [Bit 7] Bus Park Disable (R) Indicates whether bus park is enabled - /// (0) or disabled (1) as set by the strapping of A15#. The value in this - /// bit is written on the deassertion of RESET#; the bit is set to 1 when - /// the address bus signal is asserted. - /// - UINT32 BusParkDisable:1; - UINT32 Reserved1:4; - /// - /// [Bits 13:12] Agent ID (R) Contains the logical agent ID value as set - /// by the strapping of BR[3:0]. The logical ID value is written into the - /// field on the deassertion of RESET#; the field is set to 1 when the - /// address bus signal is asserted. - /// - UINT32 AgentID:2; - UINT32 Reserved2:18; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_EBC_HARD_POWERON_REGISTER; - - -/** - 0, 1, 2, 3, 4, 6. Shared. Processor Soft Power-On Configuration (R/W) - Enables and disables processor features. - - @param ECX MSR_PENTIUM_4_EBC_SOFT_POWERON (0x0000002B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_SOFT_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_SOFT_POWERON_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_EBC_SOFT_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_SOFT_POWERON); - AsmWriteMsr64 (MSR_PENTIUM_4_EBC_SOFT_POWERON, Msr.Uint64); - @endcode - @note MSR_PENTIUM_4_EBC_SOFT_POWERON is defined as MSR_EBC_SOFT_POWERON in SDM. -**/ -#define MSR_PENTIUM_4_EBC_SOFT_POWERON 0x0000002B - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_EBC_SOFT_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] RCNT/SCNT On Request Encoding Enable (R/W) Controls the - /// driving of RCNT/SCNT on the request encoding. Set to enable (1); clear - /// to disabled (0, default). - /// - UINT32 RCNT_SCNT:1; - /// - /// [Bit 1] Data Error Checking Disable (R/W) Set to disable system data - /// bus parity checking; clear to enable parity checking. - /// - UINT32 DataErrorCheckingDisable:1; - /// - /// [Bit 2] Response Error Checking Disable (R/W) Set to disable - /// (default); clear to enable. - /// - UINT32 ResponseErrorCheckingDisable:1; - /// - /// [Bit 3] Address/Request Error Checking Disable (R/W) Set to disable - /// (default); clear to enable. - /// - UINT32 AddressRequestErrorCheckingDisable:1; - /// - /// [Bit 4] Initiator MCERR# Disable (R/W) Set to disable MCERR# driving - /// for initiator bus requests (default); clear to enable. - /// - UINT32 InitiatorMCERR_Disable:1; - /// - /// [Bit 5] Internal MCERR# Disable (R/W) Set to disable MCERR# driving - /// for initiator internal errors (default); clear to enable. - /// - UINT32 InternalMCERR_Disable:1; - /// - /// [Bit 6] BINIT# Driver Disable (R/W) Set to disable BINIT# driver - /// (default); clear to enable driver. - /// - UINT32 BINIT_DriverDisable:1; - UINT32 Reserved1:25; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_EBC_SOFT_POWERON_REGISTER; - - -/** - 2,3, 4, 6. Shared. Processor Frequency Configuration The bit field layout of - this MSR varies according to the MODEL value in the CPUID version - information. The following bit field layout applies to Pentium 4 and Xeon - Processors with MODEL encoding equal or greater than 2. (R) The field - Indicates the current processor frequency configuration. - - @param ECX MSR_PENTIUM_4_EBC_FREQUENCY_ID (0x0000002C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_FREQUENCY_ID); - @endcode - @note MSR_PENTIUM_4_EBC_FREQUENCY_ID is defined as MSR_EBC_FREQUENCY_ID in SDM. -**/ -#define MSR_PENTIUM_4_EBC_FREQUENCY_ID 0x0000002C - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_EBC_FREQUENCY_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 18:16] Scalable Bus Speed (R/W) Indicates the intended scalable - /// bus speed: *EncodingScalable Bus Speed* - /// - /// 000B 100 MHz (Model 2). - /// 000B 266 MHz (Model 3 or 4) - /// 001B 133 MHz - /// 010B 200 MHz - /// 011B 166 MHz - /// 100B 333 MHz (Model 6) - /// - /// 133.33 MHz should be utilized if performing calculation with System - /// Bus Speed when encoding is 001B. 166.67 MHz should be utilized if - /// performing calculation with System Bus Speed when encoding is 011B. - /// 266.67 MHz should be utilized if performing calculation with System - /// Bus Speed when encoding is 000B and model encoding = 3 or 4. 333.33 - /// MHz should be utilized if performing calculation with System Bus - /// Speed when encoding is 100B and model encoding = 6. All other values - /// are reserved. - /// - UINT32 ScalableBusSpeed:3; - UINT32 Reserved2:5; - /// - /// [Bits 31:24] Core Clock Frequency to System Bus Frequency Ratio (R) - /// The processor core clock frequency to system bus frequency ratio - /// observed at the de-assertion of the reset pin. - /// - UINT32 ClockRatio:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER; - - -/** - 0, 1. Shared. Processor Frequency Configuration (R) The bit field layout of - this MSR varies according to the MODEL value of the CPUID version - information. This bit field layout applies to Pentium 4 and Xeon Processors - with MODEL encoding less than 2. Indicates current processor frequency - configuration. - - @param ECX MSR_PENTIUM_4_EBC_FREQUENCY_ID_1 (0x0000002C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_FREQUENCY_ID_1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_EBC_FREQUENCY_ID_1_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_EBC_FREQUENCY_ID_1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_FREQUENCY_ID_1); - @endcode - @note MSR_PENTIUM_4_EBC_FREQUENCY_ID_1 is defined as MSR_EBC_FREQUENCY_ID_1 in SDM. -**/ -#define MSR_PENTIUM_4_EBC_FREQUENCY_ID_1 0x0000002C - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_EBC_FREQUENCY_ID_1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:21; - /// - /// [Bits 23:21] Scalable Bus Speed (R/W) Indicates the intended scalable - /// bus speed: *Encoding* *Scalable Bus Speed* - /// - /// 000B 100 MHz All others values reserved. - /// - UINT32 ScalableBusSpeed:3; - UINT32 Reserved2:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_EBC_FREQUENCY_ID_1_REGISTER; - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EAX/RAX Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RAX (0x00000180) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RAX); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RAX, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RAX is defined as MSR_MCG_RAX in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RAX 0x00000180 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EBX/RBX Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RBX (0x00000181) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RBX); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RBX, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RBX is defined as MSR_MCG_RBX in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RBX 0x00000181 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check ECX/RCX Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RCX (0x00000182) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RCX); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RCX, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RCX is defined as MSR_MCG_RCX in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RCX 0x00000182 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EDX/RDX Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RDX (0x00000183) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RDX); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RDX, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RDX is defined as MSR_MCG_RDX in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RDX 0x00000183 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check ESI/RSI Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RSI (0x00000184) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RSI); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RSI, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RSI is defined as MSR_MCG_RSI in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RSI 0x00000184 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EDI/RDI Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RDI (0x00000185) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RDI); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RDI, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RDI is defined as MSR_MCG_RDI in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RDI 0x00000185 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EBP/RBP Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RBP (0x00000186) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RBP); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RBP, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RBP is defined as MSR_MCG_RBP in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RBP 0x00000186 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check ESP/RSP Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RSP (0x00000187) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RSP); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RSP, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RSP is defined as MSR_MCG_RSP in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RSP 0x00000187 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EFLAGS/RFLAG Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RFLAGS (0x00000188) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RFLAGS); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RFLAGS, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RFLAGS is defined as MSR_MCG_RFLAGS in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RFLAGS 0x00000188 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check EIP/RIP Save State See Section - 15.3.2.6, "IA32_MCG Extended Machine Check State MSRs.". Contains register - state at time of machine check error. When in non-64-bit modes at the time - of the error, bits 63-32 do not contain valid data. - - @param ECX MSR_PENTIUM_4_MCG_RIP (0x00000189) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RIP); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RIP, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_RIP is defined as MSR_MCG_RIP in SDM. -**/ -#define MSR_PENTIUM_4_MCG_RIP 0x00000189 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check Miscellaneous See Section 15.3.2.6, - "IA32_MCG Extended Machine Check State MSRs.". - - @param ECX MSR_PENTIUM_4_MCG_MISC (0x0000018A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_MCG_MISC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_MCG_MISC_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_MCG_MISC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_MCG_MISC); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_MISC, Msr.Uint64); - @endcode - @note MSR_PENTIUM_4_MCG_MISC is defined as MSR_MCG_MISC in SDM. -**/ -#define MSR_PENTIUM_4_MCG_MISC 0x0000018A - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_MCG_MISC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] DS When set, the bit indicates that a page assist or page - /// fault occurred during DS normal operation. The processors response is - /// to shut down. The bit is used as an aid for debugging DS handling - /// code. It is the responsibility of the user (BIOS or operating system) - /// to clear this bit for normal operation. - /// - UINT32 DS:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_MCG_MISC_REGISTER; - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R8 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R8 (0x00000190) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R8); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R8, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R8 is defined as MSR_MCG_R8 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R8 0x00000190 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R9D/R9 See Section 15.3.2.6, - "IA32_MCG Extended Machine Check State MSRs.". Registers R8-15 (and the - associated state-save MSRs) exist only in Intel 64 processors. These - registers contain valid information only when the processor is operating in - 64-bit mode at the time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R9 (0x00000191) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R9); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R9, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R9 is defined as MSR_MCG_R9 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R9 0x00000191 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R10 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R10 (0x00000192) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R10); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R10, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R10 is defined as MSR_MCG_R10 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R10 0x00000192 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R11 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R11 (0x00000193) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R11); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R11, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R11 is defined as MSR_MCG_R11 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R11 0x00000193 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R12 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R12 (0x00000194) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R12); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R12, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R12 is defined as MSR_MCG_R12 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R12 0x00000194 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R13 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R13 (0x00000195) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R13); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R13, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R13 is defined as MSR_MCG_R13 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R13 0x00000195 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R14 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R14 (0x00000196) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R14); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R14, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R14 is defined as MSR_MCG_R14 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R14 0x00000196 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Machine Check R15 See Section 15.3.2.6, "IA32_MCG - Extended Machine Check State MSRs.". Registers R8-15 (and the associated - state-save MSRs) exist only in Intel 64 processors. These registers contain - valid information only when the processor is operating in 64-bit mode at the - time of the error. - - @param ECX MSR_PENTIUM_4_MCG_R15 (0x00000197) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R15); - AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R15, Msr); - @endcode - @note MSR_PENTIUM_4_MCG_R15 is defined as MSR_MCG_R15 in SDM. -**/ -#define MSR_PENTIUM_4_MCG_R15 0x00000197 - - -/** - Thermal Monitor 2 Control. 3,. Shared. For Family F, Model 3 processors: - When read, specifies the value of the target TM2 transition last written. - When set, it sets the next target value for TM2 transition. 4, 6. Shared. - For Family F, Model 4 and Model 6 processors: When read, specifies the value - of the target TM2 transition last written. Writes may cause #GP exceptions. - - @param ECX MSR_PENTIUM_4_THERM2_CTL (0x0000019D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_THERM2_CTL); - AsmWriteMsr64 (MSR_PENTIUM_4_THERM2_CTL, Msr); - @endcode - @note MSR_PENTIUM_4_THERM2_CTL is defined as MSR_THERM2_CTL in SDM. -**/ -#define MSR_PENTIUM_4_THERM2_CTL 0x0000019D - - -/** - 0, 1, 2, 3, 4, 6. Shared. Enable Miscellaneous Processor Features (R/W). - - @param ECX MSR_PENTIUM_4_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_PENTIUM_4_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_PENTIUM_4_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_PENTIUM_4_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fast-Strings Enable. See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] x87 FPU Fopcode Compatibility Mode Enable. - /// - UINT32 FPU:1; - /// - /// [Bit 3] Thermal Monitor 1 Enable See Section 14.7.2, "Thermal - /// Monitor," and see Table 35-2. - /// - UINT32 TM1:1; - /// - /// [Bit 4] Split-Lock Disable When set, the bit causes an #AC exception - /// to be issued instead of a split-lock cycle. Operating systems that set - /// this bit must align system structures to avoid split-lock scenarios. - /// When the bit is clear (default), normal split-locks are issued to the - /// bus. - /// This debug feature is specific to the Pentium 4 processor. - /// - UINT32 SplitLockDisable:1; - UINT32 Reserved2:1; - /// - /// [Bit 6] Third-Level Cache Disable (R/W) When set, the third-level - /// cache is disabled; when clear (default) the third-level cache is - /// enabled. This flag is reserved for processors that do not have a - /// third-level cache. Note that the bit controls only the third-level - /// cache; and only if overall caching is enabled through the CD flag of - /// control register CR0, the page-level cache controls, and/or the MTRRs. - /// See Section 11.5.4, "Disabling and Enabling the L3 Cache.". - /// - UINT32 ThirdLevelCacheDisable:1; - /// - /// [Bit 7] Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - /// - /// [Bit 8] Suppress Lock Enable When set, assertion of LOCK on the bus is - /// suppressed during a Split Lock access. When clear (default), LOCK is - /// not suppressed. - /// - UINT32 SuppressLockEnable:1; - /// - /// [Bit 9] Prefetch Queue Disable When set, disables the prefetch queue. - /// When clear (default), enables the prefetch queue. - /// - UINT32 PrefetchQueueDisable:1; - /// - /// [Bit 10] FERR# Interrupt Reporting Enable (R/W) When set, interrupt - /// reporting through the FERR# pin is enabled; when clear, this interrupt - /// reporting function is disabled. - /// When this flag is set and the processor is in the stop-clock state - /// (STPCLK# is asserted), asserting the FERR# pin signals to the - /// processor that an interrupt (such as, INIT#, BINIT#, INTR, NMI, - /// SMI#, or RESET#) is pending and that the processor should return to - /// normal operation to handle the interrupt. This flag does not affect - /// the normal operation of the FERR# pin (to indicate an unmasked - /// floatingpoint error) when the STPCLK# pin is not asserted. - /// - UINT32 FERR:1; - /// - /// [Bit 11] Branch Trace Storage Unavailable (BTS_UNAVILABLE) (R) See - /// Table 35-2. When set, the processor does not support branch trace - /// storage (BTS); when clear, BTS is supported. - /// - UINT32 BTS:1; - /// - /// [Bit 12] PEBS_UNAVILABLE: Processor Event Based Sampling Unavailable - /// (R) See Table 35-2. When set, the processor does not support processor - /// event-based sampling (PEBS); when clear, PEBS is supported. - /// - UINT32 PEBS:1; - /// - /// [Bit 13] 3. TM2 Enable (R/W) When this bit is set (1) and the thermal - /// sensor indicates that the die temperature is at the predetermined - /// threshold, the Thermal Monitor 2 mechanism is engaged. TM2 will reduce - /// the bus to core ratio and voltage according to the value last written - /// to MSR_THERM2_CTL bits 15:0. When this bit is clear (0, default), the - /// processor does not change the VID signals or the bus to core ratio - /// when the processor enters a thermal managed state. If the TM2 feature - /// flag (ECX[8]) is not set to 1 after executing CPUID with EAX = 1, then - /// this feature is not supported and BIOS must not alter the contents of - /// this bit location. The processor is operating out of spec if both this - /// bit and the TM1 bit are set to disabled states. - /// - UINT32 TM2:1; - UINT32 Reserved3:4; - /// - /// [Bit 18] 3, 4, 6. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - /// - /// [Bit 19] Adjacent Cache Line Prefetch Disable (R/W) When set to 1, - /// the processor fetches the cache line of the 128-byte sector containing - /// currently required data. When set to 0, the processor fetches both - /// cache lines in the sector. - /// Single processor platforms should not set this bit. Server platforms - /// should set or clear this bit based on platform performance observed - /// in validation and testing. BIOS may contain a setup option that - /// controls the setting of this bit. - /// - UINT32 AdjacentCacheLinePrefetchDisable:1; - UINT32 Reserved4:2; - /// - /// [Bit 22] 3, 4, 6. Limit CPUID MAXVAL (R/W) See Table 35-2. Setting - /// this can cause unexpected behavior to software that depends on the - /// availability of CPUID leaves greater than 3. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Shared. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - /// - /// [Bit 24] L1 Data Cache Context Mode (R/W) When set, the L1 data cache - /// is placed in shared mode; when clear (default), the cache is placed in - /// adaptive mode. This bit is only enabled for IA-32 processors that - /// support Intel Hyper-Threading Technology. See Section 11.5.6, "L1 Data - /// Cache Context Mode." When L1 is running in adaptive mode and CR3s are - /// identical, data in L1 is shared across logical processors. Otherwise, - /// L1 is not shared and cache use is competitive. If the Context ID - /// feature flag (ECX[10]) is set to 0 after executing CPUID with EAX = 1, - /// the ability to switch modes is not supported. BIOS must not alter the - /// contents of IA32_MISC_ENABLE[24]. - /// - UINT32 L1DataCacheContextMode:1; - UINT32 Reserved5:7; - UINT32 Reserved6:2; - /// - /// [Bit 34] Unique. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved7:29; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_IA32_MISC_ENABLE_REGISTER; - - -/** - 3, 4, 6. Shared. Platform Feature Requirements (R). - - @param ECX MSR_PENTIUM_4_PLATFORM_BRV (0x000001A1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_PLATFORM_BRV_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_PLATFORM_BRV_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_PLATFORM_BRV_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_PLATFORM_BRV); - @endcode - @note MSR_PENTIUM_4_PLATFORM_BRV is defined as MSR_PLATFORM_BRV in SDM. -**/ -#define MSR_PENTIUM_4_PLATFORM_BRV 0x000001A1 - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_PLATFORM_BRV -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:18; - /// - /// [Bit 18] PLATFORM Requirements When set to 1, indicates the processor - /// has specific platform requirements. The details of the platform - /// requirements are listed in the respective data sheets of the processor. - /// - UINT32 PLATFORM:1; - UINT32 Reserved2:13; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_PLATFORM_BRV_REGISTER; - - -/** - 0, 1, 2, 3, 4, 6. Unique. Last Exception Record From Linear IP (R) Contains - a pointer to the last branch instruction that the processor executed prior - to the last exception that was generated or the last interrupt that was - handled. See Section 17.11.3, "Last Exception Records.". Unique. From Linear - IP Linear address of the last branch instruction (If IA32e mode is active). - From Linear IP Linear address of the last branch instruction. Reserved. - - @param ECX MSR_PENTIUM_4_LER_FROM_LIP (0x000001D7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LER_FROM_LIP); - @endcode - @note MSR_PENTIUM_4_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_PENTIUM_4_LER_FROM_LIP 0x000001D7 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Last Exception Record To Linear IP (R) This area - contains a pointer to the target of the last branch instruction that the - processor executed prior to the last exception that was generated or the - last interrupt that was handled. See Section 17.11.3, "Last Exception - Records.". Unique. From Linear IP Linear address of the target of the last - branch instruction (If IA-32e mode is active). From Linear IP Linear address - of the target of the last branch instruction. Reserved. - - @param ECX MSR_PENTIUM_4_LER_TO_LIP (0x000001D8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LER_TO_LIP); - @endcode - @note MSR_PENTIUM_4_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_PENTIUM_4_LER_TO_LIP 0x000001D8 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Debug Control (R/W) Controls how several debug - features are used. Bit definitions are discussed in the referenced section. - See Section 17.11.1, "MSR_DEBUGCTLA MSR.". - - @param ECX MSR_PENTIUM_4_DEBUGCTLA (0x000001D9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_DEBUGCTLA); - AsmWriteMsr64 (MSR_PENTIUM_4_DEBUGCTLA, Msr); - @endcode - @note MSR_PENTIUM_4_DEBUGCTLA is defined as MSR_DEBUGCTLA in SDM. -**/ -#define MSR_PENTIUM_4_DEBUGCTLA 0x000001D9 - - -/** - 0, 1, 2, 3, 4, 6. Unique. Last Branch Record Stack TOS (R/W) Contains an - index (0-3 or 0-15) that points to the top of the last branch record stack - (that is, that points the index of the MSR containing the most recent branch - record). See Section 17.11.2, "LBR Stack for Processors Based on Intel - NetBurst(R) Microarchitecture"; and addresses 1DBH-1DEH and 680H-68FH. - - @param ECX MSR_PENTIUM_4_LASTBRANCH_TOS (0x000001DA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_PENTIUM_4_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_PENTIUM_4_LASTBRANCH_TOS 0x000001DA - - -/** - 0, 1, 2. Unique. Last Branch Record n (R/W) One of four last branch record - registers on the last branch record stack. It contains pointers to the - source and destination instruction for one of the last four branches, - exceptions, or interrupts that the processor took. MSR_LASTBRANCH_0 through - MSR_LASTBRANCH_3 at 1DBH-1DEH are available only on family 0FH, models - 0H-02H. They have been replaced by the MSRs at 680H68FH and 6C0H-6CFH. See - Section 17.10, "Last Branch, Call Stack, Interrupt, and Exception Recording - for Processors based on Skylake Microarchitecture.". - - @param ECX MSR_PENTIUM_4_LASTBRANCH_n - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0); - AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0, Msr); - @endcode - @note MSR_PENTIUM_4_LASTBRANCH_0 is defined as MSR_LASTBRANCH_0 in SDM. - MSR_PENTIUM_4_LASTBRANCH_1 is defined as MSR_LASTBRANCH_1 in SDM. - MSR_PENTIUM_4_LASTBRANCH_2 is defined as MSR_LASTBRANCH_2 in SDM. - MSR_PENTIUM_4_LASTBRANCH_3 is defined as MSR_LASTBRANCH_3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_LASTBRANCH_0 0x000001DB -#define MSR_PENTIUM_4_LASTBRANCH_1 0x000001DC -#define MSR_PENTIUM_4_LASTBRANCH_2 0x000001DD -#define MSR_PENTIUM_4_LASTBRANCH_3 0x000001DE -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.2, "Performance Counters.". - - @param ECX MSR_PENTIUM_4_BPU_COUNTERn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_COUNTER0); - AsmWriteMsr64 (MSR_PENTIUM_4_BPU_COUNTER0, Msr); - @endcode - @note MSR_PENTIUM_4_BPU_COUNTER0 is defined as MSR_BPU_COUNTER0 in SDM. - MSR_PENTIUM_4_BPU_COUNTER1 is defined as MSR_BPU_COUNTER1 in SDM. - MSR_PENTIUM_4_BPU_COUNTER2 is defined as MSR_BPU_COUNTER2 in SDM. - MSR_PENTIUM_4_BPU_COUNTER3 is defined as MSR_BPU_COUNTER3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_BPU_COUNTER0 0x00000300 -#define MSR_PENTIUM_4_BPU_COUNTER1 0x00000301 -#define MSR_PENTIUM_4_BPU_COUNTER2 0x00000302 -#define MSR_PENTIUM_4_BPU_COUNTER3 0x00000303 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.2, "Performance Counters.". - - @param ECX MSR_PENTIUM_4_MS_COUNTERn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_COUNTER0); - AsmWriteMsr64 (MSR_PENTIUM_4_MS_COUNTER0, Msr); - @endcode - @note MSR_PENTIUM_4_MS_COUNTER0 is defined as MSR_MS_COUNTER0 in SDM. - MSR_PENTIUM_4_MS_COUNTER1 is defined as MSR_MS_COUNTER1 in SDM. - MSR_PENTIUM_4_MS_COUNTER2 is defined as MSR_MS_COUNTER2 in SDM. - MSR_PENTIUM_4_MS_COUNTER3 is defined as MSR_MS_COUNTER3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_MS_COUNTER0 0x00000304 -#define MSR_PENTIUM_4_MS_COUNTER1 0x00000305 -#define MSR_PENTIUM_4_MS_COUNTER2 0x00000306 -#define MSR_PENTIUM_4_MS_COUNTER3 0x00000307 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.2, "Performance Counters.". - - @param ECX MSR_PENTIUM_4_FLAME_COUNTERn (0x00000308) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_COUNTER0); - AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_COUNTER0, Msr); - @endcode - @note MSR_PENTIUM_4_FLAME_COUNTER0 is defined as MSR_FLAME_COUNTER0 in SDM. - MSR_PENTIUM_4_FLAME_COUNTER1 is defined as MSR_FLAME_COUNTER1 in SDM. - MSR_PENTIUM_4_FLAME_COUNTER2 is defined as MSR_FLAME_COUNTER2 in SDM. - MSR_PENTIUM_4_FLAME_COUNTER3 is defined as MSR_FLAME_COUNTER3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_FLAME_COUNTER0 0x00000308 -#define MSR_PENTIUM_4_FLAME_COUNTER1 0x00000309 -#define MSR_PENTIUM_4_FLAME_COUNTER2 0x0000030A -#define MSR_PENTIUM_4_FLAME_COUNTER3 0x0000030B -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.2, "Performance Counters.". - - @param ECX MSR_PENTIUM_4_IQ_COUNTERn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_COUNTER0); - AsmWriteMsr64 (MSR_PENTIUM_4_IQ_COUNTER0, Msr); - @endcode - @note MSR_PENTIUM_4_IQ_COUNTER0 is defined as MSR_IQ_COUNTER0 in SDM. - MSR_PENTIUM_4_IQ_COUNTER1 is defined as MSR_IQ_COUNTER1 in SDM. - MSR_PENTIUM_4_IQ_COUNTER2 is defined as MSR_IQ_COUNTER2 in SDM. - MSR_PENTIUM_4_IQ_COUNTER3 is defined as MSR_IQ_COUNTER3 in SDM. - MSR_PENTIUM_4_IQ_COUNTER4 is defined as MSR_IQ_COUNTER4 in SDM. - MSR_PENTIUM_4_IQ_COUNTER5 is defined as MSR_IQ_COUNTER5 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_IQ_COUNTER0 0x0000030C -#define MSR_PENTIUM_4_IQ_COUNTER1 0x0000030D -#define MSR_PENTIUM_4_IQ_COUNTER2 0x0000030E -#define MSR_PENTIUM_4_IQ_COUNTER3 0x0000030F -#define MSR_PENTIUM_4_IQ_COUNTER4 0x00000310 -#define MSR_PENTIUM_4_IQ_COUNTER5 0x00000311 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.3, "CCCR MSRs.". - - @param ECX MSR_PENTIUM_4_BPU_CCCRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_CCCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_BPU_CCCR0, Msr); - @endcode - @note MSR_PENTIUM_4_BPU_CCCR0 is defined as MSR_BPU_CCCR0 in SDM. - MSR_PENTIUM_4_BPU_CCCR1 is defined as MSR_BPU_CCCR1 in SDM. - MSR_PENTIUM_4_BPU_CCCR2 is defined as MSR_BPU_CCCR2 in SDM. - MSR_PENTIUM_4_BPU_CCCR3 is defined as MSR_BPU_CCCR3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_BPU_CCCR0 0x00000360 -#define MSR_PENTIUM_4_BPU_CCCR1 0x00000361 -#define MSR_PENTIUM_4_BPU_CCCR2 0x00000362 -#define MSR_PENTIUM_4_BPU_CCCR3 0x00000363 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.3, "CCCR MSRs.". - - @param ECX MSR_PENTIUM_4_MS_CCCRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_CCCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_MS_CCCR0, Msr); - @endcode - @note MSR_PENTIUM_4_MS_CCCR0 is defined as MSR_MS_CCCR0 in SDM. - MSR_PENTIUM_4_MS_CCCR1 is defined as MSR_MS_CCCR1 in SDM. - MSR_PENTIUM_4_MS_CCCR2 is defined as MSR_MS_CCCR2 in SDM. - MSR_PENTIUM_4_MS_CCCR3 is defined as MSR_MS_CCCR3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_MS_CCCR0 0x00000364 -#define MSR_PENTIUM_4_MS_CCCR1 0x00000365 -#define MSR_PENTIUM_4_MS_CCCR2 0x00000366 -#define MSR_PENTIUM_4_MS_CCCR3 0x00000367 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.3, "CCCR MSRs.". - - @param ECX MSR_PENTIUM_4_FLAME_CCCRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_CCCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_CCCR0, Msr); - @endcode - @note MSR_PENTIUM_4_FLAME_CCCR0 is defined as MSR_FLAME_CCCR0 in SDM. - MSR_PENTIUM_4_FLAME_CCCR1 is defined as MSR_FLAME_CCCR1 in SDM. - MSR_PENTIUM_4_FLAME_CCCR2 is defined as MSR_FLAME_CCCR2 in SDM. - MSR_PENTIUM_4_FLAME_CCCR3 is defined as MSR_FLAME_CCCR3 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_FLAME_CCCR0 0x00000368 -#define MSR_PENTIUM_4_FLAME_CCCR1 0x00000369 -#define MSR_PENTIUM_4_FLAME_CCCR2 0x0000036A -#define MSR_PENTIUM_4_FLAME_CCCR3 0x0000036B -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.3, "CCCR MSRs.". - - @param ECX MSR_PENTIUM_4_IQ_CCCRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_CCCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_IQ_CCCR0, Msr); - @endcode - @note MSR_PENTIUM_4_IQ_CCCR0 is defined as MSR_IQ_CCCR0 in SDM. - MSR_PENTIUM_4_IQ_CCCR1 is defined as MSR_IQ_CCCR1 in SDM. - MSR_PENTIUM_4_IQ_CCCR2 is defined as MSR_IQ_CCCR2 in SDM. - MSR_PENTIUM_4_IQ_CCCR3 is defined as MSR_IQ_CCCR3 in SDM. - MSR_PENTIUM_4_IQ_CCCR4 is defined as MSR_IQ_CCCR4 in SDM. - MSR_PENTIUM_4_IQ_CCCR5 is defined as MSR_IQ_CCCR5 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_IQ_CCCR0 0x0000036C -#define MSR_PENTIUM_4_IQ_CCCR1 0x0000036D -#define MSR_PENTIUM_4_IQ_CCCR2 0x0000036E -#define MSR_PENTIUM_4_IQ_CCCR3 0x0000036F -#define MSR_PENTIUM_4_IQ_CCCR4 0x00000370 -#define MSR_PENTIUM_4_IQ_CCCR5 0x00000371 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_BSU_ESCR0 (0x000003A0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BSU_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_BSU_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_BSU_ESCR0 is defined as MSR_BSU_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_BSU_ESCR0 0x000003A0 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_BSU_ESCR1 (0x000003A1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BSU_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_BSU_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_BSU_ESCR1 is defined as MSR_BSU_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_BSU_ESCR1 0x000003A1 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FSB_ESCR0 (0x000003A2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FSB_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_FSB_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_FSB_ESCR0 is defined as MSR_FSB_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_FSB_ESCR0 0x000003A2 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FSB_ESCR1 (0x000003A3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FSB_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_FSB_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_FSB_ESCR1 is defined as MSR_FSB_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_FSB_ESCR1 0x000003A3 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FIRM_ESCR0 (0x000003A4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FIRM_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_FIRM_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_FIRM_ESCR0 is defined as MSR_FIRM_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_FIRM_ESCR0 0x000003A4 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FIRM_ESCR1 (0x000003A5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FIRM_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_FIRM_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_FIRM_ESCR1 is defined as MSR_FIRM_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_FIRM_ESCR1 0x000003A5 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FLAME_ESCR0 (0x000003A6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_FLAME_ESCR0 is defined as MSR_FLAME_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_FLAME_ESCR0 0x000003A6 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_FLAME_ESCR1 (0x000003A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_FLAME_ESCR1 is defined as MSR_FLAME_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_FLAME_ESCR1 0x000003A7 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_DAC_ESCR0 (0x000003A8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_DAC_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_DAC_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_DAC_ESCR0 is defined as MSR_DAC_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_DAC_ESCR0 0x000003A8 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_DAC_ESCR1 (0x000003A9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_DAC_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_DAC_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_DAC_ESCR1 is defined as MSR_DAC_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_DAC_ESCR1 0x000003A9 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_MOB_ESCR0 (0x000003AA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MOB_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_MOB_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_MOB_ESCR0 is defined as MSR_MOB_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_MOB_ESCR0 0x000003AA - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_MOB_ESCR1 (0x000003AB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MOB_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_MOB_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_MOB_ESCR1 is defined as MSR_MOB_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_MOB_ESCR1 0x000003AB - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_PMH_ESCR0 (0x000003AC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_PMH_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_PMH_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_PMH_ESCR0 is defined as MSR_PMH_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_PMH_ESCR0 0x000003AC - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_PMH_ESCR1 (0x000003AD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_PMH_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_PMH_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_PMH_ESCR1 is defined as MSR_PMH_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_PMH_ESCR1 0x000003AD - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_SAAT_ESCR0 (0x000003AE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_SAAT_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_SAAT_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_SAAT_ESCR0 is defined as MSR_SAAT_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_SAAT_ESCR0 0x000003AE - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_SAAT_ESCR1 (0x000003AF) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_SAAT_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_SAAT_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_SAAT_ESCR1 is defined as MSR_SAAT_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_SAAT_ESCR1 0x000003AF - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_U2L_ESCR0 (0x000003B0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_U2L_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_U2L_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_U2L_ESCR0 is defined as MSR_U2L_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_U2L_ESCR0 0x000003B0 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_U2L_ESCR1 (0x000003B1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_U2L_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_U2L_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_U2L_ESCR1 is defined as MSR_U2L_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_U2L_ESCR1 0x000003B1 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_BPU_ESCR0 (0x000003B2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_BPU_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_BPU_ESCR0 is defined as MSR_BPU_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_BPU_ESCR0 0x000003B2 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_BPU_ESCR1 (0x000003B3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_BPU_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_BPU_ESCR1 is defined as MSR_BPU_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_BPU_ESCR1 0x000003B3 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_IS_ESCR0 (0x000003B4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IS_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_IS_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_IS_ESCR0 is defined as MSR_IS_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_IS_ESCR0 0x000003B4 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_IS_ESCR1 (0x000003B5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IS_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_IS_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_IS_ESCR1 is defined as MSR_IS_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_IS_ESCR1 0x000003B5 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_ITLB_ESCR0 (0x000003B6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_ITLB_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_ITLB_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_ITLB_ESCR0 is defined as MSR_ITLB_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_ITLB_ESCR0 0x000003B6 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_ITLB_ESCR1 (0x000003B7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_ITLB_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_ITLB_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_ITLB_ESCR1 is defined as MSR_ITLB_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_ITLB_ESCR1 0x000003B7 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_CRU_ESCR0 (0x000003B8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_CRU_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_CRU_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_CRU_ESCR0 is defined as MSR_CRU_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_CRU_ESCR0 0x000003B8 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_CRU_ESCR1 (0x000003B9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_CRU_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_CRU_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_CRU_ESCR1 is defined as MSR_CRU_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_CRU_ESCR1 0x000003B9 - - -/** - 0, 1, 2. Shared. See Section 18.15.1, "ESCR MSRs." This MSR is not available - on later processors. It is only available on processor family 0FH, models - 01H-02H. - - @param ECX MSR_PENTIUM_4_IQ_ESCR0 (0x000003BA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_IQ_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_IQ_ESCR0 is defined as MSR_IQ_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_IQ_ESCR0 0x000003BA - - -/** - 0, 1, 2. Shared. See Section 18.15.1, "ESCR MSRs." This MSR is not available - on later processors. It is only available on processor family 0FH, models - 01H-02H. - - @param ECX MSR_PENTIUM_4_IQ_ESCR1 (0x000003BB) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_IQ_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_IQ_ESCR1 is defined as MSR_IQ_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_IQ_ESCR1 0x000003BB - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_RAT_ESCR0 (0x000003BC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_RAT_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_RAT_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_RAT_ESCR0 is defined as MSR_RAT_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_RAT_ESCR0 0x000003BC - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_RAT_ESCR1 (0x000003BD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_RAT_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_RAT_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_RAT_ESCR1 is defined as MSR_RAT_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_RAT_ESCR1 0x000003BD - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_SSU_ESCR0 (0x000003BE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_SSU_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_SSU_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_SSU_ESCR0 is defined as MSR_SSU_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_SSU_ESCR0 0x000003BE - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_MS_ESCR0 (0x000003C0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_MS_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_MS_ESCR0 is defined as MSR_MS_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_MS_ESCR0 0x000003C0 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_MS_ESCR1 (0x000003C1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_MS_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_MS_ESCR1 is defined as MSR_MS_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_MS_ESCR1 0x000003C1 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_TBPU_ESCR0 (0x000003C2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_TBPU_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_TBPU_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_TBPU_ESCR0 is defined as MSR_TBPU_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_TBPU_ESCR0 0x000003C2 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_TBPU_ESCR1 (0x000003C3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_TBPU_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_TBPU_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_TBPU_ESCR1 is defined as MSR_TBPU_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_TBPU_ESCR1 0x000003C3 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_TC_ESCR0 (0x000003C4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_TC_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_TC_ESCR0 is defined as MSR_TC_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_TC_ESCR0 0x000003C4 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_TC_ESCR1 (0x000003C5) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_TC_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_TC_ESCR1 is defined as MSR_TC_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_TC_ESCR1 0x000003C5 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_IX_ESCR0 (0x000003C8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IX_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_IX_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_IX_ESCR0 is defined as MSR_IX_ESCR0 in SDM. -**/ -#define MSR_PENTIUM_4_IX_ESCR0 0x000003C8 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_IX_ESCR1 (0x000003C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IX_ESCR1); - AsmWriteMsr64 (MSR_PENTIUM_4_IX_ESCR1, Msr); - @endcode - @note MSR_PENTIUM_4_IX_ESCR1 is defined as MSR_IX_ESCR1 in SDM. -**/ -#define MSR_PENTIUM_4_IX_ESCR1 0x000003C9 - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_ALF_ESCRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_ALF_ESCR0); - AsmWriteMsr64 (MSR_PENTIUM_4_ALF_ESCR0, Msr); - @endcode - @note MSR_PENTIUM_4_ALF_ESCR0 is defined as MSR_ALF_ESCR0 in SDM. - MSR_PENTIUM_4_ALF_ESCR1 is defined as MSR_ALF_ESCR1 in SDM. - MSR_PENTIUM_4_CRU_ESCR2 is defined as MSR_CRU_ESCR2 in SDM. - MSR_PENTIUM_4_CRU_ESCR3 is defined as MSR_CRU_ESCR3 in SDM. - MSR_PENTIUM_4_CRU_ESCR4 is defined as MSR_CRU_ESCR4 in SDM. - MSR_PENTIUM_4_CRU_ESCR5 is defined as MSR_CRU_ESCR5 in SDM. - @{ -**/ -#define MSR_PENTIUM_4_ALF_ESCR0 0x000003CA -#define MSR_PENTIUM_4_ALF_ESCR1 0x000003CB -#define MSR_PENTIUM_4_CRU_ESCR2 0x000003CC -#define MSR_PENTIUM_4_CRU_ESCR3 0x000003CD -#define MSR_PENTIUM_4_CRU_ESCR4 0x000003E0 -#define MSR_PENTIUM_4_CRU_ESCR5 0x000003E1 -/// @} - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Section 18.15.1, "ESCR MSRs.". - - @param ECX MSR_PENTIUM_4_TC_PRECISE_EVENT (0x000003F0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_PRECISE_EVENT); - AsmWriteMsr64 (MSR_PENTIUM_4_TC_PRECISE_EVENT, Msr); - @endcode - @note MSR_PENTIUM_4_TC_PRECISE_EVENT is defined as MSR_TC_PRECISE_EVENT in SDM. -**/ -#define MSR_PENTIUM_4_TC_PRECISE_EVENT 0x000003F0 - - -/** - 0, 1, 2, 3, 4, 6. Shared. Processor Event Based Sampling (PEBS) (R/W) - Controls the enabling of processor event sampling and replay tagging. - - @param ECX MSR_PENTIUM_4_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_4_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_PENTIUM_4_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_PEBS_ENABLE); - AsmWriteMsr64 (MSR_PENTIUM_4_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_PENTIUM_4_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_PENTIUM_4_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_PENTIUM_4_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 12:0] See Table 19-33. - /// - UINT32 EventNum:13; - UINT32 Reserved1:11; - /// - /// [Bit 24] UOP Tag Enables replay tagging when set. - /// - UINT32 UOP:1; - /// - /// [Bit 25] ENABLE_PEBS_MY_THR (R/W) Enables PEBS for the target logical - /// processor when set; disables PEBS when clear (default). See Section - /// 18.16.3, "IA32_PEBS_ENABLE MSR," for an explanation of the target - /// logical processor. This bit is called ENABLE_PEBS in IA-32 processors - /// that do not support Intel HyperThreading Technology. - /// - UINT32 ENABLE_PEBS_MY_THR:1; - /// - /// [Bit 26] ENABLE_PEBS_OTH_THR (R/W) Enables PEBS for the target logical - /// processor when set; disables PEBS when clear (default). See Section - /// 18.16.3, "IA32_PEBS_ENABLE MSR," for an explanation of the target - /// logical processor. This bit is reserved for IA-32 processors that do - /// not support Intel Hyper-Threading Technology. - /// - UINT32 ENABLE_PEBS_OTH_THR:1; - UINT32 Reserved2:5; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_4_PEBS_ENABLE_REGISTER; - - -/** - 0, 1, 2, 3, 4, 6. Shared. See Table 19-33. - - @param ECX MSR_PENTIUM_4_PEBS_MATRIX_VERT (0x000003F2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_PEBS_MATRIX_VERT); - AsmWriteMsr64 (MSR_PENTIUM_4_PEBS_MATRIX_VERT, Msr); - @endcode - @note MSR_PENTIUM_4_PEBS_MATRIX_VERT is defined as MSR_PEBS_MATRIX_VERT in SDM. -**/ -#define MSR_PENTIUM_4_PEBS_MATRIX_VERT 0x000003F2 - - -/** - 3, 4, 6. Unique. Last Branch Record n (R/W) One of 16 pairs of last branch - record registers on the last branch record stack (680H-68FH). This part of - the stack contains pointers to the source instruction for one of the last 16 - branches, exceptions, or interrupts taken by the processor. The MSRs at - 680H-68FH, 6C0H-6CfH are not available in processor releases before family - 0FH, model 03H. These MSRs replace MSRs previously located at - 1DBH-1DEH.which performed the same function for early releases. See Section - 17.10, "Last Branch, Call Stack, Interrupt, and Exception Recording for - Processors based on Skylake Microarchitecture.". - - @param ECX MSR_PENTIUM_4_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_8_FROM_IP is defined as MSR_LASTBRANCH_8_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_9_FROM_IP is defined as MSR_LASTBRANCH_9_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_10_FROM_IP is defined as MSR_LASTBRANCH_10_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_11_FROM_IP is defined as MSR_LASTBRANCH_11_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_12_FROM_IP is defined as MSR_LASTBRANCH_12_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_13_FROM_IP is defined as MSR_LASTBRANCH_13_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_14_FROM_IP is defined as MSR_LASTBRANCH_14_FROM_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_15_FROM_IP is defined as MSR_LASTBRANCH_15_FROM_IP in SDM. - @{ -**/ -#define MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP 0x00000680 -#define MSR_PENTIUM_4_LASTBRANCH_1_FROM_IP 0x00000681 -#define MSR_PENTIUM_4_LASTBRANCH_2_FROM_IP 0x00000682 -#define MSR_PENTIUM_4_LASTBRANCH_3_FROM_IP 0x00000683 -#define MSR_PENTIUM_4_LASTBRANCH_4_FROM_IP 0x00000684 -#define MSR_PENTIUM_4_LASTBRANCH_5_FROM_IP 0x00000685 -#define MSR_PENTIUM_4_LASTBRANCH_6_FROM_IP 0x00000686 -#define MSR_PENTIUM_4_LASTBRANCH_7_FROM_IP 0x00000687 -#define MSR_PENTIUM_4_LASTBRANCH_8_FROM_IP 0x00000688 -#define MSR_PENTIUM_4_LASTBRANCH_9_FROM_IP 0x00000689 -#define MSR_PENTIUM_4_LASTBRANCH_10_FROM_IP 0x0000068A -#define MSR_PENTIUM_4_LASTBRANCH_11_FROM_IP 0x0000068B -#define MSR_PENTIUM_4_LASTBRANCH_12_FROM_IP 0x0000068C -#define MSR_PENTIUM_4_LASTBRANCH_13_FROM_IP 0x0000068D -#define MSR_PENTIUM_4_LASTBRANCH_14_FROM_IP 0x0000068E -#define MSR_PENTIUM_4_LASTBRANCH_15_FROM_IP 0x0000068F -/// @} - - -/** - 3, 4, 6. Unique. Last Branch Record n (R/W) One of 16 pairs of last branch - record registers on the last branch record stack (6C0H-6CFH). This part of - the stack contains pointers to the destination instruction for one of the - last 16 branches, exceptions, or interrupts that the processor took. See - Section 17.10, "Last Branch, Call Stack, Interrupt, and Exception Recording - for Processors based on Skylake Microarchitecture.". - - @param ECX MSR_PENTIUM_4_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_PENTIUM_4_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_8_TO_IP is defined as MSR_LASTBRANCH_8_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_9_TO_IP is defined as MSR_LASTBRANCH_9_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_10_TO_IP is defined as MSR_LASTBRANCH_10_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_11_TO_IP is defined as MSR_LASTBRANCH_11_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_12_TO_IP is defined as MSR_LASTBRANCH_12_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_13_TO_IP is defined as MSR_LASTBRANCH_13_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_14_TO_IP is defined as MSR_LASTBRANCH_14_TO_IP in SDM. - MSR_PENTIUM_4_LASTBRANCH_15_TO_IP is defined as MSR_LASTBRANCH_15_TO_IP in SDM. - @{ -**/ -#define MSR_PENTIUM_4_LASTBRANCH_0_TO_IP 0x000006C0 -#define MSR_PENTIUM_4_LASTBRANCH_1_TO_IP 0x000006C1 -#define MSR_PENTIUM_4_LASTBRANCH_2_TO_IP 0x000006C2 -#define MSR_PENTIUM_4_LASTBRANCH_3_TO_IP 0x000006C3 -#define MSR_PENTIUM_4_LASTBRANCH_4_TO_IP 0x000006C4 -#define MSR_PENTIUM_4_LASTBRANCH_5_TO_IP 0x000006C5 -#define MSR_PENTIUM_4_LASTBRANCH_6_TO_IP 0x000006C6 -#define MSR_PENTIUM_4_LASTBRANCH_7_TO_IP 0x000006C7 -#define MSR_PENTIUM_4_LASTBRANCH_8_TO_IP 0x000006C8 -#define MSR_PENTIUM_4_LASTBRANCH_9_TO_IP 0x000006C9 -#define MSR_PENTIUM_4_LASTBRANCH_10_TO_IP 0x000006CA -#define MSR_PENTIUM_4_LASTBRANCH_11_TO_IP 0x000006CB -#define MSR_PENTIUM_4_LASTBRANCH_12_TO_IP 0x000006CC -#define MSR_PENTIUM_4_LASTBRANCH_13_TO_IP 0x000006CD -#define MSR_PENTIUM_4_LASTBRANCH_14_TO_IP 0x000006CE -#define MSR_PENTIUM_4_LASTBRANCH_15_TO_IP 0x000006CF -/// @} - - -/** - 3, 4. Shared. IFSB BUSQ Event Control and Counter Register (R/W) See - Section 18.21, "Performance Monitoring on 64-bit Intel Xeon Processor MP - with Up to 8-MByte L3 Cache.". - - @param ECX MSR_PENTIUM_4_IFSB_BUSQ0 (0x000107CC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_BUSQ0); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_BUSQ0, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_BUSQ0 is defined as MSR_IFSB_BUSQ0 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_BUSQ0 0x000107CC - - -/** - 3, 4. Shared. IFSB BUSQ Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_IFSB_BUSQ1 (0x000107CD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_BUSQ1); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_BUSQ1, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_BUSQ1 is defined as MSR_IFSB_BUSQ1 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_BUSQ1 0x000107CD - - -/** - 3, 4. Shared. IFSB SNPQ Event Control and Counter Register (R/W) See - Section 18.21, "Performance Monitoring on 64-bit Intel Xeon Processor MP - with Up to 8-MByte L3 Cache.". - - @param ECX MSR_PENTIUM_4_IFSB_SNPQ0 (0x000107CE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_SNPQ0); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_SNPQ0, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_SNPQ0 is defined as MSR_IFSB_SNPQ0 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_SNPQ0 0x000107CE - - -/** - 3, 4. Shared. IFSB SNPQ Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_IFSB_SNPQ1 (0x000107CF) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_SNPQ1); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_SNPQ1, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_SNPQ1 is defined as MSR_IFSB_SNPQ1 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_SNPQ1 0x000107CF - - -/** - 3, 4. Shared. EFSB DRDY Event Control and Counter Register (R/W) See - Section 18.21, "Performance Monitoring on 64-bit Intel Xeon Processor MP - with Up to 8-MByte L3 Cache" for details. - - @param ECX MSR_PENTIUM_4_EFSB_DRDY0 (0x000107D0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EFSB_DRDY0); - AsmWriteMsr64 (MSR_PENTIUM_4_EFSB_DRDY0, Msr); - @endcode - @note MSR_PENTIUM_4_EFSB_DRDY0 is defined as MSR_EFSB_DRDY0 in SDM. -**/ -#define MSR_PENTIUM_4_EFSB_DRDY0 0x000107D0 - - -/** - 3, 4. Shared. EFSB DRDY Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EFSB_DRDY1 (0x000107D1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EFSB_DRDY1); - AsmWriteMsr64 (MSR_PENTIUM_4_EFSB_DRDY1, Msr); - @endcode - @note MSR_PENTIUM_4_EFSB_DRDY1 is defined as MSR_EFSB_DRDY1 in SDM. -**/ -#define MSR_PENTIUM_4_EFSB_DRDY1 0x000107D1 - - -/** - 3, 4. Shared. IFSB Latency Event Control Register (R/W) See Section 18.21, - "Performance Monitoring on 64-bit Intel Xeon Processor MP with Up to 8-MByte - L3 Cache" for details. - - @param ECX MSR_PENTIUM_4_IFSB_CTL6 (0x000107D2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_CTL6); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_CTL6, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_CTL6 is defined as MSR_IFSB_CTL6 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_CTL6 0x000107D2 - - -/** - 3, 4. Shared. IFSB Latency Event Counter Register (R/W) See Section 18.21, - "Performance Monitoring on 64-bit Intel Xeon Processor MP with Up to 8-MByte - L3 Cache.". - - @param ECX MSR_PENTIUM_4_IFSB_CNTR7 (0x000107D3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_CNTR7); - AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_CNTR7, Msr); - @endcode - @note MSR_PENTIUM_4_IFSB_CNTR7 is defined as MSR_IFSB_CNTR7 in SDM. -**/ -#define MSR_PENTIUM_4_IFSB_CNTR7 0x000107D3 - - -/** - 6. Shared. GBUSQ Event Control and Counter Register (R/W) See Section 18.21, - "Performance Monitoring on 64-bit Intel Xeon Processor MP with Up to 8-MByte - L3 Cache.". - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL0 (0x000107CC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL0); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL0, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL0 is defined as MSR_EMON_L3_CTR_CTL0 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL0 0x000107CC - - -/** - 6. Shared. GBUSQ Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL1 (0x000107CD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL1); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL1, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL1 is defined as MSR_EMON_L3_CTR_CTL1 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL1 0x000107CD - - -/** - 6. Shared. GSNPQ Event Control and Counter Register (R/W) See Section - 18.21, "Performance Monitoring on 64-bit Intel Xeon Processor MP with Up to - 8-MByte L3 Cache.". - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL2 (0x000107CE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL2); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL2, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL2 is defined as MSR_EMON_L3_CTR_CTL2 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL2 0x000107CE - - -/** - 6. Shared. GSNPQ Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL3 (0x000107CF) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL3); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL3, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL3 is defined as MSR_EMON_L3_CTR_CTL3 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL3 0x000107CF - - -/** - 6. Shared. FSB Event Control and Counter Register (R/W) See Section 18.21, - "Performance Monitoring on 64-bit Intel Xeon Processor MP with Up to 8-MByte - L3 Cache" for details. - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL4 (0x000107D0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL4); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL4, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL4 is defined as MSR_EMON_L3_CTR_CTL4 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL4 0x000107D0 - - -/** - 6. Shared. FSB Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL5 (0x000107D1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL5); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL5, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL5 is defined as MSR_EMON_L3_CTR_CTL5 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL5 0x000107D1 - - -/** - 6. Shared. FSB Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL6 (0x000107D2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL6); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL6, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL6 is defined as MSR_EMON_L3_CTR_CTL6 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL6 0x000107D2 - - -/** - 6. Shared. FSB Event Control and Counter Register (R/W). - - @param ECX MSR_PENTIUM_4_EMON_L3_CTR_CTL7 (0x000107D3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL7); - AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL7, Msr); - @endcode - @note MSR_PENTIUM_4_EMON_L3_CTR_CTL7 is defined as MSR_EMON_L3_CTR_CTL7 in SDM. -**/ -#define MSR_PENTIUM_4_EMON_L3_CTR_CTL7 0x000107D3 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h deleted file mode 100644 index 70d54c81e..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h +++ /dev/null @@ -1,684 +0,0 @@ -/** @file - MSR Definitions for Pentium M Processors. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.20. - -**/ - -#ifndef __PENTIUM_M_MSR_H__ -#define __PENTIUM_M_MSR_H__ - -#include - -/** - Is Pentium M Processors? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_PENTIUM_M_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x0D \ - ) \ - ) - -/** - See Section 35.22, "MSRs in Pentium Processors.". - - @param ECX MSR_PENTIUM_M_P5_MC_ADDR (0x00000000) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_P5_MC_ADDR); - AsmWriteMsr64 (MSR_PENTIUM_M_P5_MC_ADDR, Msr); - @endcode - @note MSR_PENTIUM_M_P5_MC_ADDR is defined as P5_MC_ADDR in SDM. -**/ -#define MSR_PENTIUM_M_P5_MC_ADDR 0x00000000 - - -/** - See Section 35.22, "MSRs in Pentium Processors.". - - @param ECX MSR_PENTIUM_M_P5_MC_TYPE (0x00000001) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_P5_MC_TYPE); - AsmWriteMsr64 (MSR_PENTIUM_M_P5_MC_TYPE, Msr); - @endcode - @note MSR_PENTIUM_M_P5_MC_TYPE is defined as P5_MC_TYPE in SDM. -**/ -#define MSR_PENTIUM_M_P5_MC_TYPE 0x00000001 - - -/** - Processor Hard Power-On Configuration (R/W) Enables and disables processor - features. (R) Indicates current processor configuration. - - @param ECX MSR_PENTIUM_M_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_PENTIUM_M_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_M_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_PENTIUM_M_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_PENTIUM_M_EBL_CR_POWERON is defined as MSR_EBL_CR_POWERON in SDM. -**/ -#define MSR_PENTIUM_M_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_PENTIUM_M_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] Data Error Checking Enable (R) 0 = Disabled Always 0 on the - /// Pentium M processor. - /// - UINT32 DataErrorCheckingEnable:1; - /// - /// [Bit 2] Response Error Checking Enable (R) 0 = Disabled Always 0 on - /// the Pentium M processor. - /// - UINT32 ResponseErrorCheckingEnable:1; - /// - /// [Bit 3] MCERR# Drive Enable (R) 0 = Disabled Always 0 on the Pentium - /// M processor. - /// - UINT32 MCERR_DriveEnable:1; - /// - /// [Bit 4] Address Parity Enable (R) 0 = Disabled Always 0 on the Pentium - /// M processor. - /// - UINT32 AddressParityEnable:1; - UINT32 Reserved2:2; - /// - /// [Bit 7] BINIT# Driver Enable (R) 1 = Enabled; 0 = Disabled Always 0 on - /// the Pentium M processor. - /// - UINT32 BINIT_DriverEnable:1; - /// - /// [Bit 8] Output Tri-state Enabled (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 OutputTriStateEnable:1; - /// - /// [Bit 9] Execute BIST (R/O) 1 = Enabled; 0 = Disabled. - /// - UINT32 ExecuteBIST:1; - /// - /// [Bit 10] MCERR# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled - /// Always 0 on the Pentium M processor. - /// - UINT32 MCERR_ObservationEnabled:1; - UINT32 Reserved3:1; - /// - /// [Bit 12] BINIT# Observation Enabled (R/O) 1 = Enabled; 0 = Disabled - /// Always 0 on the Pentium M processor. - /// - UINT32 BINIT_ObservationEnabled:1; - UINT32 Reserved4:1; - /// - /// [Bit 14] 1 MByte Power on Reset Vector (R/O) 1 = 1 MByte; 0 = 4 GBytes - /// Always 0 on the Pentium M processor. - /// - UINT32 ResetVector:1; - UINT32 Reserved5:1; - /// - /// [Bits 17:16] APIC Cluster ID (R/O) Always 00B on the Pentium M - /// processor. - /// - UINT32 APICClusterID:2; - /// - /// [Bit 18] System Bus Frequency (R/O) 1. = 100 MHz 2. = Reserved Always - /// 0 on the Pentium M processor. - /// - UINT32 SystemBusFrequency:1; - UINT32 Reserved6:1; - /// - /// [Bits 21:20] Symmetric Arbitration ID (R/O) Always 00B on the Pentium - /// M processor. - /// - UINT32 SymmetricArbitrationID:2; - /// - /// [Bits 26:22] Clock Frequency Ratio (R/O). - /// - UINT32 ClockFrequencyRatio:5; - UINT32 Reserved7:5; - UINT32 Reserved8:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_M_EBL_CR_POWERON_REGISTER; - - -/** - Last Branch Record n (R/W) One of 8 last branch record registers on the last - branch record stack: bits 31-0 hold the 'from' address and bits 63-32 hold - the to address. See also: - Last Branch Record Stack TOS at 1C9H - Section - 17.13, "Last Branch, Interrupt, and Exception Recording (Pentium M - Processors)". - - @param ECX MSR_PENTIUM_M_LASTBRANCH_n - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_LASTBRANCH_0); - AsmWriteMsr64 (MSR_PENTIUM_M_LASTBRANCH_0, Msr); - @endcode - @note MSR_PENTIUM_M_LASTBRANCH_0 is defined as MSR_LASTBRANCH_0 in SDM. - MSR_PENTIUM_M_LASTBRANCH_1 is defined as MSR_LASTBRANCH_1 in SDM. - MSR_PENTIUM_M_LASTBRANCH_2 is defined as MSR_LASTBRANCH_2 in SDM. - MSR_PENTIUM_M_LASTBRANCH_3 is defined as MSR_LASTBRANCH_3 in SDM. - MSR_PENTIUM_M_LASTBRANCH_4 is defined as MSR_LASTBRANCH_4 in SDM. - MSR_PENTIUM_M_LASTBRANCH_5 is defined as MSR_LASTBRANCH_5 in SDM. - MSR_PENTIUM_M_LASTBRANCH_6 is defined as MSR_LASTBRANCH_6 in SDM. - MSR_PENTIUM_M_LASTBRANCH_7 is defined as MSR_LASTBRANCH_7 in SDM. - @{ -**/ -#define MSR_PENTIUM_M_LASTBRANCH_0 0x00000040 -#define MSR_PENTIUM_M_LASTBRANCH_1 0x00000041 -#define MSR_PENTIUM_M_LASTBRANCH_2 0x00000042 -#define MSR_PENTIUM_M_LASTBRANCH_3 0x00000043 -#define MSR_PENTIUM_M_LASTBRANCH_4 0x00000044 -#define MSR_PENTIUM_M_LASTBRANCH_5 0x00000045 -#define MSR_PENTIUM_M_LASTBRANCH_6 0x00000046 -#define MSR_PENTIUM_M_LASTBRANCH_7 0x00000047 -/// @} - - -/** - Reserved. - - @param ECX MSR_PENTIUM_M_BBL_CR_CTL (0x00000119) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_BBL_CR_CTL); - AsmWriteMsr64 (MSR_PENTIUM_M_BBL_CR_CTL, Msr); - @endcode - @note MSR_PENTIUM_M_BBL_CR_CTL is defined as MSR_BBL_CR_CTL in SDM. -**/ -#define MSR_PENTIUM_M_BBL_CR_CTL 0x00000119 - - -/** - - - @param ECX MSR_PENTIUM_M_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_PENTIUM_M_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_M_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_PENTIUM_M_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_PENTIUM_M_BBL_CR_CTL3 is defined as MSR_BBL_CR_CTL3 in SDM. -**/ -#define MSR_PENTIUM_M_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_PENTIUM_M_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Hardware Enabled (RO) 1 = If the L2 is hardware-enabled 0 = - /// Indicates if the L2 is hardware-disabled. - /// - UINT32 L2HardwareEnabled:1; - UINT32 Reserved1:4; - /// - /// [Bit 5] ECC Check Enable (RO) This bit enables ECC checking on the - /// cache data bus. ECC is always generated on write cycles. 1. = Disabled - /// (default) 2. = Enabled For the Pentium M processor, ECC checking on - /// the cache data bus is always enabled. - /// - UINT32 ECCCheckEnable:1; - UINT32 Reserved2:2; - /// - /// [Bit 8] L2 Enabled (R/W) 1 = L2 cache has been initialized 0 = - /// Disabled (default) Until this bit is set the processor will not - /// respond to the WBINVD instruction or the assertion of the FLUSH# input. - /// - UINT32 L2Enabled:1; - UINT32 Reserved3:14; - /// - /// [Bit 23] L2 Not Present (RO) 1. = L2 Present 2. = L2 Not Present. - /// - UINT32 L2NotPresent:1; - UINT32 Reserved4:8; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_M_BBL_CR_CTL3_REGISTER; - - -/** - - - @param ECX MSR_PENTIUM_M_THERM2_CTL (0x0000019D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_THERM2_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_THERM2_CTL_REGISTER. - - Example usage - @code - MSR_PENTIUM_M_THERM2_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_M_THERM2_CTL); - AsmWriteMsr64 (MSR_PENTIUM_M_THERM2_CTL, Msr.Uint64); - @endcode - @note MSR_PENTIUM_M_THERM2_CTL is defined as MSR_THERM2_CTL in SDM. -**/ -#define MSR_PENTIUM_M_THERM2_CTL 0x0000019D - -/** - MSR information returned for MSR index #MSR_PENTIUM_M_THERM2_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bit 16] TM_SELECT (R/W) Mode of automatic thermal monitor: 1. = - /// Thermal Monitor 1 (thermally-initiated on-die modulation of the - /// stop-clock duty cycle) 2. = Thermal Monitor 2 (thermally-initiated - /// frequency transitions) If bit 3 of the IA32_MISC_ENABLE register is - /// cleared, TM_SELECT has no effect. Neither TM1 nor TM2 will be enabled. - /// - UINT32 TM_SELECT:1; - UINT32 Reserved2:15; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_M_THERM2_CTL_REGISTER; - - -/** - Enable Miscellaneous Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_PENTIUM_M_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_PENTIUM_M_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_PENTIUM_M_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_M_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_PENTIUM_M_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_PENTIUM_M_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_PENTIUM_M_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_PENTIUM_M_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:3; - /// - /// [Bit 3] Automatic Thermal Control Circuit Enable (R/W) 1 = Setting - /// this bit enables the thermal control circuit (TCC) portion of the - /// Intel Thermal Monitor feature. This allows processor clocks to be - /// automatically modulated based on the processor's thermal sensor - /// operation. 0 = Disabled (default). The automatic thermal control - /// circuit enable bit determines if the thermal control circuit (TCC) - /// will be activated when the processor's internal thermal sensor - /// determines the processor is about to exceed its maximum operating - /// temperature. When the TCC is activated and TM1 is enabled, the - /// processors clocks will be forced to a 50% duty cycle. BIOS must enable - /// this feature. The bit should not be confused with the on-demand - /// thermal control circuit enable bit. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Performance Monitoring Available (R) 1 = Performance - /// monitoring enabled 0 = Performance monitoring disabled. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:2; - /// - /// [Bit 10] FERR# Multiplexing Enable (R/W) 1 = FERR# asserted by the - /// processor to indicate a pending break event within the processor 0 = - /// Indicates compatible FERR# signaling behavior This bit must be set to - /// 1 to support XAPIC interrupt model usage. - /// **Branch Trace Storage Unavailable (RO)** 1 = Processor doesn't - /// support branch trace storage (BTS) 0 = BTS is supported - /// - UINT32 FERR:1; - /// - /// [Bit 11] Branch Trace Storage Unavailable (RO) - /// 1 = Processor doesn't support branch trace storage (BTS) - /// 0 = BTS is supported - /// - UINT32 BTS:1; - /// - /// [Bit 12] Processor Event Based Sampling Unavailable (RO) 1 = - /// Processor does not support processor event based sampling (PEBS); 0 = - /// PEBS is supported. The Pentium M processor does not support PEBS. - /// - UINT32 PEBS:1; - UINT32 Reserved5:3; - /// - /// [Bit 16] Enhanced Intel SpeedStep Technology Enable (R/W) 1 = - /// Enhanced Intel SpeedStep Technology enabled. On the Pentium M - /// processor, this bit may be configured to be read-only. - /// - UINT32 EIST:1; - UINT32 Reserved6:6; - /// - /// [Bit 23] xTPR Message Disable (R/W) When set to 1, xTPR messages are - /// disabled. xTPR messages are optional messages that allow the processor - /// to inform the chipset of its priority. The default is processor - /// specific. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_PENTIUM_M_IA32_MISC_ENABLE_REGISTER; - - -/** - Last Branch Record Stack TOS (R/W) Contains an index (bits 0-3) that points - to the MSR containing the most recent branch record. See also: - - MSR_LASTBRANCH_0_FROM_IP (at 40H) - Section 17.13, "Last Branch, Interrupt, - and Exception Recording (Pentium M Processors)". - - @param ECX MSR_PENTIUM_M_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_PENTIUM_M_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_PENTIUM_M_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_PENTIUM_M_LASTBRANCH_TOS 0x000001C9 - - -/** - Debug Control (R/W) Controls how several debug features are used. Bit - definitions are discussed in the referenced section. See Section 17.13, - "Last Branch, Interrupt, and Exception Recording (Pentium M Processors).". - - @param ECX MSR_PENTIUM_M_DEBUGCTLB (0x000001D9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_DEBUGCTLB); - AsmWriteMsr64 (MSR_PENTIUM_M_DEBUGCTLB, Msr); - @endcode - @note MSR_PENTIUM_M_DEBUGCTLB is defined as MSR_DEBUGCTLB in SDM. -**/ -#define MSR_PENTIUM_M_DEBUGCTLB 0x000001D9 - - -/** - Last Exception Record To Linear IP (R) This area contains a pointer to the - target of the last branch instruction that the processor executed prior to - the last exception that was generated or the last interrupt that was - handled. See Section 17.13, "Last Branch, Interrupt, and Exception Recording - (Pentium M Processors)" and Section 17.14.2, "Last Branch and Last Exception - MSRs.". - - @param ECX MSR_PENTIUM_M_LER_TO_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_LER_TO_LIP); - @endcode - @note MSR_PENTIUM_M_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_PENTIUM_M_LER_TO_LIP 0x000001DD - - -/** - Last Exception Record From Linear IP (R) Contains a pointer to the last - branch instruction that the processor executed prior to the last exception - that was generated or the last interrupt that was handled. See Section - 17.13, "Last Branch, Interrupt, and Exception Recording (Pentium M - Processors)" and Section 17.14.2, "Last Branch and Last Exception MSRs.". - - @param ECX MSR_PENTIUM_M_LER_FROM_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_LER_FROM_LIP); - @endcode - @note MSR_PENTIUM_M_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_PENTIUM_M_LER_FROM_LIP 0x000001DE - - -/** - See Section 15.3.2.1, "IA32_MCi_CTL MSRs.". - - @param ECX MSR_PENTIUM_M_MC4_CTL (0x0000040C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_CTL); - AsmWriteMsr64 (MSR_PENTIUM_M_MC4_CTL, Msr); - @endcode - @note MSR_PENTIUM_M_MC4_CTL is defined as MSR_MC4_CTL in SDM. -**/ -#define MSR_PENTIUM_M_MC4_CTL 0x0000040C - - -/** - See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.". - - @param ECX MSR_PENTIUM_M_MC4_STATUS (0x0000040D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_STATUS); - AsmWriteMsr64 (MSR_PENTIUM_M_MC4_STATUS, Msr); - @endcode - @note MSR_PENTIUM_M_MC4_STATUS is defined as MSR_MC4_STATUS in SDM. -**/ -#define MSR_PENTIUM_M_MC4_STATUS 0x0000040D - - -/** - See Section 15.3.2.3, "IA32_MCi_ADDR MSRs." The MSR_MC4_ADDR register is - either not implemented or contains no address if the ADDRV flag in the - MSR_MC4_STATUS register is clear. When not implemented in the processor, all - reads and writes to this MSR will cause a general-protection exception. - - @param ECX MSR_PENTIUM_M_MC4_ADDR (0x0000040E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_ADDR); - AsmWriteMsr64 (MSR_PENTIUM_M_MC4_ADDR, Msr); - @endcode - @note MSR_PENTIUM_M_MC4_ADDR is defined as MSR_MC4_ADDR in SDM. -**/ -#define MSR_PENTIUM_M_MC4_ADDR 0x0000040E - - -/** - See Section 15.3.2.1, "IA32_MCi_CTL MSRs.". - - @param ECX MSR_PENTIUM_M_MC3_CTL (0x00000410) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_CTL); - AsmWriteMsr64 (MSR_PENTIUM_M_MC3_CTL, Msr); - @endcode - @note MSR_PENTIUM_M_MC3_CTL is defined as MSR_MC3_CTL in SDM. -**/ -#define MSR_PENTIUM_M_MC3_CTL 0x00000410 - - -/** - See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.". - - @param ECX MSR_PENTIUM_M_MC3_STATUS (0x00000411) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_STATUS); - AsmWriteMsr64 (MSR_PENTIUM_M_MC3_STATUS, Msr); - @endcode - @note MSR_PENTIUM_M_MC3_STATUS is defined as MSR_MC3_STATUS in SDM. -**/ -#define MSR_PENTIUM_M_MC3_STATUS 0x00000411 - - -/** - See Section 15.3.2.3, "IA32_MCi_ADDR MSRs." The MSR_MC3_ADDR register is - either not implemented or contains no address if the ADDRV flag in the - MSR_MC3_STATUS register is clear. When not implemented in the processor, all - reads and writes to this MSR will cause a general-protection exception. - - @param ECX MSR_PENTIUM_M_MC3_ADDR (0x00000412) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_ADDR); - AsmWriteMsr64 (MSR_PENTIUM_M_MC3_ADDR, Msr); - @endcode - @note MSR_PENTIUM_M_MC3_ADDR is defined as MSR_MC3_ADDR in SDM. -**/ -#define MSR_PENTIUM_M_MC3_ADDR 0x00000412 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h deleted file mode 100644 index 9b2578bac..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - MSR Definitions for Pentium Processors. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.22. - -**/ - -#ifndef __PENTIUM_MSR_H__ -#define __PENTIUM_MSR_H__ - -#include - -/** - Is Pentium Processors? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_PENTIUM_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x05 && \ - ( \ - DisplayModel == 0x01 || \ - DisplayModel == 0x02 || \ - DisplayModel == 0x04 \ - ) \ - ) - -/** - See Section 15.10.2, "Pentium Processor Machine-Check Exception Handling.". - - @param ECX MSR_PENTIUM_P5_MC_ADDR (0x00000000) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_P5_MC_ADDR); - AsmWriteMsr64 (MSR_PENTIUM_P5_MC_ADDR, Msr); - @endcode - @note MSR_PENTIUM_P5_MC_ADDR is defined as P5_MC_ADDR in SDM. -**/ -#define MSR_PENTIUM_P5_MC_ADDR 0x00000000 - - -/** - See Section 15.10.2, "Pentium Processor Machine-Check Exception Handling.". - - @param ECX MSR_PENTIUM_P5_MC_TYPE (0x00000001) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_P5_MC_TYPE); - AsmWriteMsr64 (MSR_PENTIUM_P5_MC_TYPE, Msr); - @endcode - @note MSR_PENTIUM_P5_MC_TYPE is defined as P5_MC_TYPE in SDM. -**/ -#define MSR_PENTIUM_P5_MC_TYPE 0x00000001 - - -/** - See Section 17.15, "Time-Stamp Counter.". - - @param ECX MSR_PENTIUM_TSC (0x00000010) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_TSC); - AsmWriteMsr64 (MSR_PENTIUM_TSC, Msr); - @endcode - @note MSR_PENTIUM_TSC is defined as TSC in SDM. -**/ -#define MSR_PENTIUM_TSC 0x00000010 - - -/** - See Section 18.24.1, "Control and Event Select Register (CESR).". - - @param ECX MSR_PENTIUM_CESR (0x00000011) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_CESR); - AsmWriteMsr64 (MSR_PENTIUM_CESR, Msr); - @endcode - @note MSR_PENTIUM_CESR is defined as CESR in SDM. -**/ -#define MSR_PENTIUM_CESR 0x00000011 - - -/** - Section 18.24.3, "Events Counted.". - - @param ECX MSR_PENTIUM_CTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_PENTIUM_CTR0); - AsmWriteMsr64 (MSR_PENTIUM_CTR0, Msr); - @endcode - @note MSR_PENTIUM_CTR0 is defined as CTR0 in SDM. - MSR_PENTIUM_CTR1 is defined as CTR1 in SDM. - @{ -**/ -#define MSR_PENTIUM_CTR0 0x00000012 -#define MSR_PENTIUM_CTR1 0x00000013 -/// @} - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h deleted file mode 100644 index c8a0b971d..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h +++ /dev/null @@ -1,4796 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Sandy Bridge microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.9. - -**/ - -#ifndef __SANDY_BRIDGE_MSR_H__ -#define __SANDY_BRIDGE_MSR_H__ - -#include - -/** - Is Intel processors based on the Sandy Bridge microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_SANDY_BRIDGE_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x2A || \ - DisplayModel == 0x2D \ - ) \ - ) - -/** - Thread. SMI Counter (R/O). - - @param ECX MSR_SANDY_BRIDGE_SMI_COUNT (0x00000034) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_SMI_COUNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_SMI_COUNT_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_SMI_COUNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_SMI_COUNT); - @endcode - @note MSR_SANDY_BRIDGE_SMI_COUNT is defined as MSR_SMI_COUNT in SDM. -**/ -#define MSR_SANDY_BRIDGE_SMI_COUNT 0x00000034 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_SMI_COUNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] SMI Count (R/O) Count SMIs. - /// - UINT32 SMICount:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_SMI_COUNT_REGISTER; - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_SANDY_BRIDGE_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PLATFORM_INFO); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_SANDY_BRIDGE_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - UINT32 Reserved3:2; - UINT32 Reserved4:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved5:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PLATFORM_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. See http://biosbits.org. - - @param ECX MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power). for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0/C1 (no package C-sate support) 001b: C2 010b: C6 no retention 011b: - /// C6 retention 100b: C7 101b: C7s 111: No package C-state limit. Note: - /// This field cannot be used to limit package C-state to C3. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W) When set, will map - /// IO_read instructions sent to IO register specified by - /// MSR_PMG_IO_CAPTURE_BASE to MWAIT instructions. - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO) When set, lock bits 15:0 of this register - /// until next reset. - /// - UINT32 CFGLock:1; - UINT32 Reserved3:9; - /// - /// [Bit 25] C3 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C6/C7 requests to C3 based on uncore - /// auto-demote information. - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 state auto demotion enable (R/W) When set, the processor - /// will conditionally demote C3/C6/C7 requests to C1 based on uncore - /// auto-demote information. - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 undemotion (R/W) When set, enables undemotion from - /// demoted C3. - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 undemotion (R/W) When set, enables undemotion from - /// demoted C1. - /// - UINT32 C1Undemotion:1; - UINT32 Reserved4:3; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Core. Power Management IO Redirection in C-state (R/W) See - http://biosbits.org. - - @param ECX MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE (0x000000E4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE is defined as MSR_PMG_IO_CAPTURE_BASE in SDM. -**/ -#define MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE 0x000000E4 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] LVL_2 Base Address (R/W) Specifies the base address - /// visible to software for IO redirection. If IO MWAIT Redirection is - /// enabled, reads to this address will be consumed by the power - /// management logic and decoded to MWAIT instructions. When IO port - /// address redirection is enabled, this is the IO port address reported - /// to the OS/software. - /// - UINT32 Lvl2Base:16; - /// - /// [Bits 18:16] C-state Range (R/W) Specifies the encoding value of the - /// maximum C-State code name to be included when IO read to MWAIT - /// redirection is enabled by MSR_PKG_CST_CONFIG_CONTROL[bit10]: 000b - C3 - /// is the max C-State to include 001b - C6 is the max C-State to include - /// 010b - C7 is the max C-State to include. - /// - UINT32 CStateRange:3; - UINT32 Reserved1:13; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PMG_IO_CAPTURE_BASE_REGISTER; - - -/** - Core. AES Configuration (RW-L) Privileged post-BIOS agent must provide a #GP - handler to handle unsuccessful read of this MSR. - - @param ECX MSR_SANDY_BRIDGE_FEATURE_CONFIG (0x0000013C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_FEATURE_CONFIG); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_FEATURE_CONFIG, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_FEATURE_CONFIG is defined as MSR_FEATURE_CONFIG in SDM. -**/ -#define MSR_SANDY_BRIDGE_FEATURE_CONFIG 0x0000013C - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_FEATURE_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] AES Configuration (RW-L) Upon a successful read of this - /// MSR, the configuration of AES instruction set availability is as - /// follows: 11b: AES instructions are not available until next RESET. - /// otherwise, AES instructions are available. Note, AES instruction set - /// is not available if read is unsuccessful. If the configuration is not - /// 01b, AES instruction can be mis-configured if a privileged agent - /// unintentionally writes 11b. - /// - UINT32 AESConfiguration:2; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER; - - -/** - Core. See Table 35-2; If CPUID.0AH:EAX[15:8] = 8. - - @param ECX MSR_SANDY_BRIDGE_IA32_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4, Msr); - @endcode - @note MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4 is defined as IA32_PERFEVTSEL4 in SDM. - MSR_SANDY_BRIDGE_IA32_PERFEVTSEL5 is defined as IA32_PERFEVTSEL5 in SDM. - MSR_SANDY_BRIDGE_IA32_PERFEVTSEL6 is defined as IA32_PERFEVTSEL6 in SDM. - MSR_SANDY_BRIDGE_IA32_PERFEVTSEL7 is defined as IA32_PERFEVTSEL7 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4 0x0000018A -#define MSR_SANDY_BRIDGE_IA32_PERFEVTSEL5 0x0000018B -#define MSR_SANDY_BRIDGE_IA32_PERFEVTSEL6 0x0000018C -#define MSR_SANDY_BRIDGE_IA32_PERFEVTSEL7 0x0000018D -/// @} - - -/** - Package. - - @param ECX MSR_SANDY_BRIDGE_PERF_STATUS (0x00000198) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PERF_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PERF_STATUS_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PERF_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PERF_STATUS); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PERF_STATUS, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PERF_STATUS is defined as MSR_PERF_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_PERF_STATUS 0x00000198 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PERF_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - /// - /// [Bits 47:32] Core Voltage (R/O) P-state core voltage can be computed - /// by MSR_PERF_STATUS[37:32] * (float) 1/(2^13). - /// - UINT32 CoreVoltage:16; - UINT32 Reserved2:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PERF_STATUS_REGISTER; - - -/** - Thread. Clock Modulation (R/W) See Table 35-2 IA32_CLOCK_MODULATION MSR was - originally named IA32_THERM_CONTROL MSR. - - @param ECX MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION (0x0000019A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION is defined as IA32_CLOCK_MODULATION in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION 0x0000019A - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] On demand Clock Modulation Duty Cycle (R/W) In 6.25% - /// increment. - /// - UINT32 OnDemandClockModulationDutyCycle:4; - /// - /// [Bit 4] On demand Clock Modulation Enable (R/W). - /// - UINT32 OnDemandClockModulationEnable:1; - UINT32 Reserved1:27; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_CLOCK_MODULATION_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_SANDY_BRIDGE_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:6; - /// - /// [Bit 7] Thread. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved2:3; - /// - /// [Bit 11] Thread. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Thread. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - UINT32 Reserved3:3; - /// - /// [Bit 16] Package. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved4:1; - /// - /// [Bit 18] Thread. ENABLE MONITOR FSM. (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved5:3; - /// - /// [Bit 22] Thread. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Thread. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved6:8; - UINT32 Reserved7:2; - /// - /// [Bit 34] Thread. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved8:3; - /// - /// [Bit 38] Package. Turbo Mode Disable (R/W) When set to 1 on processors - /// that support Intel Turbo Boost Technology, the turbo mode feature is - /// disabled and the IDA_Enable feature flag will be clear (CPUID.06H: - /// EAX[1]=0). When set to a 0 on processors that support IDA, CPUID.06H: - /// EAX[1] reports the processor's support of turbo mode is enabled. Note: - /// the power-on default value is used by BIOS to detect hardware support - /// of turbo mode. If power-on default value is 1, turbo mode is available - /// in the processor. If power-on default value is 0, turbo mode is not - /// available. - /// - UINT32 TurboModeDisable:1; - UINT32 Reserved9:25; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_MISC_ENABLE_REGISTER; - - -/** - Unique. - - @param ECX MSR_SANDY_BRIDGE_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_SANDY_BRIDGE_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (R) The minimum temperature at which - /// PROCHOT# will be asserted. The value is degree C. - /// - UINT32 TemperatureTarget:8; - UINT32 Reserved2:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_TEMPERATURE_TARGET_REGISTER; - - -/** - Miscellaneous Feature Control (R/W). - - @param ECX MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL (0x000001A4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL is defined as MSR_MISC_FEATURE_CONTROL in SDM. -**/ -#define MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL 0x000001A4 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. L2 Hardware Prefetcher Disable (R/W) If 1, disables the - /// L2 hardware prefetcher, which fetches additional lines of code or data - /// into the L2 cache. - /// - UINT32 L2HardwarePrefetcherDisable:1; - /// - /// [Bit 1] Core. L2 Adjacent Cache Line Prefetcher Disable (R/W) If 1, - /// disables the adjacent cache line prefetcher, which fetches the cache - /// line that comprises a cache line pair (128 bytes). - /// - UINT32 L2AdjacentCacheLinePrefetcherDisable:1; - /// - /// [Bit 2] Core. DCU Hardware Prefetcher Disable (R/W) If 1, disables - /// the L1 data cache prefetcher, which fetches the next cache line into - /// L1 data cache. - /// - UINT32 DCUHardwarePrefetcherDisable:1; - /// - /// [Bit 3] Core. DCU IP Prefetcher Disable (R/W) If 1, disables the L1 - /// data cache IP prefetcher, which uses sequential load history (based on - /// instruction Pointer of previous loads) to determine whether to - /// prefetch additional lines. - /// - UINT32 DCUIPPrefetcherDisable:1; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_MISC_FEATURE_CONTROL_REGISTER; - - -/** - Thread. Offcore Response Event Select Register (R/W). - - @param ECX MSR_SANDY_BRIDGE_OFFCORE_RSP_0 (0x000001A6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_OFFCORE_RSP_0 is defined as MSR_OFFCORE_RSP_0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_OFFCORE_RSP_0 0x000001A6 - - -/** - Thread. Offcore Response Event Select Register (R/W). - - @param ECX MSR_SANDY_BRIDGE_OFFCORE_RSP_1 (0x000001A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_OFFCORE_RSP_1 is defined as MSR_OFFCORE_RSP_1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_OFFCORE_RSP_1 0x000001A7 - - -/** - See http://biosbits.org. - - @param ECX MSR_SANDY_BRIDGE_MISC_PWR_MGMT (0x000001AA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MISC_PWR_MGMT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_MISC_PWR_MGMT, Msr); - @endcode - @note MSR_SANDY_BRIDGE_MISC_PWR_MGMT is defined as MSR_MISC_PWR_MGMT in SDM. -**/ -#define MSR_SANDY_BRIDGE_MISC_PWR_MGMT 0x000001AA - - -/** - Thread. Last Branch Record Filtering Select Register (R/W) See Section - 17.7.2, "Filtering of Last Branch Records.". - - @param ECX MSR_SANDY_BRIDGE_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_LBR_SELECT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_LBR_SELECT_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_LBR_SELECT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_LBR_SELECT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_LBR_SELECT, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_SANDY_BRIDGE_LBR_SELECT 0x000001C8 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_LBR_SELECT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CPL_EQ_0. - /// - UINT32 CPL_EQ_0:1; - /// - /// [Bit 1] CPL_NEQ_0. - /// - UINT32 CPL_NEQ_0:1; - /// - /// [Bit 2] JCC. - /// - UINT32 JCC:1; - /// - /// [Bit 3] NEAR_REL_CALL. - /// - UINT32 NEAR_REL_CALL:1; - /// - /// [Bit 4] NEAR_IND_CALL. - /// - UINT32 NEAR_IND_CALL:1; - /// - /// [Bit 5] NEAR_RET. - /// - UINT32 NEAR_RET:1; - /// - /// [Bit 6] NEAR_IND_JMP. - /// - UINT32 NEAR_IND_JMP:1; - /// - /// [Bit 7] NEAR_REL_JMP. - /// - UINT32 NEAR_REL_JMP:1; - /// - /// [Bit 8] FAR_BRANCH. - /// - UINT32 FAR_BRANCH:1; - UINT32 Reserved1:23; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_LBR_SELECT_REGISTER; - - -/** - Thread. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-3) - that points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP (at 680H). - - @param ECX MSR_SANDY_BRIDGE_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_SANDY_BRIDGE_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_SANDY_BRIDGE_LASTBRANCH_TOS 0x000001C9 - - -/** - Thread. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_SANDY_BRIDGE_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LER_FROM_LIP); - @endcode - @note MSR_SANDY_BRIDGE_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_SANDY_BRIDGE_LER_FROM_LIP 0x000001DD - - -/** - Thread. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_SANDY_BRIDGE_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LER_TO_LIP); - @endcode - @note MSR_SANDY_BRIDGE_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_SANDY_BRIDGE_LER_TO_LIP 0x000001DE - - -/** - Core. See http://biosbits.org. - - @param ECX MSR_SANDY_BRIDGE_POWER_CTL (0x000001FC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_POWER_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_POWER_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_POWER_CTL is defined as MSR_POWER_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_POWER_CTL 0x000001FC - - -/** - Package. Always 0 (CMCI not supported). - - @param ECX MSR_SANDY_BRIDGE_IA32_MC4_CTL2 (0x00000284) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_MC4_CTL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_MC4_CTL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_IA32_MC4_CTL2 is defined as IA32_MC4_CTL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_MC4_CTL2 0x00000284 - - -/** - See Table 35-2. See Section 18.4.2, "Global Counter Control Facilities.". - - @param ECX MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS is defined as IA32_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS 0x0000038E - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Thread. Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Thread. Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Thread. Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - /// - /// [Bit 4] Core. Ovf_PMC4 (if CPUID.0AH:EAX[15:8] > 4). - /// - UINT32 Ovf_PMC4:1; - /// - /// [Bit 5] Core. Ovf_PMC5 (if CPUID.0AH:EAX[15:8] > 5). - /// - UINT32 Ovf_PMC5:1; - /// - /// [Bit 6] Core. Ovf_PMC6 (if CPUID.0AH:EAX[15:8] > 6). - /// - UINT32 Ovf_PMC6:1; - /// - /// [Bit 7] Core. Ovf_PMC7 (if CPUID.0AH:EAX[15:8] > 7). - /// - UINT32 Ovf_PMC7:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Thread. Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Thread. Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:26; - /// - /// [Bit 61] Thread. Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Thread. Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - /// - /// [Bit 63] Thread. CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Thread. See Table 35-2. See Section 18.4.2, "Global Counter Control - Facilities.". - - @param ECX MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL (0x0000038F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL is defined as IA32_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL 0x0000038F - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Set 1 to enable PMC0 to count. - /// - UINT32 PCM0_EN:1; - /// - /// [Bit 1] Thread. Set 1 to enable PMC1 to count. - /// - UINT32 PCM1_EN:1; - /// - /// [Bit 2] Thread. Set 1 to enable PMC2 to count. - /// - UINT32 PCM2_EN:1; - /// - /// [Bit 3] Thread. Set 1 to enable PMC3 to count. - /// - UINT32 PCM3_EN:1; - /// - /// [Bit 4] Core. Set 1 to enable PMC4 to count (if CPUID.0AH:EAX[15:8] > - /// 4). - /// - UINT32 PCM4_EN:1; - /// - /// [Bit 5] Core. Set 1 to enable PMC5 to count (if CPUID.0AH:EAX[15:8] > - /// 5). - /// - UINT32 PCM5_EN:1; - /// - /// [Bit 6] Core. Set 1 to enable PMC6 to count (if CPUID.0AH:EAX[15:8] > - /// 6). - /// - UINT32 PCM6_EN:1; - /// - /// [Bit 7] Core. Set 1 to enable PMC7 to count (if CPUID.0AH:EAX[15:8] > - /// 7). - /// - UINT32 PCM7_EN:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Set 1 to enable FixedCtr0 to count. - /// - UINT32 FIXED_CTR0:1; - /// - /// [Bit 33] Thread. Set 1 to enable FixedCtr1 to count. - /// - UINT32 FIXED_CTR1:1; - /// - /// [Bit 34] Thread. Set 1 to enable FixedCtr2 to count. - /// - UINT32 FIXED_CTR2:1; - UINT32 Reserved2:29; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_CTRL_REGISTER; - - -/** - See Table 35-2. See Section 18.4.2, "Global Counter Control Facilities.". - - @param ECX MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL is defined as IA32_PERF_GLOBAL_OVF_CTRL in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL 0x00000390 - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Set 1 to clear Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Thread. Set 1 to clear Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Thread. Set 1 to clear Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Thread. Set 1 to clear Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - /// - /// [Bit 4] Core. Set 1 to clear Ovf_PMC4 (if CPUID.0AH:EAX[15:8] > 4). - /// - UINT32 Ovf_PMC4:1; - /// - /// [Bit 5] Core. Set 1 to clear Ovf_PMC5 (if CPUID.0AH:EAX[15:8] > 5). - /// - UINT32 Ovf_PMC5:1; - /// - /// [Bit 6] Core. Set 1 to clear Ovf_PMC6 (if CPUID.0AH:EAX[15:8] > 6). - /// - UINT32 Ovf_PMC6:1; - /// - /// [Bit 7] Core. Set 1 to clear Ovf_PMC7 (if CPUID.0AH:EAX[15:8] > 7). - /// - UINT32 Ovf_PMC7:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Set 1 to clear Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Thread. Set 1 to clear Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Thread. Set 1 to clear Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:26; - /// - /// [Bit 61] Thread. Set 1 to clear Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Thread. Set 1 to clear Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - /// - /// [Bit 63] Thread. Set 1 to clear CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_OVF_CTRL_REGISTER; - - -/** - Thread. See Section 18.8.1.1, "Processor Event Based Sampling (PEBS).". - - @param ECX MSR_SANDY_BRIDGE_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PEBS_ENABLE); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_SANDY_BRIDGE_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS on IA32_PMC0. (R/W). - /// - UINT32 PEBS_EN_PMC0:1; - /// - /// [Bit 1] Enable PEBS on IA32_PMC1. (R/W). - /// - UINT32 PEBS_EN_PMC1:1; - /// - /// [Bit 2] Enable PEBS on IA32_PMC2. (R/W). - /// - UINT32 PEBS_EN_PMC2:1; - /// - /// [Bit 3] Enable PEBS on IA32_PMC3. (R/W). - /// - UINT32 PEBS_EN_PMC3:1; - UINT32 Reserved1:28; - /// - /// [Bit 32] Enable Load Latency on IA32_PMC0. (R/W). - /// - UINT32 LL_EN_PMC0:1; - /// - /// [Bit 33] Enable Load Latency on IA32_PMC1. (R/W). - /// - UINT32 LL_EN_PMC1:1; - /// - /// [Bit 34] Enable Load Latency on IA32_PMC2. (R/W). - /// - UINT32 LL_EN_PMC2:1; - /// - /// [Bit 35] Enable Load Latency on IA32_PMC3. (R/W). - /// - UINT32 LL_EN_PMC3:1; - UINT32 Reserved2:27; - /// - /// [Bit 63] Enable Precise Store. (R/W). - /// - UINT32 PS_EN:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PEBS_ENABLE_REGISTER; - - -/** - Thread. see See Section 18.8.1.2, "Load Latency Performance Monitoring - Facility.". - - @param ECX MSR_SANDY_BRIDGE_PEBS_LD_LAT (0x000003F6) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_LD_LAT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_LD_LAT_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PEBS_LD_LAT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PEBS_LD_LAT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PEBS_LD_LAT, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PEBS_LD_LAT is defined as MSR_PEBS_LD_LAT in SDM. -**/ -#define MSR_SANDY_BRIDGE_PEBS_LD_LAT 0x000003F6 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PEBS_LD_LAT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] Minimum threshold latency value of tagged load operation - /// that will be counted. (R/W). - /// - UINT32 MinimumThreshold:16; - UINT32 Reserved1:16; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PEBS_LD_LAT_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C3 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY (0x000003F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY is defined as MSR_PKG_C3_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY 0x000003F8 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C6 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C6 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY (0x000003F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY 0x000003F9 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C7 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C7 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY (0x000003FA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY is defined as MSR_PKG_C7_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY 0x000003FA - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C3 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C3 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY (0x000003FC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY is defined as MSR_CORE_C3_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY 0x000003FC - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C6 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C6 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY (0x000003FD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY is defined as MSR_CORE_C6_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY 0x000003FD - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C7 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C7 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY (0x000003FE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY is defined as MSR_CORE_C7_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY 0x000003FE - - -/** - Core. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.". - - @param ECX MSR_SANDY_BRIDGE_IA32_MC4_CTL (0x00000410) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_MC4_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_IA32_MC4_CTL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_IA32_MC4_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_MC4_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_MC4_CTL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_IA32_MC4_CTL is defined as IA32_MC4_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_MC4_CTL 0x00000410 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_IA32_MC4_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PCU Hardware Error (R/W) When set, enables signaling of PCU - /// hardware detected errors. - /// - UINT32 PCUHardwareError:1; - /// - /// [Bit 1] PCU Controller Error (R/W) When set, enables signaling of PCU - /// controller detected errors. - /// - UINT32 PCUControllerError:1; - /// - /// [Bit 2] PCU Firmware Error (R/W) When set, enables signaling of PCU - /// firmware detected errors. - /// - UINT32 PCUFirmwareError:1; - UINT32 Reserved1:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_IA32_MC4_CTL_REGISTER; - - -/** - Thread. Capability Reporting Register of EPT and VPID (R/O) See Table 35-2. - - @param ECX MSR_SANDY_BRIDGE_IA32_VMX_EPT_VPID_ENUM (0x0000048C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_VMX_EPT_VPID_ENUM); - @endcode - @note MSR_SANDY_BRIDGE_IA32_VMX_EPT_VPID_ENUM is defined as IA32_VMX_EPT_VPID_ENUM in SDM. -**/ -#define MSR_SANDY_BRIDGE_IA32_VMX_EPT_VPID_ENUM 0x0000048C - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O) See Section 14.9.1, - "RAPL Interfaces.". - - @param ECX MSR_SANDY_BRIDGE_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_RAPL_POWER_UNIT); - @endcode - @note MSR_SANDY_BRIDGE_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_RAPL_POWER_UNIT 0x00000606 - - -/** - Package. Package C3 Interrupt Response Limit (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. - - @param ECX MSR_SANDY_BRIDGE_PKGC3_IRTL (0x0000060A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC3_IRTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC3_IRTL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PKGC3_IRTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKGC3_IRTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKGC3_IRTL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PKGC3_IRTL is defined as MSR_PKGC3_IRTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKGC3_IRTL 0x0000060A - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PKGC3_IRTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C3 state. - /// - UINT32 TimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. The following time unit - /// encodings are supported: 000b: 1 ns 001b: 32 ns 010b: 1024 ns 011b: - /// 32768 ns 100b: 1048576 ns 101b: 33554432 ns. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PKGC3_IRTL_REGISTER; - - -/** - Package. Package C6 Interrupt Response Limit (R/W) This MSR defines the - budget allocated for the package to exit from C6 to a C0 state, where - interrupt request can be delivered to the core and serviced. Additional - core-exit latency amy be applicable depending on the actual C-state the core - is in. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. - - @param ECX MSR_SANDY_BRIDGE_PKGC6_IRTL (0x0000060B) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC6_IRTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC6_IRTL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PKGC6_IRTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKGC6_IRTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKGC6_IRTL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PKGC6_IRTL is defined as MSR_PKGC6_IRTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKGC6_IRTL 0x0000060B - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PKGC6_IRTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C6 state. - /// - UINT32 TimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. The following time unit - /// encodings are supported: 000b: 1 ns 001b: 32 ns 010b: 1024 ns 011b: - /// 32768 ns 100b: 1048576 ns 101b: 33554432 ns. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PKGC6_IRTL_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C2 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C2 states. Count at the same frequency as the TSC. - - @param ECX MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY (0x0000060D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY is defined as MSR_PKG_C2_RESIDENCY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY 0x0000060D - - -/** - Package. PKG RAPL Power Limit Control (R/W) See Section 14.9.3, "Package - RAPL Domain.". - - @param ECX MSR_SANDY_BRIDGE_PKG_POWER_LIMIT (0x00000610) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_LIMIT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_LIMIT, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_POWER_LIMIT is defined as MSR_PKG_POWER_LIMIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_POWER_LIMIT 0x00000610 - - -/** - Package. PKG Energy Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_SANDY_BRIDGE_PKG_ENERGY_STATUS (0x00000611) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_ENERGY_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_PKG_ENERGY_STATUS is defined as MSR_PKG_ENERGY_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_ENERGY_STATUS 0x00000611 - - -/** - Package. PKG RAPL Parameters (R/W) See Section 14.9.3, "Package RAPL - Domain.". - - @param ECX MSR_SANDY_BRIDGE_PKG_POWER_INFO (0x00000614) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_INFO); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_INFO, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PKG_POWER_INFO is defined as MSR_PKG_POWER_INFO in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_POWER_INFO 0x00000614 - - -/** - Package. PP0 RAPL Power Limit Control (R/W) See Section 14.9.4, "PP0/PP1 - RAPL Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP0_POWER_LIMIT (0x00000638) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_POWER_LIMIT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP0_POWER_LIMIT, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PP0_POWER_LIMIT is defined as MSR_PP0_POWER_LIMIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP0_POWER_LIMIT 0x00000638 - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_ENERGY_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP0_ENERGY_STATUS 0x00000639 - - -/** - Thread. Last Branch Record n From IP (R/W) One of sixteen pairs of last - branch record registers on the last branch record stack. This part of the - stack contains pointers to the source instruction. See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.7.1 and record format in Section - 17.4.8.1. - - @param ECX MSR_SANDY_BRIDGE_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_8_FROM_IP is defined as MSR_LASTBRANCH_8_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_9_FROM_IP is defined as MSR_LASTBRANCH_9_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_10_FROM_IP is defined as MSR_LASTBRANCH_10_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_11_FROM_IP is defined as MSR_LASTBRANCH_11_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_12_FROM_IP is defined as MSR_LASTBRANCH_12_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_13_FROM_IP is defined as MSR_LASTBRANCH_13_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_14_FROM_IP is defined as MSR_LASTBRANCH_14_FROM_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_15_FROM_IP is defined as MSR_LASTBRANCH_15_FROM_IP in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP 0x00000680 -#define MSR_SANDY_BRIDGE_LASTBRANCH_1_FROM_IP 0x00000681 -#define MSR_SANDY_BRIDGE_LASTBRANCH_2_FROM_IP 0x00000682 -#define MSR_SANDY_BRIDGE_LASTBRANCH_3_FROM_IP 0x00000683 -#define MSR_SANDY_BRIDGE_LASTBRANCH_4_FROM_IP 0x00000684 -#define MSR_SANDY_BRIDGE_LASTBRANCH_5_FROM_IP 0x00000685 -#define MSR_SANDY_BRIDGE_LASTBRANCH_6_FROM_IP 0x00000686 -#define MSR_SANDY_BRIDGE_LASTBRANCH_7_FROM_IP 0x00000687 -#define MSR_SANDY_BRIDGE_LASTBRANCH_8_FROM_IP 0x00000688 -#define MSR_SANDY_BRIDGE_LASTBRANCH_9_FROM_IP 0x00000689 -#define MSR_SANDY_BRIDGE_LASTBRANCH_10_FROM_IP 0x0000068A -#define MSR_SANDY_BRIDGE_LASTBRANCH_11_FROM_IP 0x0000068B -#define MSR_SANDY_BRIDGE_LASTBRANCH_12_FROM_IP 0x0000068C -#define MSR_SANDY_BRIDGE_LASTBRANCH_13_FROM_IP 0x0000068D -#define MSR_SANDY_BRIDGE_LASTBRANCH_14_FROM_IP 0x0000068E -#define MSR_SANDY_BRIDGE_LASTBRANCH_15_FROM_IP 0x0000068F -/// @} - - -/** - Thread. Last Branch Record n To IP (R/W) One of sixteen pairs of last branch - record registers on the last branch record stack. This part of the stack - contains pointers to the destination instruction. - - @param ECX MSR_SANDY_BRIDGE_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_8_TO_IP is defined as MSR_LASTBRANCH_8_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_9_TO_IP is defined as MSR_LASTBRANCH_9_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_10_TO_IP is defined as MSR_LASTBRANCH_10_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_11_TO_IP is defined as MSR_LASTBRANCH_11_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_12_TO_IP is defined as MSR_LASTBRANCH_12_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_13_TO_IP is defined as MSR_LASTBRANCH_13_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_14_TO_IP is defined as MSR_LASTBRANCH_14_TO_IP in SDM. - MSR_SANDY_BRIDGE_LASTBRANCH_15_TO_IP is defined as MSR_LASTBRANCH_15_TO_IP in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP 0x000006C0 -#define MSR_SANDY_BRIDGE_LASTBRANCH_1_TO_IP 0x000006C1 -#define MSR_SANDY_BRIDGE_LASTBRANCH_2_TO_IP 0x000006C2 -#define MSR_SANDY_BRIDGE_LASTBRANCH_3_TO_IP 0x000006C3 -#define MSR_SANDY_BRIDGE_LASTBRANCH_4_TO_IP 0x000006C4 -#define MSR_SANDY_BRIDGE_LASTBRANCH_5_TO_IP 0x000006C5 -#define MSR_SANDY_BRIDGE_LASTBRANCH_6_TO_IP 0x000006C6 -#define MSR_SANDY_BRIDGE_LASTBRANCH_7_TO_IP 0x000006C7 -#define MSR_SANDY_BRIDGE_LASTBRANCH_8_TO_IP 0x000006C8 -#define MSR_SANDY_BRIDGE_LASTBRANCH_9_TO_IP 0x000006C9 -#define MSR_SANDY_BRIDGE_LASTBRANCH_10_TO_IP 0x000006CA -#define MSR_SANDY_BRIDGE_LASTBRANCH_11_TO_IP 0x000006CB -#define MSR_SANDY_BRIDGE_LASTBRANCH_12_TO_IP 0x000006CC -#define MSR_SANDY_BRIDGE_LASTBRANCH_13_TO_IP 0x000006CD -#define MSR_SANDY_BRIDGE_LASTBRANCH_14_TO_IP 0x000006CE -#define MSR_SANDY_BRIDGE_LASTBRANCH_15_TO_IP 0x000006CF -/// @} - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT); - @endcode - @note MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C Maximum turbo ratio - /// limit of 5 core active. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C Maximum turbo ratio - /// limit of 6 core active. - /// - UINT32 Maximum6C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 7C Maximum turbo ratio - /// limit of 7 core active. - /// - UINT32 Maximum7C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for 8C Maximum turbo ratio - /// limit of 8 core active. - /// - UINT32 Maximum8C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. Uncore PMU global control. - - @param ECX MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL (0x00000391) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL is defined as MSR_UNC_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL 0x00000391 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Slice 0 select. - /// - UINT32 PMI_Sel_Slice0:1; - /// - /// [Bit 1] Slice 1 select. - /// - UINT32 PMI_Sel_Slice1:1; - /// - /// [Bit 2] Slice 2 select. - /// - UINT32 PMI_Sel_Slice2:1; - /// - /// [Bit 3] Slice 3 select. - /// - UINT32 PMI_Sel_Slice3:1; - /// - /// [Bit 4] Slice 4 select. - /// - UINT32 PMI_Sel_Slice4:1; - UINT32 Reserved1:14; - UINT32 Reserved2:10; - /// - /// [Bit 29] Enable all uncore counters. - /// - UINT32 EN:1; - /// - /// [Bit 30] Enable wake on PMI. - /// - UINT32 WakePMI:1; - /// - /// [Bit 31] Enable Freezing counter when overflow. - /// - UINT32 FREEZE:1; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_CTRL_REGISTER; - - -/** - Package. Uncore PMU main status. - - @param ECX MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS (0x00000392) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS is defined as MSR_UNC_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS 0x00000392 - -/** - MSR information returned for MSR index - #MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fixed counter overflowed. - /// - UINT32 Fixed:1; - /// - /// [Bit 1] An ARB counter overflowed. - /// - UINT32 ARB:1; - UINT32 Reserved1:1; - /// - /// [Bit 3] A CBox counter overflowed (on any slice). - /// - UINT32 CBox:1; - UINT32 Reserved2:28; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_UNC_PERF_GLOBAL_STATUS_REGISTER; - - -/** - Package. Uncore fixed counter control (R/W). - - @param ECX MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL (0x00000394) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL is defined as MSR_UNC_PERF_FIXED_CTRL in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL 0x00000394 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:20; - /// - /// [Bit 20] Enable overflow propagation. - /// - UINT32 EnableOverflow:1; - UINT32 Reserved2:1; - /// - /// [Bit 22] Enable counting. - /// - UINT32 EnableCounting:1; - UINT32 Reserved3:9; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTRL_REGISTER; - - -/** - Package. Uncore fixed counter. - - @param ECX MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR (0x00000395) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR is defined as MSR_UNC_PERF_FIXED_CTR in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR 0x00000395 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Current count. - /// - UINT32 CurrentCount:32; - /// - /// [Bits 47:32] Current count. - /// - UINT32 CurrentCountHi:16; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_UNC_PERF_FIXED_CTR_REGISTER; - - -/** - Package. Uncore C-Box configuration information (R/O). - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_CONFIG (0x00000396) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_CBO_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_UNC_CBO_CONFIG_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_UNC_CBO_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_CONFIG); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_CONFIG is defined as MSR_UNC_CBO_CONFIG in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_CONFIG 0x00000396 - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_UNC_CBO_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Report the number of C-Box units with performance counters, - /// including processor cores and processor graphics". - /// - UINT32 CBox:4; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_UNC_CBO_CONFIG_REGISTER; - - -/** - Package. Uncore Arb unit, performance counter 0. - - @param ECX MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0 (0x000003B0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0 is defined as MSR_UNC_ARB_PERFCTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0 0x000003B0 - - -/** - Package. Uncore Arb unit, performance counter 1. - - @param ECX MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1 (0x000003B1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1 is defined as MSR_UNC_ARB_PERFCTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1 0x000003B1 - - -/** - Package. Uncore Arb unit, counter 0 event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0 (0x000003B2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0 is defined as MSR_UNC_ARB_PERFEVTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0 0x000003B2 - - -/** - Package. Uncore Arb unit, counter 1 event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1 (0x000003B3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1 is defined as MSR_UNC_ARB_PERFEVTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1 0x000003B3 - - -/** - Package. Package C7 Interrupt Response Limit (R/W) This MSR defines the - budget allocated for the package to exit from C7 to a C0 state, where - interrupt request can be delivered to the core and serviced. Additional - core-exit latency amy be applicable depending on the actual C-state the core - is in. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. - - @param ECX MSR_SANDY_BRIDGE_PKGC7_IRTL (0x0000060C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC7_IRTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PKGC7_IRTL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PKGC7_IRTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKGC7_IRTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKGC7_IRTL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PKGC7_IRTL is defined as MSR_PKGC7_IRTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKGC7_IRTL 0x0000060C - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PKGC7_IRTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] Interrupt response time limit (R/W) Specifies the limit - /// that should be used to decide if the package should be put into a - /// package C7 state. - /// - UINT32 TimeLimit:10; - /// - /// [Bits 12:10] Time Unit (R/W) Specifies the encoding value of time - /// unit of the interrupt response time limit. The following time unit - /// encodings are supported: 000b: 1 ns 001b: 32 ns 010b: 1024 ns 011b: - /// 32768 ns 100b: 1048576 ns 101b: 33554432 ns. - /// - UINT32 TimeUnit:3; - UINT32 Reserved1:2; - /// - /// [Bit 15] Valid (R/W) Indicates whether the values in bits 12:0 are - /// valid and can be used by the processor for package C-sate management. - /// - UINT32 Valid:1; - UINT32 Reserved2:16; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PKGC7_IRTL_REGISTER; - - -/** - Package. PP0 Balance Policy (R/W) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP0_POLICY (0x0000063A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_POLICY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP0_POLICY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PP0_POLICY is defined as MSR_PP0_POLICY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP0_POLICY 0x0000063A - - -/** - Package. PP1 RAPL Power Limit Control (R/W) See Section 14.9.4, "PP0/PP1 - RAPL Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP1_POWER_LIMIT (0x00000640) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_POWER_LIMIT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP1_POWER_LIMIT, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PP1_POWER_LIMIT is defined as MSR_PP1_POWER_LIMIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP1_POWER_LIMIT 0x00000640 - - -/** - Package. PP1 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP1_ENERGY_STATUS (0x00000641) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_ENERGY_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_PP1_ENERGY_STATUS is defined as MSR_PP1_ENERGY_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP1_ENERGY_STATUS 0x00000641 - - -/** - Package. PP1 Balance Policy (R/W) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_SANDY_BRIDGE_PP1_POLICY (0x00000642) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_POLICY); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP1_POLICY, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PP1_POLICY is defined as MSR_PP1_POLICY in SDM. -**/ -#define MSR_SANDY_BRIDGE_PP1_POLICY 0x00000642 - - -/** - Package. Uncore C-Box 0, counter n event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0 is defined as MSR_UNC_CBO_0_PERFEVTSEL0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1 is defined as MSR_UNC_CBO_0_PERFEVTSEL1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL2 is defined as MSR_UNC_CBO_0_PERFEVTSEL2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL3 is defined as MSR_UNC_CBO_0_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0 0x00000700 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1 0x00000701 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL2 0x00000702 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL3 0x00000703 -/// @} - - -/** - Package. Uncore C-Box n, unit status for counter 0-3. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_n_UNIT_STATUS - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_UNIT_STATUS); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_UNIT_STATUS, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_0_UNIT_STATUS is defined as MSR_UNC_CBO_0_UNIT_STATUS in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_UNIT_STATUS is defined as MSR_UNC_CBO_1_UNIT_STATUS in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_UNIT_STATUS is defined as MSR_UNC_CBO_2_UNIT_STATUS in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_UNIT_STATUS is defined as MSR_UNC_CBO_3_UNIT_STATUS in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_UNIT_STATUS is defined as MSR_UNC_CBO_4_UNIT_STATUS in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_0_UNIT_STATUS 0x00000705 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_UNIT_STATUS 0x00000715 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_UNIT_STATUS 0x00000725 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_UNIT_STATUS 0x00000735 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_UNIT_STATUS 0x00000745 -/// @} - - -/** - Package. Uncore C-Box 0, performance counter n. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0 is defined as MSR_UNC_CBO_0_PERFCTR0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1 is defined as MSR_UNC_CBO_0_PERFCTR1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR2 is defined as MSR_UNC_CBO_0_PERFCTR2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR3 is defined as MSR_UNC_CBO_0_PERFCTR3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0 0x00000706 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1 0x00000707 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR2 0x00000708 -#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR3 0x00000709 -/// @} - - -/** - Package. Uncore C-Box 1, counter n event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0 is defined as MSR_UNC_CBO_1_PERFEVTSEL0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1 is defined as MSR_UNC_CBO_1_PERFEVTSEL1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL2 is defined as MSR_UNC_CBO_1_PERFEVTSEL2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL3 is defined as MSR_UNC_CBO_1_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0 0x00000710 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1 0x00000711 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL2 0x00000712 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL3 0x00000713 -/// @} - - -/** - Package. Uncore C-Box 1, performance counter n. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0 is defined as MSR_UNC_CBO_1_PERFCTR0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1 is defined as MSR_UNC_CBO_1_PERFCTR1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR2 is defined as MSR_UNC_CBO_1_PERFCTR2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR3 is defined as MSR_UNC_CBO_1_PERFCTR3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0 0x00000716 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1 0x00000717 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR2 0x00000718 -#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR3 0x00000719 -/// @} - - -/** - Package. Uncore C-Box 2, counter n event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0 is defined as MSR_UNC_CBO_2_PERFEVTSEL0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1 is defined as MSR_UNC_CBO_2_PERFEVTSEL1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL2 is defined as MSR_UNC_CBO_2_PERFEVTSEL2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL3 is defined as MSR_UNC_CBO_2_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0 0x00000720 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1 0x00000721 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL2 0x00000722 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL3 0x00000723 -/// @} - - -/** - Package. Uncore C-Box 2, performance counter n. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0 is defined as MSR_UNC_CBO_2_PERFCTR0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1 is defined as MSR_UNC_CBO_2_PERFCTR1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR2 is defined as MSR_UNC_CBO_2_PERFCTR2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR3 is defined as MSR_UNC_CBO_2_PERFCTR3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0 0x00000726 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1 0x00000727 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR2 0x00000728 -#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR3 0x00000729 -/// @} - - -/** - Package. Uncore C-Box 3, counter n event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0 is defined as MSR_UNC_CBO_3_PERFEVTSEL0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1 is defined as MSR_UNC_CBO_3_PERFEVTSEL1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL2 is defined as MSR_UNC_CBO_3_PERFEVTSEL2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL3 is defined as MSR_UNC_CBO_3_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0 0x00000730 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1 0x00000731 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL2 0x00000732 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL3 0x00000733 -/// @} - - -/** - Package. Uncore C-Box 3, performance counter n. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0 is defined as MSR_UNC_CBO_3_PERFCTR0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1 is defined as MSR_UNC_CBO_3_PERFCTR1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR2 is defined as MSR_UNC_CBO_3_PERFCTR2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR3 is defined as MSR_UNC_CBO_3_PERFCTR3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0 0x00000736 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1 0x00000737 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR2 0x00000738 -#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR3 0x00000739 -/// @} - - -/** - Package. Uncore C-Box 4, counter n event select MSR. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL0 is defined as MSR_UNC_CBO_4_PERFEVTSEL0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL1 is defined as MSR_UNC_CBO_4_PERFEVTSEL1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL2 is defined as MSR_UNC_CBO_4_PERFEVTSEL2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL3 is defined as MSR_UNC_CBO_4_PERFEVTSEL3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL0 0x00000740 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL1 0x00000741 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL2 0x00000742 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFEVTSEL3 0x00000743 -/// @} - - -/** - Package. Uncore C-Box 4, performance counter n. - - @param ECX MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR0 is defined as MSR_UNC_CBO_4_PERFCTR0 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR1 is defined as MSR_UNC_CBO_4_PERFCTR1 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR2 is defined as MSR_UNC_CBO_4_PERFCTR2 in SDM. - MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR3 is defined as MSR_UNC_CBO_4_PERFCTR3 in SDM. - @{ -**/ -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR0 0x00000746 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR1 0x00000747 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR2 0x00000748 -#define MSR_SANDY_BRIDGE_UNC_CBO_4_PERFCTR3 0x00000749 -/// @} - - -/** - Package. MC Bank Error Configuration (R/W). - - @param ECX MSR_SANDY_BRIDGE_ERROR_CONTROL (0x0000017F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_ERROR_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_ERROR_CONTROL_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_ERROR_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_ERROR_CONTROL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_ERROR_CONTROL, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_ERROR_CONTROL is defined as MSR_ERROR_CONTROL in SDM. -**/ -#define MSR_SANDY_BRIDGE_ERROR_CONTROL 0x0000017F - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_ERROR_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:1; - /// - /// [Bit 1] MemError Log Enable (R/W) When set, enables IMC status bank - /// to log additional info in bits 36:32. - /// - UINT32 MemErrorLogEnable:1; - UINT32 Reserved2:30; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_ERROR_CONTROL_REGISTER; - - -/** - Package. - - @param ECX MSR_SANDY_BRIDGE_PEBS_NUM_ALT (0x0000039C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_NUM_ALT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SANDY_BRIDGE_PEBS_NUM_ALT_REGISTER. - - Example usage - @code - MSR_SANDY_BRIDGE_PEBS_NUM_ALT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PEBS_NUM_ALT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PEBS_NUM_ALT, Msr.Uint64); - @endcode - @note MSR_SANDY_BRIDGE_PEBS_NUM_ALT is defined as MSR_PEBS_NUM_ALT in SDM. -**/ -#define MSR_SANDY_BRIDGE_PEBS_NUM_ALT 0x0000039C - -/** - MSR information returned for MSR index #MSR_SANDY_BRIDGE_PEBS_NUM_ALT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] ENABLE_PEBS_NUM_ALT (RW) Write 1 to enable alternate PEBS - /// counting logic for specific events requiring additional configuration, - /// see Table 19-15. - /// - UINT32 ENABLE_PEBS_NUM_ALT:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SANDY_BRIDGE_PEBS_NUM_ALT_REGISTER; - - -/** - Package. Package RAPL Perf Status (R/O). - - @param ECX MSR_SANDY_BRIDGE_PKG_PERF_STATUS (0x00000613) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_PERF_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_PKG_PERF_STATUS is defined as MSR_PKG_PERF_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_PKG_PERF_STATUS 0x00000613 - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_SANDY_BRIDGE_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_ENERGY_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_DRAM_ENERGY_STATUS 0x00000619 - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_SANDY_BRIDGE_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_PERF_STATUS); - @endcode - @note MSR_SANDY_BRIDGE_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_SANDY_BRIDGE_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_SANDY_BRIDGE_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_SANDY_BRIDGE_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_SANDY_BRIDGE_DRAM_POWER_INFO 0x0000061C - - -/** - Package. Uncore U-box UCLK fixed counter control. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL (0x00000C08) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL is defined as MSR_U_PMON_UCLK_FIXED_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL 0x00000C08 - - -/** - Package. Uncore U-box UCLK fixed counter. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR (0x00000C09) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR is defined as MSR_U_PMON_UCLK_FIXED_CTR in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR 0x00000C09 - - -/** - Package. Uncore U-box perfmon event select for U-box counter 0. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0 (0x00000C10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0 is defined as MSR_U_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0 0x00000C10 - - -/** - Package. Uncore U-box perfmon event select for U-box counter 1. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1 (0x00000C11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1 is defined as MSR_U_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1 0x00000C11 - - -/** - Package. Uncore U-box perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_CTR0 (0x00000C16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_CTR0 is defined as MSR_U_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_CTR0 0x00000C16 - - -/** - Package. Uncore U-box perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_U_PMON_CTR1 (0x00000C17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_U_PMON_CTR1 is defined as MSR_U_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_U_PMON_CTR1 0x00000C17 - - -/** - Package. Uncore PCU perfmon for PCU-box-wide control. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL (0x00000C24) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL is defined as MSR_PCU_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL 0x00000C24 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 0. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0 (0x00000C30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0 is defined as MSR_PCU_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0 0x00000C30 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 1. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1 (0x00000C31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1 is defined as MSR_PCU_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1 0x00000C31 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 2. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2 (0x00000C32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2 is defined as MSR_PCU_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2 0x00000C32 - - -/** - Package. Uncore PCU perfmon event select for PCU counter 3. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3 (0x00000C33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3 is defined as MSR_PCU_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3 0x00000C33 - - -/** - Package. Uncore PCU perfmon box-wide filter. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER (0x00000C34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER is defined as MSR_PCU_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER 0x00000C34 - - -/** - Package. Uncore PCU perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_CTR0 (0x00000C36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_CTR0 is defined as MSR_PCU_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_CTR0 0x00000C36 - - -/** - Package. Uncore PCU perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_CTR1 (0x00000C37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_CTR1 is defined as MSR_PCU_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_CTR1 0x00000C37 - - -/** - Package. Uncore PCU perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_CTR2 (0x00000C38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_CTR2 is defined as MSR_PCU_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_CTR2 0x00000C38 - - -/** - Package. Uncore PCU perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_PCU_PMON_CTR3 (0x00000C39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_PCU_PMON_CTR3 is defined as MSR_PCU_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_PCU_PMON_CTR3 0x00000C39 - - -/** - Package. Uncore C-box 0 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL (0x00000D04) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL is defined as MSR_C0_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL 0x00000D04 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0 (0x00000D10) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0 is defined as MSR_C0_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0 0x00000D10 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1 (0x00000D11) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1 is defined as MSR_C0_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1 0x00000D11 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2 (0x00000D12) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2 is defined as MSR_C0_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2 0x00000D12 - - -/** - Package. Uncore C-box 0 perfmon event select for C-box 0 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3 (0x00000D13) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3 is defined as MSR_C0_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3 0x00000D13 - - -/** - Package. Uncore C-box 0 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER (0x00000D14) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER is defined as MSR_C0_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER 0x00000D14 - - -/** - Package. Uncore C-box 0 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_CTR0 (0x00000D16) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_CTR0 is defined as MSR_C0_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_CTR0 0x00000D16 - - -/** - Package. Uncore C-box 0 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_CTR1 (0x00000D17) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_CTR1 is defined as MSR_C0_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_CTR1 0x00000D17 - - -/** - Package. Uncore C-box 0 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_CTR2 (0x00000D18) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_CTR2 is defined as MSR_C0_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_CTR2 0x00000D18 - - -/** - Package. Uncore C-box 0 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C0_PMON_CTR3 (0x00000D19) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C0_PMON_CTR3 is defined as MSR_C0_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C0_PMON_CTR3 0x00000D19 - - -/** - Package. Uncore C-box 1 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL (0x00000D24) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL is defined as MSR_C1_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL 0x00000D24 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0 (0x00000D30) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0 is defined as MSR_C1_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0 0x00000D30 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1 (0x00000D31) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1 is defined as MSR_C1_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1 0x00000D31 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2 (0x00000D32) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2 is defined as MSR_C1_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2 0x00000D32 - - -/** - Package. Uncore C-box 1 perfmon event select for C-box 1 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3 (0x00000D33) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3 is defined as MSR_C1_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3 0x00000D33 - - -/** - Package. Uncore C-box 1 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER (0x00000D34) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER is defined as MSR_C1_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER 0x00000D34 - - -/** - Package. Uncore C-box 1 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_CTR0 (0x00000D36) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_CTR0 is defined as MSR_C1_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_CTR0 0x00000D36 - - -/** - Package. Uncore C-box 1 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_CTR1 (0x00000D37) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_CTR1 is defined as MSR_C1_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_CTR1 0x00000D37 - - -/** - Package. Uncore C-box 1 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_CTR2 (0x00000D38) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_CTR2 is defined as MSR_C1_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_CTR2 0x00000D38 - - -/** - Package. Uncore C-box 1 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C1_PMON_CTR3 (0x00000D39) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C1_PMON_CTR3 is defined as MSR_C1_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C1_PMON_CTR3 0x00000D39 - - -/** - Package. Uncore C-box 2 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL (0x00000D44) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL is defined as MSR_C2_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL 0x00000D44 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0 (0x00000D50) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0 is defined as MSR_C2_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0 0x00000D50 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1 (0x00000D51) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1 is defined as MSR_C2_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1 0x00000D51 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2 (0x00000D52) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2 is defined as MSR_C2_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2 0x00000D52 - - -/** - Package. Uncore C-box 2 perfmon event select for C-box 2 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3 (0x00000D53) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3 is defined as MSR_C2_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3 0x00000D53 - - -/** - Package. Uncore C-box 2 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER (0x00000D54) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER is defined as MSR_C2_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER 0x00000D54 - - -/** - Package. Uncore C-box 2 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_CTR0 (0x00000D56) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_CTR0 is defined as MSR_C2_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_CTR0 0x00000D56 - - -/** - Package. Uncore C-box 2 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_CTR1 (0x00000D57) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_CTR1 is defined as MSR_C2_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_CTR1 0x00000D57 - - -/** - Package. Uncore C-box 2 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_CTR2 (0x00000D58) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_CTR2 is defined as MSR_C2_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_CTR2 0x00000D58 - - -/** - Package. Uncore C-box 2 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C2_PMON_CTR3 (0x00000D59) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C2_PMON_CTR3 is defined as MSR_C2_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C2_PMON_CTR3 0x00000D59 - - -/** - Package. Uncore C-box 3 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL (0x00000D64) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL is defined as MSR_C3_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL 0x00000D64 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0 (0x00000D70) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0 is defined as MSR_C3_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0 0x00000D70 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1 (0x00000D71) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1 is defined as MSR_C3_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1 0x00000D71 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2 (0x00000D72) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2 is defined as MSR_C3_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2 0x00000D72 - - -/** - Package. Uncore C-box 3 perfmon event select for C-box 3 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3 (0x00000D73) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3 is defined as MSR_C3_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3 0x00000D73 - - -/** - Package. Uncore C-box 3 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER (0x00000D74) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER is defined as MSR_C3_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER 0x00000D74 - - -/** - Package. Uncore C-box 3 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_CTR0 (0x00000D76) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_CTR0 is defined as MSR_C3_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_CTR0 0x00000D76 - - -/** - Package. Uncore C-box 3 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_CTR1 (0x00000D77) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_CTR1 is defined as MSR_C3_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_CTR1 0x00000D77 - - -/** - Package. Uncore C-box 3 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_CTR2 (0x00000D78) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_CTR2 is defined as MSR_C3_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_CTR2 0x00000D78 - - -/** - Package. Uncore C-box 3 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C3_PMON_CTR3 (0x00000D79) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C3_PMON_CTR3 is defined as MSR_C3_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C3_PMON_CTR3 0x00000D79 - - -/** - Package. Uncore C-box 4 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL (0x00000D84) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL is defined as MSR_C4_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL 0x00000D84 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0 (0x00000D90) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0 is defined as MSR_C4_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0 0x00000D90 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1 (0x00000D91) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1 is defined as MSR_C4_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1 0x00000D91 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2 (0x00000D92) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2 is defined as MSR_C4_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2 0x00000D92 - - -/** - Package. Uncore C-box 4 perfmon event select for C-box 4 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3 (0x00000D93) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3 is defined as MSR_C4_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3 0x00000D93 - - -/** - Package. Uncore C-box 4 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER (0x00000D94) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER is defined as MSR_C4_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER 0x00000D94 - - -/** - Package. Uncore C-box 4 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_CTR0 (0x00000D96) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_CTR0 is defined as MSR_C4_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_CTR0 0x00000D96 - - -/** - Package. Uncore C-box 4 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_CTR1 (0x00000D97) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_CTR1 is defined as MSR_C4_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_CTR1 0x00000D97 - - -/** - Package. Uncore C-box 4 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_CTR2 (0x00000D98) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_CTR2 is defined as MSR_C4_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_CTR2 0x00000D98 - - -/** - Package. Uncore C-box 4 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C4_PMON_CTR3 (0x00000D99) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C4_PMON_CTR3 is defined as MSR_C4_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C4_PMON_CTR3 0x00000D99 - - -/** - Package. Uncore C-box 5 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL (0x00000DA4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL is defined as MSR_C5_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL 0x00000DA4 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0 (0x00000DB0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0 is defined as MSR_C5_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0 0x00000DB0 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1 (0x00000DB1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1 is defined as MSR_C5_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1 0x00000DB1 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2 (0x00000DB2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2 is defined as MSR_C5_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2 0x00000DB2 - - -/** - Package. Uncore C-box 5 perfmon event select for C-box 5 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3 (0x00000DB3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3 is defined as MSR_C5_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3 0x00000DB3 - - -/** - Package. Uncore C-box 5 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER (0x00000DB4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER is defined as MSR_C5_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER 0x00000DB4 - - -/** - Package. Uncore C-box 5 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_CTR0 (0x00000DB6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_CTR0 is defined as MSR_C5_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_CTR0 0x00000DB6 - - -/** - Package. Uncore C-box 5 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_CTR1 (0x00000DB7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_CTR1 is defined as MSR_C5_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_CTR1 0x00000DB7 - - -/** - Package. Uncore C-box 5 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_CTR2 (0x00000DB8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_CTR2 is defined as MSR_C5_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_CTR2 0x00000DB8 - - -/** - Package. Uncore C-box 5 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C5_PMON_CTR3 (0x00000DB9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C5_PMON_CTR3 is defined as MSR_C5_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C5_PMON_CTR3 0x00000DB9 - - -/** - Package. Uncore C-box 6 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL (0x00000DC4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL is defined as MSR_C6_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL 0x00000DC4 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0 (0x00000DD0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0 is defined as MSR_C6_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0 0x00000DD0 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1 (0x00000DD1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1 is defined as MSR_C6_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1 0x00000DD1 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2 (0x00000DD2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2 is defined as MSR_C6_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2 0x00000DD2 - - -/** - Package. Uncore C-box 6 perfmon event select for C-box 6 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3 (0x00000DD3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3 is defined as MSR_C6_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3 0x00000DD3 - - -/** - Package. Uncore C-box 6 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER (0x00000DD4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER is defined as MSR_C6_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER 0x00000DD4 - - -/** - Package. Uncore C-box 6 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_CTR0 (0x00000DD6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_CTR0 is defined as MSR_C6_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_CTR0 0x00000DD6 - - -/** - Package. Uncore C-box 6 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_CTR1 (0x00000DD7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_CTR1 is defined as MSR_C6_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_CTR1 0x00000DD7 - - -/** - Package. Uncore C-box 6 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_CTR2 (0x00000DD8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_CTR2 is defined as MSR_C6_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_CTR2 0x00000DD8 - - -/** - Package. Uncore C-box 6 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C6_PMON_CTR3 (0x00000DD9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C6_PMON_CTR3 is defined as MSR_C6_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C6_PMON_CTR3 0x00000DD9 - - -/** - Package. Uncore C-box 7 perfmon local box wide control. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL (0x00000DE4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL is defined as MSR_C7_PMON_BOX_CTL in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL 0x00000DE4 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 0. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0 (0x00000DF0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0 is defined as MSR_C7_PMON_EVNTSEL0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0 0x00000DF0 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 1. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1 (0x00000DF1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1 is defined as MSR_C7_PMON_EVNTSEL1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1 0x00000DF1 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 2. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2 (0x00000DF2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2 is defined as MSR_C7_PMON_EVNTSEL2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2 0x00000DF2 - - -/** - Package. Uncore C-box 7 perfmon event select for C-box 7 counter 3. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3 (0x00000DF3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3 is defined as MSR_C7_PMON_EVNTSEL3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3 0x00000DF3 - - -/** - Package. Uncore C-box 7 perfmon box wide filter. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER (0x00000DF4) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER is defined as MSR_C7_PMON_BOX_FILTER in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER 0x00000DF4 - - -/** - Package. Uncore C-box 7 perfmon counter 0. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_CTR0 (0x00000DF6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR0); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR0, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_CTR0 is defined as MSR_C7_PMON_CTR0 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_CTR0 0x00000DF6 - - -/** - Package. Uncore C-box 7 perfmon counter 1. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_CTR1 (0x00000DF7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR1); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR1, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_CTR1 is defined as MSR_C7_PMON_CTR1 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_CTR1 0x00000DF7 - - -/** - Package. Uncore C-box 7 perfmon counter 2. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_CTR2 (0x00000DF8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR2); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR2, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_CTR2 is defined as MSR_C7_PMON_CTR2 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_CTR2 0x00000DF8 - - -/** - Package. Uncore C-box 7 perfmon counter 3. - - @param ECX MSR_SANDY_BRIDGE_C7_PMON_CTR3 (0x00000DF9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR3); - AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR3, Msr); - @endcode - @note MSR_SANDY_BRIDGE_C7_PMON_CTR3 is defined as MSR_C7_PMON_CTR3 in SDM. -**/ -#define MSR_SANDY_BRIDGE_C7_PMON_CTR3 0x00000DF9 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h deleted file mode 100644 index ec09bf3c1..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h +++ /dev/null @@ -1,1570 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Silvermont microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.4. - -**/ - -#ifndef __SILVERMONT_MSR_H__ -#define __SILVERMONT_MSR_H__ - -#include - -/** - Is Intel processors based on the Silvermont microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_SILVERMONT_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x37 || \ - DisplayModel == 0x4A || \ - DisplayModel == 0x4D || \ - DisplayModel == 0x5A || \ - DisplayModel == 0x5D \ - ) \ - ) - -/** - Module. Model Specific Platform ID (R). - - @param ECX MSR_SILVERMONT_PLATFORM_ID (0x00000017) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PLATFORM_ID_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PLATFORM_ID_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PLATFORM_ID_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PLATFORM_ID); - @endcode - @note MSR_SILVERMONT_PLATFORM_ID is defined as MSR_PLATFORM_ID in SDM. -**/ -#define MSR_SILVERMONT_PLATFORM_ID 0x00000017 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PLATFORM_ID -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 12:8] Maximum Qualified Ratio (R) The maximum allowed bus ratio. - /// - UINT32 MaximumQualifiedRatio:5; - UINT32 Reserved2:19; - UINT32 Reserved3:18; - /// - /// [Bits 52:50] See Table 35-2. - /// - UINT32 PlatformId:3; - UINT32 Reserved4:11; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PLATFORM_ID_REGISTER; - - -/** - Module. Processor Hard Power-On Configuration (R/W) Writes ignored. - - @param ECX MSR_SILVERMONT_EBL_CR_POWERON (0x0000002A) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_EBL_CR_POWERON_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_EBL_CR_POWERON_REGISTER. - - Example usage - @code - MSR_SILVERMONT_EBL_CR_POWERON_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_EBL_CR_POWERON); - AsmWriteMsr64 (MSR_SILVERMONT_EBL_CR_POWERON, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_EBL_CR_POWERON is defined as MSR_EBL_CR_POWERON in SDM. -**/ -#define MSR_SILVERMONT_EBL_CR_POWERON 0x0000002A - -/** - MSR information returned for MSR index #MSR_SILVERMONT_EBL_CR_POWERON -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_EBL_CR_POWERON_REGISTER; - - -/** - Core. SMI Counter (R/O). - - @param ECX MSR_SILVERMONT_SMI_COUNT (0x00000034) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_SMI_COUNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_SMI_COUNT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_SMI_COUNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_SMI_COUNT); - @endcode - @note MSR_SILVERMONT_SMI_COUNT is defined as MSR_SMI_COUNT in SDM. -**/ -#define MSR_SILVERMONT_SMI_COUNT 0x00000034 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_SMI_COUNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] SMI Count (R/O) Running count of SMI events since last - /// RESET. - /// - UINT32 SMICount:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_SMI_COUNT_REGISTER; - - -/** - Core. Control Features in Intel 64 Processor (R/W). See Table 35-2. - - @param ECX MSR_IA32_SILVERMONT_FEATURE_CONTROL (0x0000003A) - @param EAX Lower 32-bits of MSR value. - Described by the type - MSR_SILVERMONT_IA32_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type - MSR_SILVERMONT_IA32_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_SILVERMONT_IA32_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_IA32_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_SILVERMONT_IA32_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_IA32_FEATURE_CONTROL is defined as IA32_FEATURE_CONTROL in SDM. -**/ -#define MSR_SILVERMONT_IA32_FEATURE_CONTROL 0x0000003A - -/** - MSR information returned for MSR index #MSR_SILVERMONT_IA32_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Lock (R/WL). - /// - UINT32 Lock:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Enable VMX outside SMX operation (R/WL). - /// - UINT32 EnableVmxOutsideSmx:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_IA32_FEATURE_CONTROL_REGISTER; - - -/** - Core. Last Branch Record n From IP (R/W) One of eight pairs of last branch - record registers on the last branch record stack. The From_IP part of the - stack contains pointers to the source instruction. See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.5 and record format in Section - 17.4.8.1. - - @param ECX MSR_SILVERMONT_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_0_FROM_IP); - AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_0_FROM_IP, Msr); - @endcode - @note MSR_SILVERMONT_LASTBRANCH_0_FROM_IP is defined as MSR_LASTBRANCH_0_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_1_FROM_IP is defined as MSR_LASTBRANCH_1_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_2_FROM_IP is defined as MSR_LASTBRANCH_2_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_3_FROM_IP is defined as MSR_LASTBRANCH_3_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_4_FROM_IP is defined as MSR_LASTBRANCH_4_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_5_FROM_IP is defined as MSR_LASTBRANCH_5_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_6_FROM_IP is defined as MSR_LASTBRANCH_6_FROM_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_7_FROM_IP is defined as MSR_LASTBRANCH_7_FROM_IP in SDM. - @{ -**/ -#define MSR_SILVERMONT_LASTBRANCH_0_FROM_IP 0x00000040 -#define MSR_SILVERMONT_LASTBRANCH_1_FROM_IP 0x00000041 -#define MSR_SILVERMONT_LASTBRANCH_2_FROM_IP 0x00000042 -#define MSR_SILVERMONT_LASTBRANCH_3_FROM_IP 0x00000043 -#define MSR_SILVERMONT_LASTBRANCH_4_FROM_IP 0x00000044 -#define MSR_SILVERMONT_LASTBRANCH_5_FROM_IP 0x00000045 -#define MSR_SILVERMONT_LASTBRANCH_6_FROM_IP 0x00000046 -#define MSR_SILVERMONT_LASTBRANCH_7_FROM_IP 0x00000047 -/// @} - - -/** - Core. Last Branch Record n To IP (R/W) One of eight pairs of last branch - record registers on the last branch record stack. The To_IP part of the - stack contains pointers to the destination instruction. - - @param ECX MSR_SILVERMONT_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_0_TO_IP); - AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_0_TO_IP, Msr); - @endcode - @note MSR_SILVERMONT_LASTBRANCH_0_TO_IP is defined as MSR_LASTBRANCH_0_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_1_TO_IP is defined as MSR_LASTBRANCH_1_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_2_TO_IP is defined as MSR_LASTBRANCH_2_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_3_TO_IP is defined as MSR_LASTBRANCH_3_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_4_TO_IP is defined as MSR_LASTBRANCH_4_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_5_TO_IP is defined as MSR_LASTBRANCH_5_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_6_TO_IP is defined as MSR_LASTBRANCH_6_TO_IP in SDM. - MSR_SILVERMONT_LASTBRANCH_7_TO_IP is defined as MSR_LASTBRANCH_7_TO_IP in SDM. - @{ -**/ -#define MSR_SILVERMONT_LASTBRANCH_0_TO_IP 0x00000060 -#define MSR_SILVERMONT_LASTBRANCH_1_TO_IP 0x00000061 -#define MSR_SILVERMONT_LASTBRANCH_2_TO_IP 0x00000062 -#define MSR_SILVERMONT_LASTBRANCH_3_TO_IP 0x00000063 -#define MSR_SILVERMONT_LASTBRANCH_4_TO_IP 0x00000064 -#define MSR_SILVERMONT_LASTBRANCH_5_TO_IP 0x00000065 -#define MSR_SILVERMONT_LASTBRANCH_6_TO_IP 0x00000066 -#define MSR_SILVERMONT_LASTBRANCH_7_TO_IP 0x00000067 -/// @} - - -/** - Module. Scalable Bus Speed(RO) This field indicates the intended scalable - bus clock speed for processors based on Silvermont microarchitecture:. - - @param ECX MSR_SILVERMONT_FSB_FREQ (0x000000CD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_FSB_FREQ_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_FSB_FREQ_REGISTER. - - Example usage - @code - MSR_SILVERMONT_FSB_FREQ_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_FSB_FREQ); - @endcode - @note MSR_SILVERMONT_FSB_FREQ is defined as MSR_FSB_FREQ in SDM. -**/ -#define MSR_SILVERMONT_FSB_FREQ 0x000000CD - -/** - MSR information returned for MSR index #MSR_SILVERMONT_FSB_FREQ -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Scalable Bus Speed - /// - /// Silvermont Processor Family - /// --------------------------- - /// 100B: 080.0 MHz - /// 000B: 083.3 MHz - /// 001B: 100.0 MHz - /// 010B: 133.3 MHz - /// 011B: 116.7 MHz - /// - /// Airmont Processor Family - /// --------------------------- - /// 0000B: 083.3 MHz - /// 0001B: 100.0 MHz - /// 0010B: 133.3 MHz - /// 0011B: 116.7 MHz - /// 0100B: 080.0 MHz - /// 0101B: 093.3 MHz - /// 0110B: 090.0 MHz - /// 0111B: 088.9 MHz - /// 1000B: 087.5 MHz - /// - UINT32 ScalableBusSpeed:4; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_FSB_FREQ_REGISTER; - - -/** - Module. C-State Configuration Control (R/W) Note: C-state values are - processor specific C-state code names, unrelated to MWAIT extension C-state - parameters or ACPI CStates. See http://biosbits.org. - - @param ECX MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power). for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0 (no package C-sate support) 001b: C1 (Behavior is the same as 000b) - /// 100b: C4 110b: C6 111b: C7 (Silvermont only). - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W) When set, will map - /// IO_read instructions sent to IO register specified by - /// MSR_PMG_IO_CAPTURE_BASE to MWAIT instructions. - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO) When set, lock bits 15:0 of this register - /// until next reset. - /// - UINT32 CFGLock:1; - UINT32 Reserved3:16; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Module. Power Management IO Redirection in C-state (R/W) See - http://biosbits.org. - - @param ECX MSR_SILVERMONT_PMG_IO_CAPTURE_BASE (0x000000E4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PMG_IO_CAPTURE_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PMG_IO_CAPTURE_BASE_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PMG_IO_CAPTURE_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PMG_IO_CAPTURE_BASE); - AsmWriteMsr64 (MSR_SILVERMONT_PMG_IO_CAPTURE_BASE, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_PMG_IO_CAPTURE_BASE is defined as MSR_PMG_IO_CAPTURE_BASE in SDM. -**/ -#define MSR_SILVERMONT_PMG_IO_CAPTURE_BASE 0x000000E4 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PMG_IO_CAPTURE_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] LVL_2 Base Address (R/W) Specifies the base address - /// visible to software for IO redirection. If IO MWAIT Redirection is - /// enabled, reads to this address will be consumed by the power - /// management logic and decoded to MWAIT instructions. When IO port - /// address redirection is enabled, this is the IO port address reported - /// to the OS/software. - /// - UINT32 Lvl2Base:16; - /// - /// [Bits 18:16] C-state Range (R/W) Specifies the encoding value of the - /// maximum C-State code name to be included when IO read to MWAIT - /// redirection is enabled by MSR_PKG_CST_CONFIG_CONTROL[bit10]: 100b - C4 - /// is the max C-State to include 110b - C6 is the max C-State to include - /// 111b - C7 is the max C-State to include. - /// - UINT32 CStateRange:3; - UINT32 Reserved1:13; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PMG_IO_CAPTURE_BASE_REGISTER; - - -/** - Module. - - @param ECX MSR_SILVERMONT_BBL_CR_CTL3 (0x0000011E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_BBL_CR_CTL3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_BBL_CR_CTL3_REGISTER. - - Example usage - @code - MSR_SILVERMONT_BBL_CR_CTL3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_BBL_CR_CTL3); - AsmWriteMsr64 (MSR_SILVERMONT_BBL_CR_CTL3, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_BBL_CR_CTL3 is defined as MSR_BBL_CR_CTL3 in SDM. -**/ -#define MSR_SILVERMONT_BBL_CR_CTL3 0x0000011E - -/** - MSR information returned for MSR index #MSR_SILVERMONT_BBL_CR_CTL3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] L2 Hardware Enabled (RO) 1 = If the L2 is hardware-enabled 0 = - /// Indicates if the L2 is hardware-disabled. - /// - UINT32 L2HardwareEnabled:1; - UINT32 Reserved1:7; - /// - /// [Bit 8] L2 Enabled. (R/W) 1 = L2 cache has been initialized 0 = - /// Disabled (default) Until this bit is set the processor will not - /// respond to the WBINVD instruction or the assertion of the FLUSH# input. - /// - UINT32 L2Enabled:1; - UINT32 Reserved2:14; - /// - /// [Bit 23] L2 Not Present (RO) 1. = L2 Present 2. = L2 Not Present. - /// - UINT32 L2NotPresent:1; - UINT32 Reserved3:8; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_BBL_CR_CTL3_REGISTER; - - -/** - Core. AES Configuration (RW-L) Privileged post-BIOS agent must provide a #GP - handler to handle unsuccessful read of this MSR. - - @param ECX MSR_SILVERMONT_FEATURE_CONFIG (0x0000013C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_FEATURE_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_FEATURE_CONFIG_REGISTER. - - Example usage - @code - MSR_SILVERMONT_FEATURE_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_FEATURE_CONFIG); - AsmWriteMsr64 (MSR_SILVERMONT_FEATURE_CONFIG, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_FEATURE_CONFIG is defined as MSR_FEATURE_CONFIG in SDM. -**/ -#define MSR_SILVERMONT_FEATURE_CONFIG 0x0000013C - -/** - MSR information returned for MSR index #MSR_SILVERMONT_FEATURE_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] AES Configuration (RW-L) Upon a successful read of this - /// MSR, the configuration of AES instruction set availability is as - /// follows: 11b: AES instructions are not available until next RESET. - /// otherwise, AES instructions are available. Note, AES instruction set - /// is not available if read is unsuccessful. If the configuration is not - /// 01b, AES instruction can be mis-configured if a privileged agent - /// unintentionally writes 11b. - /// - UINT32 AESConfiguration:2; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_FEATURE_CONFIG_REGISTER; - - -/** - Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_SILVERMONT_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_SILVERMONT_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_SILVERMONT_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_SILVERMONT_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. Fast-Strings Enable See Table 35-2. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Module. Automatic Thermal Control Circuit Enable (R/W) See - /// Table 35-2. Default value is 0. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Core. Performance Monitoring Available (R) See Table 35-2. - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:3; - /// - /// [Bit 11] Core. Branch Trace Storage Unavailable (RO) See Table 35-2. - /// - UINT32 BTS:1; - /// - /// [Bit 12] Core. Processor Event Based Sampling Unavailable (RO) See - /// Table 35-2. - /// - UINT32 PEBS:1; - UINT32 Reserved4:3; - /// - /// [Bit 16] Module. Enhanced Intel SpeedStep Technology Enable (R/W) See - /// Table 35-2. - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] Core. ENABLE MONITOR FSM (R/W) See Table 35-2. - /// - UINT32 MONITOR:1; - UINT32 Reserved6:3; - /// - /// [Bit 22] Core. Limit CPUID Maxval (R/W) See Table 35-2. - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] Module. xTPR Message Disable (R/W) See Table 35-2. - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] Core. XD Bit Disable (R/W) See Table 35-2. - /// - UINT32 XD:1; - UINT32 Reserved9:3; - /// - /// [Bit 38] Module. Turbo Mode Disable (R/W) When set to 1 on processors - /// that support Intel Turbo Boost Technology, the turbo mode feature is - /// disabled and the IDA_Enable feature flag will be clear (CPUID.06H: - /// EAX[1]=0). When set to a 0 on processors that support IDA, CPUID.06H: - /// EAX[1] reports the processor's support of turbo mode is enabled. Note: - /// the power-on default value is used by BIOS to detect hardware support - /// of turbo mode. If power-on default value is 1, turbo mode is available - /// in the processor. If power-on default value is 0, turbo mode is not - /// available. - /// - UINT32 TurboModeDisable:1; - UINT32 Reserved10:25; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_IA32_MISC_ENABLE_REGISTER; - - -/** - Package. - - @param ECX MSR_SILVERMONT_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_SILVERMONT_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_SILVERMONT_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_SILVERMONT_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (R) The default thermal throttling or - /// PROCHOT# activation temperature in degree C, The effective temperature - /// for thermal throttling or PROCHOT# activation is "Temperature Target" - /// + "Target Offset". - /// - UINT32 TemperatureTarget:8; - /// - /// [Bits 29:24] Target Offset (R/W) Specifies an offset in degrees C to - /// adjust the throttling and PROCHOT# activation temperature from the - /// default target specified in TEMPERATURE_TARGET (bits 23:16). - /// - UINT32 TargetOffset:6; - UINT32 Reserved2:2; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_TEMPERATURE_TARGET_REGISTER; - - -/** - Miscellaneous Feature Control (R/W). - - @param ECX MSR_SILVERMONT_MISC_FEATURE_CONTROL (0x000001A4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_MISC_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_MISC_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_SILVERMONT_MISC_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_MISC_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_SILVERMONT_MISC_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_MISC_FEATURE_CONTROL is defined as MSR_MISC_FEATURE_CONTROL in SDM. -**/ -#define MSR_SILVERMONT_MISC_FEATURE_CONTROL 0x000001A4 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_MISC_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. L2 Hardware Prefetcher Disable (R/W) If 1, disables the - /// L2 hardware prefetcher, which fetches additional lines of code or data - /// into the L2 cache. - /// - UINT32 L2HardwarePrefetcherDisable:1; - UINT32 Reserved1:1; - /// - /// [Bit 2] Core. DCU Hardware Prefetcher Disable (R/W) If 1, disables - /// the L1 data cache prefetcher, which fetches the next cache line into - /// L1 data cache. - /// - UINT32 DCUHardwarePrefetcherDisable:1; - UINT32 Reserved2:29; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_MISC_FEATURE_CONTROL_REGISTER; - - -/** - Module. Offcore Response Event Select Register (R/W). - - @param ECX MSR_SILVERMONT_OFFCORE_RSP_0 (0x000001A6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_OFFCORE_RSP_0); - AsmWriteMsr64 (MSR_SILVERMONT_OFFCORE_RSP_0, Msr); - @endcode - @note MSR_SILVERMONT_OFFCORE_RSP_0 is defined as MSR_OFFCORE_RSP_0 in SDM. -**/ -#define MSR_SILVERMONT_OFFCORE_RSP_0 0x000001A6 - - -/** - Module. Offcore Response Event Select Register (R/W). - - @param ECX MSR_SILVERMONT_OFFCORE_RSP_1 (0x000001A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_OFFCORE_RSP_1); - AsmWriteMsr64 (MSR_SILVERMONT_OFFCORE_RSP_1, Msr); - @endcode - @note MSR_SILVERMONT_OFFCORE_RSP_1 is defined as MSR_OFFCORE_RSP_1 in SDM. -**/ -#define MSR_SILVERMONT_OFFCORE_RSP_1 0x000001A7 - - -/** - Package. Maximum Ratio Limit of Turbo Mode (RW). - - @param ECX MSR_SILVERMONT_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_TURBO_RATIO_LIMIT); - AsmWriteMsr64 (MSR_SILVERMONT_TURBO_RATIO_LIMIT, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_SILVERMONT_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_SILVERMONT_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C Maximum turbo ratio - /// limit of 5 core active. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C Maximum turbo ratio - /// limit of 6 core active. - /// - UINT32 Maximum6C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 7C Maximum turbo ratio - /// limit of 7 core active. - /// - UINT32 Maximum7C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for 8C Maximum turbo ratio - /// limit of 8 core active. - /// - UINT32 Maximum8C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Core. Last Branch Record Filtering Select Register (R/W) See Section - 17.7.2, "Filtering of Last Branch Records.". - - @param ECX MSR_SILVERMONT_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_LBR_SELECT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_LBR_SELECT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_LBR_SELECT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_LBR_SELECT); - AsmWriteMsr64 (MSR_SILVERMONT_LBR_SELECT, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_SILVERMONT_LBR_SELECT 0x000001C8 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_LBR_SELECT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CPL_EQ_0. - /// - UINT32 CPL_EQ_0:1; - /// - /// [Bit 1] CPL_NEQ_0. - /// - UINT32 CPL_NEQ_0:1; - /// - /// [Bit 2] JCC. - /// - UINT32 JCC:1; - /// - /// [Bit 3] NEAR_REL_CALL. - /// - UINT32 NEAR_REL_CALL:1; - /// - /// [Bit 4] NEAR_IND_CALL. - /// - UINT32 NEAR_IND_CALL:1; - /// - /// [Bit 5] NEAR_RET. - /// - UINT32 NEAR_RET:1; - /// - /// [Bit 6] NEAR_IND_JMP. - /// - UINT32 NEAR_IND_JMP:1; - /// - /// [Bit 7] NEAR_REL_JMP. - /// - UINT32 NEAR_REL_JMP:1; - /// - /// [Bit 8] FAR_BRANCH. - /// - UINT32 FAR_BRANCH:1; - UINT32 Reserved1:23; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_LBR_SELECT_REGISTER; - - -/** - Core. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-2) that - points to the MSR containing the most recent branch record. See - MSR_LASTBRANCH_0_FROM_IP. - - @param ECX MSR_SILVERMONT_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_SILVERMONT_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_SILVERMONT_LASTBRANCH_TOS 0x000001C9 - - -/** - Core. Last Exception Record From Linear IP (R) Contains a pointer to the - last branch instruction that the processor executed prior to the last - exception that was generated or the last interrupt that was handled. - - @param ECX MSR_SILVERMONT_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_LER_FROM_LIP); - @endcode - @note MSR_SILVERMONT_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_SILVERMONT_LER_FROM_LIP 0x000001DD - - -/** - Core. Last Exception Record To Linear IP (R) This area contains a pointer - to the target of the last branch instruction that the processor executed - prior to the last exception that was generated or the last interrupt that - was handled. - - @param ECX MSR_SILVERMONT_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_LER_TO_LIP); - @endcode - @note MSR_SILVERMONT_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_SILVERMONT_LER_TO_LIP 0x000001DE - - -/** - Core. See Table 35-2. See Section 18.4.4, "Processor Event Based Sampling - (PEBS).". - - @param ECX MSR_SILVERMONT_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PEBS_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PEBS_ENABLE_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PEBS_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PEBS_ENABLE); - AsmWriteMsr64 (MSR_SILVERMONT_PEBS_ENABLE, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_SILVERMONT_PEBS_ENABLE 0x000003F1 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PEBS_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Enable PEBS for precise event on IA32_PMC0. (R/W). - /// - UINT32 PEBS:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PEBS_ENABLE_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. Package C6 - Residency Counter. (R/O) Value since last reset that this package is in - processor-specific C6 states. Counts at the TSC Frequency. - - @param ECX MSR_SILVERMONT_PKG_C6_RESIDENCY (0x000003FA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_SILVERMONT_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_SILVERMONT_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_SILVERMONT_PKG_C6_RESIDENCY 0x000003FA - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C6 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C6 states. Counts at the TSC Frequency. - - @param ECX MSR_SILVERMONT_CORE_C6_RESIDENCY (0x000003FD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_CORE_C6_RESIDENCY); - AsmWriteMsr64 (MSR_SILVERMONT_CORE_C6_RESIDENCY, Msr); - @endcode - @note MSR_SILVERMONT_CORE_C6_RESIDENCY is defined as MSR_CORE_C6_RESIDENCY in SDM. -**/ -#define MSR_SILVERMONT_CORE_C6_RESIDENCY 0x000003FD - - -/** - Core. Capability Reporting Register of EPT and VPID (R/O) See Table 35-2. - - @param ECX MSR_SILVERMONT_IA32_VMX_EPT_VPID_ENUM (0x0000048C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_IA32_VMX_EPT_VPID_ENUM); - @endcode - @note MSR_SILVERMONT_IA32_VMX_EPT_VPID_ENUM is defined as IA32_VMX_EPT_VPID_ENUM in SDM. -**/ -#define MSR_SILVERMONT_IA32_VMX_EPT_VPID_ENUM 0x0000048C - - -/** - Core. Capability Reporting Register of VM-function Controls (R/O) See Table - 35-2. - - @param ECX MSR_SILVERMONT_IA32_VMX_FMFUNC (0x00000491) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_IA32_VMX_FMFUNC); - @endcode - @note MSR_SILVERMONT_IA32_VMX_FMFUNC is defined as IA32_VMX_FMFUNC in SDM. -**/ -#define MSR_SILVERMONT_IA32_VMX_FMFUNC 0x00000491 - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI CStates. CORE C1 - Residency Counter. (R/O) Value since last reset that this core is in - processor-specific C1 states. Counts at the TSC frequency. - - @param ECX MSR_SILVERMONT_CORE_C1_RESIDENCY (0x00000660) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_CORE_C1_RESIDENCY); - AsmWriteMsr64 (MSR_SILVERMONT_CORE_C1_RESIDENCY, Msr); - @endcode - @note MSR_SILVERMONT_CORE_C1_RESIDENCY is defined as MSR_CORE_C1_RESIDENCY in SDM. -**/ -#define MSR_SILVERMONT_CORE_C1_RESIDENCY 0x00000660 - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O) See Section 14.9.1, - "RAPL Interfaces.". - - @param ECX MSR_SILVERMONT_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_RAPL_POWER_UNIT); - @endcode - @note MSR_SILVERMONT_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_SILVERMONT_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Power Units. Power related information (in milliWatts) is - /// based on the multiplier, 2^PU; where PU is an unsigned integer - /// represented by bits 3:0. Default value is 0101b, indicating power unit - /// is in 32 milliWatts increment. - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Energy Status Units. Energy related information (in - /// microJoules) is based on the multiplier, 2^ESU; where ESU is an - /// unsigned integer represented by bits 12:8. Default value is 00101b, - /// indicating energy unit is in 32 microJoules increment. - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Time Unit. The value is 0000b, indicating time unit is in - /// one second. - /// - UINT32 TimeUnits:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. PKG RAPL Power Limit Control (R/W). - - @param ECX MSR_SILVERMONT_PKG_POWER_LIMIT (0x00000610) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_POWER_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_POWER_LIMIT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PKG_POWER_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PKG_POWER_LIMIT); - AsmWriteMsr64 (MSR_SILVERMONT_PKG_POWER_LIMIT, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_PKG_POWER_LIMIT is defined as MSR_PKG_POWER_LIMIT in SDM. -**/ -#define MSR_SILVERMONT_PKG_POWER_LIMIT 0x00000610 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PKG_POWER_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Package Power Limit #1. (R/W) See Section 14.9.3, "Package - /// RAPL Domain." and MSR_RAPL_POWER_UNIT in Table 35-8. - /// - UINT32 Limit:15; - /// - /// [Bit 15] Enable Power Limit #1. (R/W) See Section 14.9.3, "Package - /// RAPL Domain.". - /// - UINT32 Enable:1; - /// - /// [Bit 16] Package Clamping Limitation #1. (R/W) See Section 14.9.3, - /// "Package RAPL Domain.". - /// - UINT32 ClampingLimit:1; - /// - /// [Bits 23:17] Time Window for Power Limit #1. (R/W) in unit of second. - /// If 0 is specified in bits [23:17], defaults to 1 second window. - /// - UINT32 Time:7; - UINT32 Reserved1:8; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PKG_POWER_LIMIT_REGISTER; - - -/** - Package. PKG Energy Status (R/O) See Section 14.9.3, "Package RAPL Domain." - and MSR_RAPL_POWER_UNIT in Table 35-8. - - @param ECX MSR_SILVERMONT_PKG_ENERGY_STATUS (0x00000611) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_PKG_ENERGY_STATUS); - @endcode - @note MSR_SILVERMONT_PKG_ENERGY_STATUS is defined as MSR_PKG_ENERGY_STATUS in SDM. -**/ -#define MSR_SILVERMONT_PKG_ENERGY_STATUS 0x00000611 - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains." and MSR_RAPL_POWER_UNIT in Table 35-8. - - @param ECX MSR_SILVERMONT_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_PP0_ENERGY_STATUS); - @endcode - @note MSR_SILVERMONT_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_SILVERMONT_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. Core C6 demotion policy config MSR. Controls per-core C6 demotion - policy. Writing a value of 0 disables core level HW demotion policy. - - @param ECX MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG (0x00000668) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG); - AsmWriteMsr64 (MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG, Msr); - @endcode - @note MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG is defined as MSR_CC6_DEMOTION_POLICY_CONFIG in SDM. -**/ -#define MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG 0x00000668 - - -/** - Package. Module C6 demotion policy config MSR. Controls module (i.e. two - cores sharing the second-level cache) C6 demotion policy. Writing a value of - 0 disables module level HW demotion policy. - - @param ECX MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG (0x00000669) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG); - AsmWriteMsr64 (MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG, Msr); - @endcode - @note MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG is defined as MSR_MC6_DEMOTION_POLICY_CONFIG in SDM. -**/ -#define MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG 0x00000669 - - -/** - Module. Module C6 Residency Counter (R/0) Note: C-state values are processor - specific C-state code names, unrelated to MWAIT extension C-state parameters - or ACPI CStates. Time that this module is in module-specific C6 states since - last reset. Counts at 1 Mhz frequency. - - @param ECX MSR_SILVERMONT_MC6_RESIDENCY_COUNTER (0x00000664) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SILVERMONT_MC6_RESIDENCY_COUNTER); - @endcode - @note MSR_SILVERMONT_MC6_RESIDENCY_COUNTER is defined as MSR_MC6_RESIDENCY_COUNTER in SDM. -**/ -#define MSR_SILVERMONT_MC6_RESIDENCY_COUNTER 0x00000664 - - -/** - Package. PKG RAPL Parameter (R/0). - - @param ECX MSR_SILVERMONT_PKG_POWER_INFO (0x0000066E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_POWER_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PKG_POWER_INFO_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PKG_POWER_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PKG_POWER_INFO); - @endcode - @note MSR_SILVERMONT_PKG_POWER_INFO is defined as MSR_PKG_POWER_INFO in SDM. -**/ -#define MSR_SILVERMONT_PKG_POWER_INFO 0x0000066E - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PKG_POWER_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Thermal Spec Power. (R/0) The unsigned integer value is - /// the equivalent of thermal specification power of the package domain. - /// The unit of this field is specified by the "Power Units" field of - /// MSR_RAPL_POWER_UNIT. - /// - UINT32 ThermalSpecPower:15; - UINT32 Reserved1:17; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PKG_POWER_INFO_REGISTER; - - -/** - Package. PP0 RAPL Power Limit Control (R/W). - - @param ECX MSR_SILVERMONT_PP0_POWER_LIMIT (0x00000638) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PP0_POWER_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SILVERMONT_PP0_POWER_LIMIT_REGISTER. - - Example usage - @code - MSR_SILVERMONT_PP0_POWER_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PP0_POWER_LIMIT); - AsmWriteMsr64 (MSR_SILVERMONT_PP0_POWER_LIMIT, Msr.Uint64); - @endcode - @note MSR_SILVERMONT_PP0_POWER_LIMIT is defined as MSR_PP0_POWER_LIMIT in SDM. -**/ -#define MSR_SILVERMONT_PP0_POWER_LIMIT 0x00000638 - -/** - MSR information returned for MSR index #MSR_SILVERMONT_PP0_POWER_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] PP0 Power Limit #1. (R/W) See Section 14.9.4, "PP0/PP1 - /// RAPL Domains." and MSR_RAPL_POWER_UNIT in Table 35-8. - /// - UINT32 Limit:15; - /// - /// [Bit 15] Enable Power Limit #1. (R/W) See Section 14.9.4, "PP0/PP1 - /// RAPL Domains.". - /// - UINT32 Enable:1; - UINT32 Reserved1:1; - /// - /// [Bits 23:17] Time Window for Power Limit #1. (R/W) Specifies the time - /// duration over which the average power must remain below - /// PP0_POWER_LIMIT #1(14:0). Supported Encodings: 0x0: 1 second time - /// duration. 0x1: 5 second time duration (Default). 0x2: 10 second time - /// duration. 0x3: 15 second time duration. 0x4: 20 second time duration. - /// 0x5: 25 second time duration. 0x6: 30 second time duration. 0x7: 35 - /// second time duration. 0x8: 40 second time duration. 0x9: 45 second - /// time duration. 0xA: 50 second time duration. 0xB-0x7F - reserved. - /// - UINT32 Time:7; - UINT32 Reserved2:8; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SILVERMONT_PP0_POWER_LIMIT_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h deleted file mode 100644 index 7166e5f9e..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h +++ /dev/null @@ -1,2257 +0,0 @@ -/** @file - MSR Definitions for Intel processors based on the Skylake microarchitecture. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.15. - -**/ - -#ifndef __SKYLAKE_MSR_H__ -#define __SKYLAKE_MSR_H__ - -#include - -/** - Is Intel processors based on the Skylake microarchitecture? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_SKYLAKE_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x4E || \ - DisplayModel == 0x5E \ - ) \ - ) - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_SKYLAKE_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_SKYLAKE_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_TURBO_RATIO_LIMIT); - @endcode - @note MSR_SKYLAKE_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_SKYLAKE_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_SKYLAKE_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Thread. Last Branch Record Stack TOS (R/W) Contains an index (bits 0-4) - that points to the MSR containing the most recent branch record. - - @param ECX MSR_SKYLAKE_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_SKYLAKE_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_SKYLAKE_LASTBRANCH_TOS 0x000001C9 - - -/** - Package. Lower 64 Bit OwnerEpoch Component of SGX Key (RO). Low 64 bits of - an 128-bit external entropy value for key derivation of an enclave. - - @param ECX MSR_SKYLAKE_SGXOWNER0 (0x00000300) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_SGXOWNER0); - @endcode - @note MSR_SKYLAKE_SGXOWNER0 is defined as MSR_SGXOWNER0 in SDM. -**/ -#define MSR_SKYLAKE_SGXOWNER0 0x00000300 - - -/** - Package. Upper 64 Bit OwnerEpoch Component of SGX Key (RO). Upper 64 bits of - an 128-bit external entropy value for key derivation of an enclave. - - @param ECX MSR_SKYLAKE_SGXOWNER1 (0x00000301) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_SGXOWNER1); - @endcode - @note MSR_SKYLAKE_SGXOWNER1 is defined as MSR_SGXOWNER1 in SDM. -**/ -#define MSR_SKYLAKE_SGXOWNER1 0x00000301 - - -/** - See Table 35-2. See Section 18.2.4, "Architectural Performance Monitoring - Version 4.". - - @param ECX MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS (0x0000038E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS is defined as IA32_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS 0x0000038E - -/** - MSR information returned for MSR index #MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Thread. Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Thread. Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Thread. Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - /// - /// [Bit 4] Thread. Ovf_PMC4 (if CPUID.0AH:EAX[15:8] > 4). - /// - UINT32 Ovf_PMC4:1; - /// - /// [Bit 5] Thread. Ovf_PMC5 (if CPUID.0AH:EAX[15:8] > 5). - /// - UINT32 Ovf_PMC5:1; - /// - /// [Bit 6] Thread. Ovf_PMC6 (if CPUID.0AH:EAX[15:8] > 6). - /// - UINT32 Ovf_PMC6:1; - /// - /// [Bit 7] Thread. Ovf_PMC7 (if CPUID.0AH:EAX[15:8] > 7). - /// - UINT32 Ovf_PMC7:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Thread. Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Thread. Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Thread. Trace_ToPA_PMI. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] Thread. LBR_Frz. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Thread. CTR_Frz. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Thread. ASCI. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Thread. Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Thread. Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - /// - /// [Bit 63] Thread. CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_REGISTER; - - -/** - See Table 35-2. See Section 18.2.4, "Architectural Performance Monitoring - Version 4.". - - @param ECX MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET (0x00000390) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER. - - Example usage - @code - MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET); - AsmWriteMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET is defined as IA32_PERF_GLOBAL_STATUS_RESET in SDM. -**/ -#define MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET 0x00000390 - -/** - MSR information returned for MSR index - #MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Set 1 to clear Ovf_PMC0. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Thread. Set 1 to clear Ovf_PMC1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Thread. Set 1 to clear Ovf_PMC2. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Thread. Set 1 to clear Ovf_PMC3. - /// - UINT32 Ovf_PMC3:1; - /// - /// [Bit 4] Thread. Set 1 to clear Ovf_PMC4 (if CPUID.0AH:EAX[15:8] > 4). - /// - UINT32 Ovf_PMC4:1; - /// - /// [Bit 5] Thread. Set 1 to clear Ovf_PMC5 (if CPUID.0AH:EAX[15:8] > 5). - /// - UINT32 Ovf_PMC5:1; - /// - /// [Bit 6] Thread. Set 1 to clear Ovf_PMC6 (if CPUID.0AH:EAX[15:8] > 6). - /// - UINT32 Ovf_PMC6:1; - /// - /// [Bit 7] Thread. Set 1 to clear Ovf_PMC7 (if CPUID.0AH:EAX[15:8] > 7). - /// - UINT32 Ovf_PMC7:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Set 1 to clear Ovf_FixedCtr0. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Thread. Set 1 to clear Ovf_FixedCtr1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Thread. Set 1 to clear Ovf_FixedCtr2. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Thread. Set 1 to clear Trace_ToPA_PMI. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] Thread. Set 1 to clear LBR_Frz. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Thread. Set 1 to clear CTR_Frz. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Thread. Set 1 to clear ASCI. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Thread. Set 1 to clear Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Thread. Set 1 to clear Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - /// - /// [Bit 63] Thread. Set 1 to clear CondChgd. - /// - UINT32 CondChgd:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_RESET_REGISTER; - - -/** - See Table 35-2. See Section 18.2.4, "Architectural Performance Monitoring - Version 4.". - - @param ECX MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET (0x00000391) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET_REGISTER. - - Example usage - @code - MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET); - AsmWriteMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET is defined as IA32_PERF_GLOBAL_STATUS_SET in SDM. -**/ -#define MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET 0x00000391 - -/** - MSR information returned for MSR index - #MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Thread. Set 1 to cause Ovf_PMC0 = 1. - /// - UINT32 Ovf_PMC0:1; - /// - /// [Bit 1] Thread. Set 1 to cause Ovf_PMC1 = 1. - /// - UINT32 Ovf_PMC1:1; - /// - /// [Bit 2] Thread. Set 1 to cause Ovf_PMC2 = 1. - /// - UINT32 Ovf_PMC2:1; - /// - /// [Bit 3] Thread. Set 1 to cause Ovf_PMC3 = 1. - /// - UINT32 Ovf_PMC3:1; - /// - /// [Bit 4] Thread. Set 1 to cause Ovf_PMC4=1 (if CPUID.0AH:EAX[15:8] > 4). - /// - UINT32 Ovf_PMC4:1; - /// - /// [Bit 5] Thread. Set 1 to cause Ovf_PMC5=1 (if CPUID.0AH:EAX[15:8] > 5). - /// - UINT32 Ovf_PMC5:1; - /// - /// [Bit 6] Thread. Set 1 to cause Ovf_PMC6=1 (if CPUID.0AH:EAX[15:8] > 6). - /// - UINT32 Ovf_PMC6:1; - /// - /// [Bit 7] Thread. Set 1 to cause Ovf_PMC7=1 (if CPUID.0AH:EAX[15:8] > 7). - /// - UINT32 Ovf_PMC7:1; - UINT32 Reserved1:24; - /// - /// [Bit 32] Thread. Set 1 to cause Ovf_FixedCtr0 = 1. - /// - UINT32 Ovf_FixedCtr0:1; - /// - /// [Bit 33] Thread. Set 1 to cause Ovf_FixedCtr1 = 1. - /// - UINT32 Ovf_FixedCtr1:1; - /// - /// [Bit 34] Thread. Set 1 to cause Ovf_FixedCtr2 = 1. - /// - UINT32 Ovf_FixedCtr2:1; - UINT32 Reserved2:20; - /// - /// [Bit 55] Thread. Set 1 to cause Trace_ToPA_PMI = 1. - /// - UINT32 Trace_ToPA_PMI:1; - UINT32 Reserved3:2; - /// - /// [Bit 58] Thread. Set 1 to cause LBR_Frz = 1. - /// - UINT32 LBR_Frz:1; - /// - /// [Bit 59] Thread. Set 1 to cause CTR_Frz = 1. - /// - UINT32 CTR_Frz:1; - /// - /// [Bit 60] Thread. Set 1 to cause ASCI = 1. - /// - UINT32 ASCI:1; - /// - /// [Bit 61] Thread. Set 1 to cause Ovf_Uncore. - /// - UINT32 Ovf_Uncore:1; - /// - /// [Bit 62] Thread. Set 1 to cause Ovf_BufDSSAVE. - /// - UINT32 Ovf_BufDSSAVE:1; - UINT32 Reserved4:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_IA32_PERF_GLOBAL_STATUS_SET_REGISTER; - - -/** - Thread. FrontEnd Precise Event Condition Select (R/W). - - @param ECX MSR_SKYLAKE_PEBS_FRONTEND (0x000003F7) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PEBS_FRONTEND_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PEBS_FRONTEND_REGISTER. - - Example usage - @code - MSR_SKYLAKE_PEBS_FRONTEND_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PEBS_FRONTEND); - AsmWriteMsr64 (MSR_SKYLAKE_PEBS_FRONTEND, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_PEBS_FRONTEND is defined as MSR_PEBS_FRONTEND in SDM. -**/ -#define MSR_SKYLAKE_PEBS_FRONTEND 0x000003F7 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_PEBS_FRONTEND -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Event Code Select. - /// - UINT32 EventCodeSelect:3; - UINT32 Reserved1:1; - /// - /// [Bit 4] Event Code Select High. - /// - UINT32 EventCodeSelectHigh:1; - UINT32 Reserved2:3; - /// - /// [Bits 19:8] IDQ_Bubble_Length Specifier. - /// - UINT32 IDQ_Bubble_Length:12; - /// - /// [Bits 22:20] IDQ_Bubble_Width Specifier. - /// - UINT32 IDQ_Bubble_Width:3; - UINT32 Reserved3:9; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_PEBS_FRONTEND_REGISTER; - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_SKYLAKE_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_PP0_ENERGY_STATUS); - @endcode - @note MSR_SKYLAKE_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_SKYLAKE_PP0_ENERGY_STATUS 0x00000639 - - -/** - Platform*. Platform Energy Counter. (R/O). This MSR is valid only if both - platform vendor hardware implementation and BIOS enablement support it. This - MSR will read 0 if not valid. - - @param ECX MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER (0x0000064D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER_REGISTER. - - Example usage - @code - MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER); - @endcode - @note MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER is defined as MSR_PLATFORM_ENERGY_COUNTER in SDM. -**/ -#define MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER 0x0000064D - -/** - MSR information returned for MSR index #MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Total energy consumed by all devices in the platform that - /// receive power from integrated power delivery mechanism, Included - /// platform devices are processor cores, SOC, memory, add-on or - /// peripheral devices that get powered directly from the platform power - /// delivery means. The energy units are specified in the - /// MSR_RAPL_POWER_UNIT.Enery_Status_Unit. - /// - UINT32 TotalEnergy:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER_REGISTER; - - -/** - Thread. Productive Performance Count. (R/O). Hardware's view of workload - scalability. See Section 14.4.5.1. - - @param ECX MSR_SKYLAKE_PPERF (0x0000064E) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_PPERF); - @endcode - @note MSR_SKYLAKE_PPERF is defined as MSR_PPERF in SDM. -**/ -#define MSR_SKYLAKE_PPERF 0x0000064E - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS (0x0000064F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS 0x0000064F - -/** - MSR information returned for MSR index #MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, frequency is reduced below the - /// operating system request due to assertion of external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:2; - /// - /// [Bit 4] Residency State Regulation Status (R0) When set, frequency is - /// reduced below the operating system request due to residency state - /// regulation limit. - /// - UINT32 ResidencyStateRegulationStatus:1; - /// - /// [Bit 5] Running Average Thermal Limit Status (R0) When set, frequency - /// is reduced below the operating system request due to Running Average - /// Thermal Limit (RATL). - /// - UINT32 RunningAverageThermalLimitStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from a - /// processor Voltage Regulator (VR). - /// - UINT32 VRThermAlertStatus:1; - /// - /// [Bit 7] VR Therm Design Current Status (R0) When set, frequency is - /// reduced below the operating system request due to VR thermal design - /// current limit. - /// - UINT32 VRThermDesignCurrentStatus:1; - /// - /// [Bit 8] Other Status (R0) When set, frequency is reduced below the - /// operating system request due to electrical or other constraints. - /// - UINT32 OtherStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 10] Package/Platform-Level Power Limiting PL1 Status (R0) When - /// set, frequency is reduced below the operating system request due to - /// package/platform-level power limiting PL1. - /// - UINT32 PL1Status:1; - /// - /// [Bit 11] Package/Platform-Level PL2 Power Limiting Status (R0) When - /// set, frequency is reduced below the operating system request due to - /// package/platform-level power limiting PL2/PL3. - /// - UINT32 PL2Status:1; - /// - /// [Bit 12] Max Turbo Limit Status (R0) When set, frequency is reduced - /// below the operating system request due to multi-core turbo limits. - /// - UINT32 MaxTurboLimitStatus:1; - /// - /// [Bit 13] Turbo Transition Attenuation Status (R0) When set, frequency - /// is reduced below the operating system request due to Turbo transition - /// attenuation. This prevents performance degradation due to frequent - /// operating ratio changes. - /// - UINT32 TurboTransitionAttenuationStatus:1; - UINT32 Reserved3:2; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved4:2; - /// - /// [Bit 20] Residency State Regulation Log When set, indicates that the - /// Residency State Regulation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 ResidencyStateRegulationLog:1; - /// - /// [Bit 21] Running Average Thermal Limit Log When set, indicates that - /// the RATL Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 RunningAverageThermalLimitLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - /// - /// [Bit 23] VR Thermal Design Current Log When set, indicates that the - /// VR TDC Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermalDesignCurrentLog:1; - /// - /// [Bit 24] Other Log When set, indicates that the Other Status bit has - /// asserted since the log bit was last cleared. This log bit will remain - /// set until cleared by software writing 0. - /// - UINT32 OtherLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 26] Package/Platform-Level PL1 Power Limiting Log When set, - /// indicates that the Package or Platform Level PL1 Power Limiting Status - /// bit has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package/Platform-Level PL2 Power Limiting Log When set, - /// indicates that the Package or Platform Level PL2/PL3 Power Limiting - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 PL2Log:1; - /// - /// [Bit 28] Max Turbo Limit Log When set, indicates that the Max Turbo - /// Limit Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MaxTurboLimitLog:1; - /// - /// [Bit 29] Turbo Transition Attenuation Log When set, indicates that the - /// Turbo Transition Attenuation Status bit has asserted since the log bit - /// was last cleared. This log bit will remain set until cleared by - /// software writing 0. - /// - UINT32 TurboTransitionAttenuationLog:1; - UINT32 Reserved6:2; - UINT32 Reserved7:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_CORE_PERF_LIMIT_REASONS_REGISTER; - - -/** - Package. HDC Configuration (R/W).. - - @param ECX MSR_SKYLAKE_PKG_HDC_CONFIG (0x00000652) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PKG_HDC_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PKG_HDC_CONFIG_REGISTER. - - Example usage - @code - MSR_SKYLAKE_PKG_HDC_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PKG_HDC_CONFIG); - AsmWriteMsr64 (MSR_SKYLAKE_PKG_HDC_CONFIG, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_PKG_HDC_CONFIG is defined as MSR_PKG_HDC_CONFIG in SDM. -**/ -#define MSR_SKYLAKE_PKG_HDC_CONFIG 0x00000652 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_PKG_HDC_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] PKG_Cx_Monitor. Configures Package Cx state threshold for - /// MSR_PKG_HDC_DEEP_RESIDENCY. - /// - UINT32 PKG_Cx_Monitor:3; - UINT32 Reserved1:29; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_PKG_HDC_CONFIG_REGISTER; - - -/** - Core. Core HDC Idle Residency. (R/O). Core_Cx_Duty_Cycle_Cnt. - - @param ECX MSR_SKYLAKE_CORE_HDC_RESIDENCY (0x00000653) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_CORE_HDC_RESIDENCY); - @endcode - @note MSR_SKYLAKE_CORE_HDC_RESIDENCY is defined as MSR_CORE_HDC_RESIDENCY in SDM. -**/ -#define MSR_SKYLAKE_CORE_HDC_RESIDENCY 0x00000653 - - -/** - Package. Accumulate the cycles the package was in C2 state and at least one - logical processor was in forced idle. (R/O). Pkg_C2_Duty_Cycle_Cnt. - - @param ECX MSR_SKYLAKE_PKG_HDC_SHALLOW_RESIDENCY (0x00000655) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_PKG_HDC_SHALLOW_RESIDENCY); - @endcode - @note MSR_SKYLAKE_PKG_HDC_SHALLOW_RESIDENCY is defined as MSR_PKG_HDC_SHALLOW_RESIDENCY in SDM. -**/ -#define MSR_SKYLAKE_PKG_HDC_SHALLOW_RESIDENCY 0x00000655 - - -/** - Package. Package Cx HDC Idle Residency. (R/O). Pkg_Cx_Duty_Cycle_Cnt. - - @param ECX MSR_SKYLAKE_PKG_HDC_DEEP_RESIDENCY (0x00000656) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_PKG_HDC_DEEP_RESIDENCY); - @endcode - @note MSR_SKYLAKE_PKG_HDC_DEEP_RESIDENCY is defined as MSR_PKG_HDC_DEEP_RESIDENCY in SDM. -**/ -#define MSR_SKYLAKE_PKG_HDC_DEEP_RESIDENCY 0x00000656 - - -/** - Package. Core-count Weighted C0 Residency. (R/O). Increment at the same rate - as the TSC. The increment each cycle is weighted by the number of processor - cores in the package that reside in C0. If N cores are simultaneously in C0, - then each cycle the counter increments by N. - - @param ECX MSR_SKYLAKE_WEIGHTED_CORE_C0 (0x00000658) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_WEIGHTED_CORE_C0); - @endcode - @note MSR_SKYLAKE_WEIGHTED_CORE_C0 is defined as MSR_WEIGHTED_CORE_C0 in SDM. -**/ -#define MSR_SKYLAKE_WEIGHTED_CORE_C0 0x00000658 - - -/** - Package. Any Core C0 Residency. (R/O). Increment at the same rate as the - TSC. The increment each cycle is one if any processor core in the package is - in C0. - - @param ECX MSR_SKYLAKE_ANY_CORE_C0 (0x00000659) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_ANY_CORE_C0); - @endcode - @note MSR_SKYLAKE_ANY_CORE_C0 is defined as MSR_ANY_CORE_C0 in SDM. -**/ -#define MSR_SKYLAKE_ANY_CORE_C0 0x00000659 - - -/** - Package. Any Graphics Engine C0 Residency. (R/O). Increment at the same rate - as the TSC. The increment each cycle is one if any processor graphic - device's compute engines are in C0. - - @param ECX MSR_SKYLAKE_ANY_GFXE_C0 (0x0000065A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_ANY_GFXE_C0); - @endcode - @note MSR_SKYLAKE_ANY_GFXE_C0 is defined as MSR_ANY_GFXE_C0 in SDM. -**/ -#define MSR_SKYLAKE_ANY_GFXE_C0 0x0000065A - - -/** - Package. Core and Graphics Engine Overlapped C0 Residency. (R/O). Increment - at the same rate as the TSC. The increment each cycle is one if at least one - compute engine of the processor graphics is in C0 and at least one processor - core in the package is also in C0. - - @param ECX MSR_SKYLAKE_CORE_GFXE_OVERLAP_C0 (0x0000065B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_CORE_GFXE_OVERLAP_C0); - @endcode - @note MSR_SKYLAKE_CORE_GFXE_OVERLAP_C0 is defined as MSR_CORE_GFXE_OVERLAP_C0 in SDM. -**/ -#define MSR_SKYLAKE_CORE_GFXE_OVERLAP_C0 0x0000065B - - -/** - Platform*. Platform Power Limit Control (R/W-L) Allows platform BIOS to - limit power consumption of the platform devices to the specified values. The - Long Duration power consumption is specified via Platform_Power_Limit_1 and - Platform_Power_Limit_1_Time. The Short Duration power consumption limit is - specified via the Platform_Power_Limit_2 with duration chosen by the - processor. The processor implements an exponential-weighted algorithm in the - placement of the time windows. - - @param ECX MSR_SKYLAKE_PLATFORM_POWER_LIMIT (0x0000065C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PLATFORM_POWER_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_PLATFORM_POWER_LIMIT_REGISTER. - - Example usage - @code - MSR_SKYLAKE_PLATFORM_POWER_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PLATFORM_POWER_LIMIT); - AsmWriteMsr64 (MSR_SKYLAKE_PLATFORM_POWER_LIMIT, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_PLATFORM_POWER_LIMIT is defined as MSR_PLATFORM_POWER_LIMIT in SDM. -**/ -#define MSR_SKYLAKE_PLATFORM_POWER_LIMIT 0x0000065C - -/** - MSR information returned for MSR index #MSR_SKYLAKE_PLATFORM_POWER_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 14:0] Platform Power Limit #1. Average Power limit value which - /// the platform must not exceed over a time window as specified by - /// Power_Limit_1_TIME field. The default value is the Thermal Design - /// Power (TDP) and varies with product skus. The unit is specified in - /// MSR_RAPLPOWER_UNIT. - /// - UINT32 PlatformPowerLimit1:15; - /// - /// [Bit 15] Enable Platform Power Limit #1. When set, enables the - /// processor to apply control policy such that the platform power does - /// not exceed Platform Power limit #1 over the time window specified by - /// Power Limit #1 Time Window. - /// - UINT32 EnablePlatformPowerLimit1:1; - /// - /// [Bit 16] Platform Clamping Limitation #1. When set, allows the - /// processor to go below the OS requested P states in order to maintain - /// the power below specified Platform Power Limit #1 value. This bit is - /// writeable only when CPUID (EAX=6):EAX[4] is set. - /// - UINT32 PlatformClampingLimitation1:1; - /// - /// [Bits 23:17] Time Window for Platform Power Limit #1. Specifies the - /// duration of the time window over which Platform Power Limit 1 value - /// should be maintained for sustained long duration. This field is made - /// up of two numbers from the following equation: Time Window = (float) - /// ((1+(X/4))*(2^Y)), where: X. = POWER_LIMIT_1_TIME[23:22] Y. = - /// POWER_LIMIT_1_TIME[21:17]. The maximum allowed value in this field is - /// defined in MSR_PKG_POWER_INFO[PKG_MAX_WIN]. The default value is 0DH, - /// The unit is specified in MSR_RAPLPOWER_UNIT[Time Unit]. - /// - UINT32 Time:7; - UINT32 Reserved1:8; - /// - /// [Bits 46:32] Platform Power Limit #2. Average Power limit value which - /// the platform must not exceed over the Short Duration time window - /// chosen by the processor. The recommended default value is 1.25 times - /// the Long Duration Power Limit (i.e. Platform Power Limit # 1). - /// - UINT32 PlatformPowerLimit2:15; - /// - /// [Bit 47] Enable Platform Power Limit #2. When set, enables the - /// processor to apply control policy such that the platform power does - /// not exceed Platform Power limit #2 over the Short Duration time window. - /// - UINT32 EnablePlatformPowerLimit2:1; - /// - /// [Bit 48] Platform Clamping Limitation #2. When set, allows the - /// processor to go below the OS requested P states in order to maintain - /// the power below specified Platform Power Limit #2 value. - /// - UINT32 PlatformClampingLimitation2:1; - UINT32 Reserved2:14; - /// - /// [Bit 63] Lock. Setting this bit will lock all other bits of this MSR - /// until system RESET. - /// - UINT32 Lock:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_PLATFORM_POWER_LIMIT_REGISTER; - - -/** - Thread. Last Branch Record n From IP (R/W) One of 32 triplets of last - branch record registers on the last branch record stack. This part of the - stack contains pointers to the source instruction. See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.10. - - @param ECX MSR_SKYLAKE_LASTBRANCH_n_FROM_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_16_FROM_IP); - AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_16_FROM_IP, Msr); - @endcode - @note MSR_SKYLAKE_LASTBRANCH_16_FROM_IP is defined as MSR_LASTBRANCH_16_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_17_FROM_IP is defined as MSR_LASTBRANCH_17_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_18_FROM_IP is defined as MSR_LASTBRANCH_18_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_19_FROM_IP is defined as MSR_LASTBRANCH_19_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_20_FROM_IP is defined as MSR_LASTBRANCH_20_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_21_FROM_IP is defined as MSR_LASTBRANCH_21_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_22_FROM_IP is defined as MSR_LASTBRANCH_22_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_23_FROM_IP is defined as MSR_LASTBRANCH_23_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_24_FROM_IP is defined as MSR_LASTBRANCH_24_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_25_FROM_IP is defined as MSR_LASTBRANCH_25_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_26_FROM_IP is defined as MSR_LASTBRANCH_26_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_27_FROM_IP is defined as MSR_LASTBRANCH_27_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_28_FROM_IP is defined as MSR_LASTBRANCH_28_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_29_FROM_IP is defined as MSR_LASTBRANCH_29_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_30_FROM_IP is defined as MSR_LASTBRANCH_30_FROM_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_31_FROM_IP is defined as MSR_LASTBRANCH_31_FROM_IP in SDM. - @{ -**/ -#define MSR_SKYLAKE_LASTBRANCH_16_FROM_IP 0x00000690 -#define MSR_SKYLAKE_LASTBRANCH_17_FROM_IP 0x00000691 -#define MSR_SKYLAKE_LASTBRANCH_18_FROM_IP 0x00000692 -#define MSR_SKYLAKE_LASTBRANCH_19_FROM_IP 0x00000693 -#define MSR_SKYLAKE_LASTBRANCH_20_FROM_IP 0x00000694 -#define MSR_SKYLAKE_LASTBRANCH_21_FROM_IP 0x00000695 -#define MSR_SKYLAKE_LASTBRANCH_22_FROM_IP 0x00000696 -#define MSR_SKYLAKE_LASTBRANCH_23_FROM_IP 0x00000697 -#define MSR_SKYLAKE_LASTBRANCH_24_FROM_IP 0x00000698 -#define MSR_SKYLAKE_LASTBRANCH_25_FROM_IP 0x00000699 -#define MSR_SKYLAKE_LASTBRANCH_26_FROM_IP 0x0000069A -#define MSR_SKYLAKE_LASTBRANCH_27_FROM_IP 0x0000069B -#define MSR_SKYLAKE_LASTBRANCH_28_FROM_IP 0x0000069C -#define MSR_SKYLAKE_LASTBRANCH_29_FROM_IP 0x0000069D -#define MSR_SKYLAKE_LASTBRANCH_30_FROM_IP 0x0000069E -#define MSR_SKYLAKE_LASTBRANCH_31_FROM_IP 0x0000069F -/// @} - - -/** - Package. Indicator of Frequency Clipping in the Processor Graphics (R/W) - (frequency refers to processor graphics frequency). - - @param ECX MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS (0x000006B0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS is defined as MSR_GRAPHICS_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS 0x000006B0 - -/** - MSR information returned for MSR index - #MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, frequency is reduced due to - /// assertion of external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced due to a - /// thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:3; - /// - /// [Bit 5] Running Average Thermal Limit Status (R0) When set, frequency - /// is reduced due to running average thermal limit. - /// - UINT32 RunningAverageThermalLimitStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced due - /// to a thermal alert from a processor Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - /// - /// [Bit 7] VR Thermal Design Current Status (R0) When set, frequency is - /// reduced due to VR TDC limit. - /// - UINT32 VRThermalDesignCurrentStatus:1; - /// - /// [Bit 8] Other Status (R0) When set, frequency is reduced due to - /// electrical or other constraints. - /// - UINT32 OtherStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 10] Package/Platform-Level Power Limiting PL1 Status (R0) When - /// set, frequency is reduced due to package/platform-level power limiting - /// PL1. - /// - UINT32 PL1Status:1; - /// - /// [Bit 11] Package/Platform-Level PL2 Power Limiting Status (R0) When - /// set, frequency is reduced due to package/platform-level power limiting - /// PL2/PL3. - /// - UINT32 PL2Status:1; - /// - /// [Bit 12] Inefficient Operation Status (R0) When set, processor - /// graphics frequency is operating below target frequency. - /// - UINT32 InefficientOperationStatus:1; - UINT32 Reserved3:3; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved4:3; - /// - /// [Bit 21] Running Average Thermal Limit Log When set, indicates that - /// the RATL Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 RunningAverageThermalLimitLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - /// - /// [Bit 23] VR Thermal Design Current Log When set, indicates that the - /// VR Therm Alert Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 VRThermalDesignCurrentLog:1; - /// - /// [Bit 24] Other Log When set, indicates that the OTHER Status bit has - /// asserted since the log bit was last cleared. This log bit will remain - /// set until cleared by software writing 0. - /// - UINT32 OtherLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 26] Package/Platform-Level PL1 Power Limiting Log When set, - /// indicates that the Package/Platform Level PL1 Power Limiting Status - /// bit has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package/Platform-Level PL2 Power Limiting Log When set, - /// indicates that the Package/Platform Level PL2 Power Limiting Status - /// bit has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PL2Log:1; - /// - /// [Bit 28] Inefficient Operation Log When set, indicates that the - /// Inefficient Operation Status bit has asserted since the log bit was - /// last cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 InefficientOperationLog:1; - UINT32 Reserved6:3; - UINT32 Reserved7:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_GRAPHICS_PERF_LIMIT_REASONS_REGISTER; - - -/** - Package. Indicator of Frequency Clipping in the Ring Interconnect (R/W) - (frequency refers to ring interconnect in the uncore). - - @param ECX MSR_SKYLAKE_RING_PERF_LIMIT_REASONS (0x000006B1) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_RING_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_RING_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_SKYLAKE_RING_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_RING_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_SKYLAKE_RING_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_RING_PERF_LIMIT_REASONS is defined as MSR_RING_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_SKYLAKE_RING_PERF_LIMIT_REASONS 0x000006B1 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_RING_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, frequency is reduced due to - /// assertion of external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced due to a - /// thermal event. - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:3; - /// - /// [Bit 5] Running Average Thermal Limit Status (R0) When set, frequency - /// is reduced due to running average thermal limit. - /// - UINT32 RunningAverageThermalLimitStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced due - /// to a thermal alert from a processor Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - /// - /// [Bit 7] VR Thermal Design Current Status (R0) When set, frequency is - /// reduced due to VR TDC limit. - /// - UINT32 VRThermalDesignCurrentStatus:1; - /// - /// [Bit 8] Other Status (R0) When set, frequency is reduced due to - /// electrical or other constraints. - /// - UINT32 OtherStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 10] Package/Platform-Level Power Limiting PL1 Status (R0) When - /// set, frequency is reduced due to package/Platform-level power limiting - /// PL1. - /// - UINT32 PL1Status:1; - /// - /// [Bit 11] Package/Platform-Level PL2 Power Limiting Status (R0) When - /// set, frequency is reduced due to package/Platform-level power limiting - /// PL2/PL3. - /// - UINT32 PL2Status:1; - UINT32 Reserved3:4; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - UINT32 Reserved4:3; - /// - /// [Bit 21] Running Average Thermal Limit Log When set, indicates that - /// the RATL Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 RunningAverageThermalLimitLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - /// - /// [Bit 23] VR Thermal Design Current Log When set, indicates that the - /// VR Therm Alert Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 VRThermalDesignCurrentLog:1; - /// - /// [Bit 24] Other Log When set, indicates that the OTHER Status bit has - /// asserted since the log bit was last cleared. This log bit will remain - /// set until cleared by software writing 0. - /// - UINT32 OtherLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 26] Package/Platform-Level PL1 Power Limiting Log When set, - /// indicates that the Package/Platform Level PL1 Power Limiting Status - /// bit has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PL1Log:1; - /// - /// [Bit 27] Package/Platform-Level PL2 Power Limiting Log When set, - /// indicates that the Package/Platform Level PL2 Power Limiting Status - /// bit has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PL2Log:1; - UINT32 Reserved6:4; - UINT32 Reserved7:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_RING_PERF_LIMIT_REASONS_REGISTER; - - -/** - Thread. Last Branch Record n To IP (R/W) One of 32 triplets of last branch - record registers on the last branch record stack. This part of the stack - contains pointers to the destination instruction. See also: - Last Branch - Record Stack TOS at 1C9H - Section 17.10. - - @param ECX MSR_SKYLAKE_LASTBRANCH_n_TO_IP - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_16_TO_IP); - AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_16_TO_IP, Msr); - @endcode - @note MSR_SKYLAKE_LASTBRANCH_16_TO_IP is defined as MSR_LASTBRANCH_16_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_17_TO_IP is defined as MSR_LASTBRANCH_17_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_18_TO_IP is defined as MSR_LASTBRANCH_18_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_19_TO_IP is defined as MSR_LASTBRANCH_19_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_20_TO_IP is defined as MSR_LASTBRANCH_20_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_21_TO_IP is defined as MSR_LASTBRANCH_21_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_22_TO_IP is defined as MSR_LASTBRANCH_22_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_23_TO_IP is defined as MSR_LASTBRANCH_23_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_24_TO_IP is defined as MSR_LASTBRANCH_24_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_25_TO_IP is defined as MSR_LASTBRANCH_25_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_26_TO_IP is defined as MSR_LASTBRANCH_26_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_27_TO_IP is defined as MSR_LASTBRANCH_27_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_28_TO_IP is defined as MSR_LASTBRANCH_28_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_29_TO_IP is defined as MSR_LASTBRANCH_29_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_30_TO_IP is defined as MSR_LASTBRANCH_30_TO_IP in SDM. - MSR_SKYLAKE_LASTBRANCH_31_TO_IP is defined as MSR_LASTBRANCH_31_TO_IP in SDM. - @{ -**/ -#define MSR_SKYLAKE_LASTBRANCH_16_TO_IP 0x000006D0 -#define MSR_SKYLAKE_LASTBRANCH_17_TO_IP 0x000006D1 -#define MSR_SKYLAKE_LASTBRANCH_18_TO_IP 0x000006D2 -#define MSR_SKYLAKE_LASTBRANCH_19_TO_IP 0x000006D3 -#define MSR_SKYLAKE_LASTBRANCH_20_TO_IP 0x000006D4 -#define MSR_SKYLAKE_LASTBRANCH_21_TO_IP 0x000006D5 -#define MSR_SKYLAKE_LASTBRANCH_22_TO_IP 0x000006D6 -#define MSR_SKYLAKE_LASTBRANCH_23_TO_IP 0x000006D7 -#define MSR_SKYLAKE_LASTBRANCH_24_TO_IP 0x000006D8 -#define MSR_SKYLAKE_LASTBRANCH_25_TO_IP 0x000006D9 -#define MSR_SKYLAKE_LASTBRANCH_26_TO_IP 0x000006DA -#define MSR_SKYLAKE_LASTBRANCH_27_TO_IP 0x000006DB -#define MSR_SKYLAKE_LASTBRANCH_28_TO_IP 0x000006DC -#define MSR_SKYLAKE_LASTBRANCH_29_TO_IP 0x000006DD -#define MSR_SKYLAKE_LASTBRANCH_30_TO_IP 0x000006DE -#define MSR_SKYLAKE_LASTBRANCH_31_TO_IP 0x000006DF -/// @} - - -/** - Thread. Last Branch Record n Additional Information (R/W) One of 32 triplet - of last branch record registers on the last branch record stack. This part - of the stack contains flag, TSX-related and elapsed cycle information. See - also: - Last Branch Record Stack TOS at 1C9H - Section 17.7.1, "LBR - Stack.". - - @param ECX MSR_SKYLAKE_LBR_INFO_n - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_LBR_INFO_0); - AsmWriteMsr64 (MSR_SKYLAKE_LBR_INFO_0, Msr); - @endcode - @note MSR_SKYLAKE_LBR_INFO_0 is defined as MSR_LBR_INFO_0 in SDM. - MSR_SKYLAKE_LBR_INFO_1 is defined as MSR_LBR_INFO_1 in SDM. - MSR_SKYLAKE_LBR_INFO_2 is defined as MSR_LBR_INFO_2 in SDM. - MSR_SKYLAKE_LBR_INFO_3 is defined as MSR_LBR_INFO_3 in SDM. - MSR_SKYLAKE_LBR_INFO_4 is defined as MSR_LBR_INFO_4 in SDM. - MSR_SKYLAKE_LBR_INFO_5 is defined as MSR_LBR_INFO_5 in SDM. - MSR_SKYLAKE_LBR_INFO_6 is defined as MSR_LBR_INFO_6 in SDM. - MSR_SKYLAKE_LBR_INFO_7 is defined as MSR_LBR_INFO_7 in SDM. - MSR_SKYLAKE_LBR_INFO_8 is defined as MSR_LBR_INFO_8 in SDM. - MSR_SKYLAKE_LBR_INFO_9 is defined as MSR_LBR_INFO_9 in SDM. - MSR_SKYLAKE_LBR_INFO_10 is defined as MSR_LBR_INFO_10 in SDM. - MSR_SKYLAKE_LBR_INFO_11 is defined as MSR_LBR_INFO_11 in SDM. - MSR_SKYLAKE_LBR_INFO_12 is defined as MSR_LBR_INFO_12 in SDM. - MSR_SKYLAKE_LBR_INFO_13 is defined as MSR_LBR_INFO_13 in SDM. - MSR_SKYLAKE_LBR_INFO_14 is defined as MSR_LBR_INFO_14 in SDM. - MSR_SKYLAKE_LBR_INFO_15 is defined as MSR_LBR_INFO_15 in SDM. - MSR_SKYLAKE_LBR_INFO_16 is defined as MSR_LBR_INFO_16 in SDM. - MSR_SKYLAKE_LBR_INFO_17 is defined as MSR_LBR_INFO_17 in SDM. - MSR_SKYLAKE_LBR_INFO_18 is defined as MSR_LBR_INFO_18 in SDM. - MSR_SKYLAKE_LBR_INFO_19 is defined as MSR_LBR_INFO_19 in SDM. - MSR_SKYLAKE_LBR_INFO_20 is defined as MSR_LBR_INFO_20 in SDM. - MSR_SKYLAKE_LBR_INFO_21 is defined as MSR_LBR_INFO_21 in SDM. - MSR_SKYLAKE_LBR_INFO_22 is defined as MSR_LBR_INFO_22 in SDM. - MSR_SKYLAKE_LBR_INFO_23 is defined as MSR_LBR_INFO_23 in SDM. - MSR_SKYLAKE_LBR_INFO_24 is defined as MSR_LBR_INFO_24 in SDM. - MSR_SKYLAKE_LBR_INFO_25 is defined as MSR_LBR_INFO_25 in SDM. - MSR_SKYLAKE_LBR_INFO_26 is defined as MSR_LBR_INFO_26 in SDM. - MSR_SKYLAKE_LBR_INFO_27 is defined as MSR_LBR_INFO_27 in SDM. - MSR_SKYLAKE_LBR_INFO_28 is defined as MSR_LBR_INFO_28 in SDM. - MSR_SKYLAKE_LBR_INFO_29 is defined as MSR_LBR_INFO_29 in SDM. - MSR_SKYLAKE_LBR_INFO_30 is defined as MSR_LBR_INFO_30 in SDM. - MSR_SKYLAKE_LBR_INFO_31 is defined as MSR_LBR_INFO_31 in SDM. - @{ -**/ -#define MSR_SKYLAKE_LBR_INFO_0 0x00000DC0 -#define MSR_SKYLAKE_LBR_INFO_1 0x00000DC1 -#define MSR_SKYLAKE_LBR_INFO_2 0x00000DC2 -#define MSR_SKYLAKE_LBR_INFO_3 0x00000DC3 -#define MSR_SKYLAKE_LBR_INFO_4 0x00000DC4 -#define MSR_SKYLAKE_LBR_INFO_5 0x00000DC5 -#define MSR_SKYLAKE_LBR_INFO_6 0x00000DC6 -#define MSR_SKYLAKE_LBR_INFO_7 0x00000DC7 -#define MSR_SKYLAKE_LBR_INFO_8 0x00000DC8 -#define MSR_SKYLAKE_LBR_INFO_9 0x00000DC9 -#define MSR_SKYLAKE_LBR_INFO_10 0x00000DCA -#define MSR_SKYLAKE_LBR_INFO_11 0x00000DCB -#define MSR_SKYLAKE_LBR_INFO_12 0x00000DCC -#define MSR_SKYLAKE_LBR_INFO_13 0x00000DCD -#define MSR_SKYLAKE_LBR_INFO_14 0x00000DCE -#define MSR_SKYLAKE_LBR_INFO_15 0x00000DCF -#define MSR_SKYLAKE_LBR_INFO_16 0x00000DD0 -#define MSR_SKYLAKE_LBR_INFO_17 0x00000DD1 -#define MSR_SKYLAKE_LBR_INFO_18 0x00000DD2 -#define MSR_SKYLAKE_LBR_INFO_19 0x00000DD3 -#define MSR_SKYLAKE_LBR_INFO_20 0x00000DD4 -#define MSR_SKYLAKE_LBR_INFO_21 0x00000DD5 -#define MSR_SKYLAKE_LBR_INFO_22 0x00000DD6 -#define MSR_SKYLAKE_LBR_INFO_23 0x00000DD7 -#define MSR_SKYLAKE_LBR_INFO_24 0x00000DD8 -#define MSR_SKYLAKE_LBR_INFO_25 0x00000DD9 -#define MSR_SKYLAKE_LBR_INFO_26 0x00000DDA -#define MSR_SKYLAKE_LBR_INFO_27 0x00000DDB -#define MSR_SKYLAKE_LBR_INFO_28 0x00000DDC -#define MSR_SKYLAKE_LBR_INFO_29 0x00000DDD -#define MSR_SKYLAKE_LBR_INFO_30 0x00000DDE -#define MSR_SKYLAKE_LBR_INFO_31 0x00000DDF -/// @} - - -/** - Package. Uncore fixed counter control (R/W). - - @param ECX MSR_SKYLAKE_UNC_PERF_FIXED_CTRL (0x00000394) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_FIXED_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_FIXED_CTRL_REGISTER. - - Example usage - @code - MSR_SKYLAKE_UNC_PERF_FIXED_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_UNC_PERF_FIXED_CTRL); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_PERF_FIXED_CTRL, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_UNC_PERF_FIXED_CTRL is defined as MSR_UNC_PERF_FIXED_CTRL in SDM. -**/ -#define MSR_SKYLAKE_UNC_PERF_FIXED_CTRL 0x00000394 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_UNC_PERF_FIXED_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:20; - /// - /// [Bit 20] Enable overflow propagation. - /// - UINT32 EnableOverflow:1; - UINT32 Reserved2:1; - /// - /// [Bit 22] Enable counting. - /// - UINT32 EnableCounting:1; - UINT32 Reserved3:9; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_UNC_PERF_FIXED_CTRL_REGISTER; - - -/** - Package. Uncore fixed counter. - - @param ECX MSR_SKYLAKE_UNC_PERF_FIXED_CTR (0x00000395) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_FIXED_CTR_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_FIXED_CTR_REGISTER. - - Example usage - @code - MSR_SKYLAKE_UNC_PERF_FIXED_CTR_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_UNC_PERF_FIXED_CTR); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_PERF_FIXED_CTR, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_UNC_PERF_FIXED_CTR is defined as MSR_UNC_PERF_FIXED_CTR in SDM. -**/ -#define MSR_SKYLAKE_UNC_PERF_FIXED_CTR 0x00000395 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_UNC_PERF_FIXED_CTR -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Current count. - /// - UINT32 CurrentCount:32; - /// - /// [Bits 43:32] Current count. - /// - UINT32 CurrentCountHi:12; - UINT32 Reserved:20; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_UNC_PERF_FIXED_CTR_REGISTER; - - -/** - Package. Uncore C-Box configuration information (R/O). - - @param ECX MSR_SKYLAKE_UNC_CBO_CONFIG (0x00000396) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_CBO_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_CBO_CONFIG_REGISTER. - - Example usage - @code - MSR_SKYLAKE_UNC_CBO_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_CONFIG); - @endcode - @note MSR_SKYLAKE_UNC_CBO_CONFIG is defined as MSR_UNC_CBO_CONFIG in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_CONFIG 0x00000396 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_UNC_CBO_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Specifies the number of C-Box units with programmable - /// counters (including processor cores and processor graphics),. - /// - UINT32 CBox:4; - UINT32 Reserved1:28; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_UNC_CBO_CONFIG_REGISTER; - - -/** - Package. Uncore Arb unit, performance counter 0. - - @param ECX MSR_SKYLAKE_UNC_ARB_PERFCTR0 (0x000003B0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_ARB_PERFCTR0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_ARB_PERFCTR0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_ARB_PERFCTR0 is defined as MSR_UNC_ARB_PERFCTR0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_ARB_PERFCTR0 0x000003B0 - - -/** - Package. Uncore Arb unit, performance counter 1. - - @param ECX MSR_SKYLAKE_UNC_ARB_PERFCTR1 (0x000003B1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_ARB_PERFCTR1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_ARB_PERFCTR1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_ARB_PERFCTR1 is defined as MSR_UNC_ARB_PERFCTR1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_ARB_PERFCTR1 0x000003B1 - - -/** - Package. Uncore Arb unit, counter 0 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_ARB_PERFEVTSEL0 (0x000003B2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_ARB_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_ARB_PERFEVTSEL0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_ARB_PERFEVTSEL0 is defined as MSR_UNC_ARB_PERFEVTSEL0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_ARB_PERFEVTSEL0 0x000003B2 - - -/** - Package. Uncore Arb unit, counter 1 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1 (0x000003B3) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1 is defined as MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_ARB_PERFEVTSEL1 0x000003B3 - - -/** - Package. Uncore C-Box 0, counter 0 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL0 (0x00000700) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL0 is defined as MSR_UNC_CBO_0_PERFEVTSEL0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL0 0x00000700 - - -/** - Package. Uncore C-Box 0, counter 1 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL1 (0x00000701) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL1 is defined as MSR_UNC_CBO_0_PERFEVTSEL1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_0_PERFEVTSEL1 0x00000701 - - -/** - Package. Uncore C-Box 0, performance counter 0. - - @param ECX MSR_SKYLAKE_UNC_CBO_0_PERFCTR0 (0x00000706) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFCTR0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFCTR0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_0_PERFCTR0 is defined as MSR_UNC_CBO_0_PERFCTR0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_0_PERFCTR0 0x00000706 - - -/** - Package. Uncore C-Box 0, performance counter 1. - - @param ECX MSR_SKYLAKE_UNC_CBO_0_PERFCTR1 (0x00000707) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFCTR1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_0_PERFCTR1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_0_PERFCTR1 is defined as MSR_UNC_CBO_0_PERFCTR1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_0_PERFCTR1 0x00000707 - - -/** - Package. Uncore C-Box 1, counter 0 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL0 (0x00000710) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL0 is defined as MSR_UNC_CBO_1_PERFEVTSEL0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL0 0x00000710 - - -/** - Package. Uncore C-Box 1, counter 1 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL1 (0x00000711) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL1 is defined as MSR_UNC_CBO_1_PERFEVTSEL1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_1_PERFEVTSEL1 0x00000711 - - -/** - Package. Uncore C-Box 1, performance counter 0. - - @param ECX MSR_SKYLAKE_UNC_CBO_1_PERFCTR0 (0x00000716) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFCTR0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFCTR0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_1_PERFCTR0 is defined as MSR_UNC_CBO_1_PERFCTR0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_1_PERFCTR0 0x00000716 - - -/** - Package. Uncore C-Box 1, performance counter 1. - - @param ECX MSR_SKYLAKE_UNC_CBO_1_PERFCTR1 (0x00000717) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFCTR1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_1_PERFCTR1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_1_PERFCTR1 is defined as MSR_UNC_CBO_1_PERFCTR1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_1_PERFCTR1 0x00000717 - - -/** - Package. Uncore C-Box 2, counter 0 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL0 (0x00000720) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL0 is defined as MSR_UNC_CBO_2_PERFEVTSEL0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL0 0x00000720 - - -/** - Package. Uncore C-Box 2, counter 1 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL1 (0x00000721) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL1 is defined as MSR_UNC_CBO_2_PERFEVTSEL1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_2_PERFEVTSEL1 0x00000721 - - -/** - Package. Uncore C-Box 2, performance counter 0. - - @param ECX MSR_SKYLAKE_UNC_CBO_2_PERFCTR0 (0x00000726) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFCTR0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFCTR0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_2_PERFCTR0 is defined as MSR_UNC_CBO_2_PERFCTR0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_2_PERFCTR0 0x00000726 - - -/** - Package. Uncore C-Box 2, performance counter 1. - - @param ECX MSR_SKYLAKE_UNC_CBO_2_PERFCTR1 (0x00000727) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFCTR1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_2_PERFCTR1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_2_PERFCTR1 is defined as MSR_UNC_CBO_2_PERFCTR1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_2_PERFCTR1 0x00000727 - - -/** - Package. Uncore C-Box 3, counter 0 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL0 (0x00000730) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL0 is defined as MSR_UNC_CBO_3_PERFEVTSEL0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL0 0x00000730 - - -/** - Package. Uncore C-Box 3, counter 1 event select MSR. - - @param ECX MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL1 (0x00000731) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL1 is defined as MSR_UNC_CBO_3_PERFEVTSEL1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_3_PERFEVTSEL1 0x00000731 - - -/** - Package. Uncore C-Box 3, performance counter 0. - - @param ECX MSR_SKYLAKE_UNC_CBO_3_PERFCTR0 (0x00000736) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFCTR0); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFCTR0, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_3_PERFCTR0 is defined as MSR_UNC_CBO_3_PERFCTR0 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_3_PERFCTR0 0x00000736 - - -/** - Package. Uncore C-Box 3, performance counter 1. - - @param ECX MSR_SKYLAKE_UNC_CBO_3_PERFCTR1 (0x00000737) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFCTR1); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_CBO_3_PERFCTR1, Msr); - @endcode - @note MSR_SKYLAKE_UNC_CBO_3_PERFCTR1 is defined as MSR_UNC_CBO_3_PERFCTR1 in SDM. -**/ -#define MSR_SKYLAKE_UNC_CBO_3_PERFCTR1 0x00000737 - - -/** - Package. Uncore PMU global control. - - @param ECX MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL (0x00000E01) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL_REGISTER. - - Example usage - @code - MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL is defined as MSR_UNC_PERF_GLOBAL_CTRL in SDM. -**/ -#define MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL 0x00000E01 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Slice 0 select. - /// - UINT32 PMI_Sel_Slice0:1; - /// - /// [Bit 1] Slice 1 select. - /// - UINT32 PMI_Sel_Slice1:1; - /// - /// [Bit 2] Slice 2 select. - /// - UINT32 PMI_Sel_Slice2:1; - /// - /// [Bit 3] Slice 3 select. - /// - UINT32 PMI_Sel_Slice3:1; - /// - /// [Bit 4] Slice 4select. - /// - UINT32 PMI_Sel_Slice4:1; - UINT32 Reserved1:14; - UINT32 Reserved2:10; - /// - /// [Bit 29] Enable all uncore counters. - /// - UINT32 EN:1; - /// - /// [Bit 30] Enable wake on PMI. - /// - UINT32 WakePMI:1; - /// - /// [Bit 31] Enable Freezing counter when overflow. - /// - UINT32 FREEZE:1; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_UNC_PERF_GLOBAL_CTRL_REGISTER; - - -/** - Package. Uncore PMU main status. - - @param ECX MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS (0x00000E02) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS_REGISTER. - - Example usage - @code - MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS); - AsmWriteMsr64 (MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS, Msr.Uint64); - @endcode - @note MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS is defined as MSR_UNC_PERF_GLOBAL_STATUS in SDM. -**/ -#define MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS 0x00000E02 - -/** - MSR information returned for MSR index #MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fixed counter overflowed. - /// - UINT32 Fixed:1; - /// - /// [Bit 1] An ARB counter overflowed. - /// - UINT32 ARB:1; - UINT32 Reserved1:1; - /// - /// [Bit 3] A CBox counter overflowed (on any slice). - /// - UINT32 CBox:1; - UINT32 Reserved2:28; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_SKYLAKE_UNC_PERF_GLOBAL_STATUS_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h deleted file mode 100644 index ad7128ae9..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h +++ /dev/null @@ -1,203 +0,0 @@ -/** @file - MSR Definitions for Intel(R) Xeon(R) Processor Series 5600. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.7. - -**/ - -#ifndef __XEON_5600_MSR_H__ -#define __XEON_5600_MSR_H__ - -#include - -/** - Is Intel(R) Xeon(R) Processor Series 5600? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_XEON_5600_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x25 || \ - DisplayModel == 0x2C \ - ) \ - ) - -/** - Core. AES Configuration (RW-L) Privileged post-BIOS agent must provide a #GP - handler to handle unsuccessful read of this MSR. - - @param ECX MSR_XEON_5600_FEATURE_CONFIG (0x0000013C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_5600_FEATURE_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_5600_FEATURE_CONFIG_REGISTER. - - Example usage - @code - MSR_XEON_5600_FEATURE_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_5600_FEATURE_CONFIG); - AsmWriteMsr64 (MSR_XEON_5600_FEATURE_CONFIG, Msr.Uint64); - @endcode - @note MSR_XEON_5600_FEATURE_CONFIG is defined as MSR_FEATURE_CONFIG in SDM. -**/ -#define MSR_XEON_5600_FEATURE_CONFIG 0x0000013C - -/** - MSR information returned for MSR index #MSR_XEON_5600_FEATURE_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] AES Configuration (RW-L) Upon a successful read of this - /// MSR, the configuration of AES instruction set availability is as - /// follows: 11b: AES instructions are not available until next RESET. - /// otherwise, AES instructions are available. Note, AES instruction set - /// is not available if read is unsuccessful. If the configuration is not - /// 01b, AES instruction can be mis-configured if a privileged agent - /// unintentionally writes 11b. - /// - UINT32 AESConfiguration:2; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_5600_FEATURE_CONFIG_REGISTER; - - -/** - Thread. Offcore Response Event Select Register (R/W). - - @param ECX MSR_XEON_5600_OFFCORE_RSP_1 (0x000001A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_5600_OFFCORE_RSP_1); - AsmWriteMsr64 (MSR_XEON_5600_OFFCORE_RSP_1, Msr); - @endcode - @note MSR_XEON_5600_OFFCORE_RSP_1 is defined as MSR_OFFCORE_RSP_1 in SDM. -**/ -#define MSR_XEON_5600_OFFCORE_RSP_1 0x000001A7 - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_XEON_5600_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_5600_TURBO_RATIO_LIMIT); - @endcode - @note MSR_XEON_5600_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_XEON_5600_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C Maximum turbo ratio - /// limit of 1 core active. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C Maximum turbo ratio - /// limit of 2 core active. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C Maximum turbo ratio - /// limit of 3 core active. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C Maximum turbo ratio - /// limit of 4 core active. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C Maximum turbo ratio - /// limit of 5 core active. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C Maximum turbo ratio - /// limit of 6 core active. - /// - UINT32 Maximum6C:8; - UINT32 Reserved:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. See Table 35-2. - - @param ECX MSR_XEON_5600_IA32_ENERGY_PERF_BIAS (0x000001B0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_5600_IA32_ENERGY_PERF_BIAS); - AsmWriteMsr64 (MSR_XEON_5600_IA32_ENERGY_PERF_BIAS, Msr); - @endcode - @note MSR_XEON_5600_IA32_ENERGY_PERF_BIAS is defined as IA32_ENERGY_PERF_BIAS in SDM. -**/ -#define MSR_XEON_5600_IA32_ENERGY_PERF_BIAS 0x000001B0 - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h deleted file mode 100644 index 7b31288a3..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h +++ /dev/null @@ -1,1219 +0,0 @@ -/** @file - MSR Definitions for Intel(R) Xeon(R) Processor D product Family. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.14. - -**/ - -#ifndef __XEON_D_MSR_H__ -#define __XEON_D_MSR_H__ - -#include - -/** - Is Intel(R) Xeon(R) Processor D product Family? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_XEON_D_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x4F || \ - DisplayModel == 0x56 \ - ) \ - ) - -/** - Package. Protected Processor Inventory Number Enable Control (R/W). - - @param ECX MSR_XEON_D_PPIN_CTL (0x0000004E) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_PPIN_CTL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_PPIN_CTL_REGISTER. - - Example usage - @code - MSR_XEON_D_PPIN_CTL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PPIN_CTL); - AsmWriteMsr64 (MSR_XEON_D_PPIN_CTL, Msr.Uint64); - @endcode - @note MSR_XEON_D_PPIN_CTL is defined as MSR_PPIN_CTL in SDM. -**/ -#define MSR_XEON_D_PPIN_CTL 0x0000004E - -/** - MSR information returned for MSR index #MSR_XEON_D_PPIN_CTL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] LockOut (R/WO) See Table 35-24. - /// - UINT32 LockOut:1; - /// - /// [Bit 1] Enable_PPIN (R/W) See Table 35-24. - /// - UINT32 Enable_PPIN:1; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_PPIN_CTL_REGISTER; - - -/** - Package. Protected Processor Inventory Number (R/O). Protected Processor - Inventory Number (R/O) See Table 35-24. - - @param ECX MSR_XEON_D_PPIN (0x0000004F) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_D_PPIN); - @endcode - @note MSR_XEON_D_PPIN is defined as MSR_PPIN in SDM. -**/ -#define MSR_XEON_D_PPIN 0x0000004F - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_XEON_D_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_XEON_D_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PLATFORM_INFO); - AsmWriteMsr64 (MSR_XEON_D_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_XEON_D_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_XEON_D_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_XEON_D_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) See Table 35-24. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:7; - /// - /// [Bit 23] Package. PPIN_CAP (R/O) See Table 35-24. - /// - UINT32 PPIN_CAP:1; - UINT32 Reserved3:4; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) See - /// Table 35-24. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) See - /// Table 35-24. - /// - UINT32 TDPLimit:1; - /// - /// [Bit 30] Package. Programmable TJ OFFSET (R/O) See Table 35-24. - /// - UINT32 TJOFFSET:1; - UINT32 Reserved4:1; - UINT32 Reserved5:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) See Table 35-24. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved6:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_PLATFORM_INFO_REGISTER; - - -/** - Core. C-State Configuration Control (R/W) Note: C-state values are processor - specific C-state code names, unrelated to MWAIT extension C-state parameters - or ACPI C-states. `See http://biosbits.org. `__. - - @param ECX MSR_XEON_D_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_XEON_D_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_XEON_D_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_XEON_D_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_XEON_D_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_XEON_D_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) Specifies the lowest - /// processor-specific C-state code name (consuming the least power) for - /// the package. The default is set as factory-configured package C-state - /// limit. The following C-state code name encodings are supported: 000b: - /// C0/C1 (no package C-state support) 001b: C2 010b: C6 (non-retention) - /// 011b: C6 (retention) 111b: No Package C state limits. All C states - /// supported by the processor are available. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W). - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO). - /// - UINT32 CFGLock:1; - /// - /// [Bit 16] Automatic C-State Conversion Enable (R/W) If 1, the processor - /// will convert HALT or MWAT(C1) to MWAIT(C6). - /// - UINT32 CStateConversion:1; - UINT32 Reserved3:8; - /// - /// [Bit 25] C3 State Auto Demotion Enable (R/W). - /// - UINT32 C3AutoDemotion:1; - /// - /// [Bit 26] C1 State Auto Demotion Enable (R/W). - /// - UINT32 C1AutoDemotion:1; - /// - /// [Bit 27] Enable C3 Undemotion (R/W). - /// - UINT32 C3Undemotion:1; - /// - /// [Bit 28] Enable C1 Undemotion (R/W). - /// - UINT32 C1Undemotion:1; - /// - /// [Bit 29] Package C State Demotion Enable (R/W). - /// - UINT32 CStateDemotion:1; - /// - /// [Bit 30] Package C State UnDemotion Enable (R/W). - /// - UINT32 CStateUndemotion:1; - UINT32 Reserved4:1; - UINT32 Reserved5:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Thread. Global Machine Check Capability (R/O). - - @param ECX MSR_XEON_D_IA32_MCG_CAP (0x00000179) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_MCG_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_MCG_CAP_REGISTER. - - Example usage - @code - MSR_XEON_D_IA32_MCG_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_MCG_CAP); - @endcode - @note MSR_XEON_D_IA32_MCG_CAP is defined as IA32_MCG_CAP in SDM. -**/ -#define MSR_XEON_D_IA32_MCG_CAP 0x00000179 - -/** - MSR information returned for MSR index #MSR_XEON_D_IA32_MCG_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Count. - /// - UINT32 Count:8; - /// - /// [Bit 8] MCG_CTL_P. - /// - UINT32 MCG_CTL_P:1; - /// - /// [Bit 9] MCG_EXT_P. - /// - UINT32 MCG_EXT_P:1; - /// - /// [Bit 10] MCP_CMCI_P. - /// - UINT32 MCP_CMCI_P:1; - /// - /// [Bit 11] MCG_TES_P. - /// - UINT32 MCG_TES_P:1; - UINT32 Reserved1:4; - /// - /// [Bits 23:16] MCG_EXT_CNT. - /// - UINT32 MCG_EXT_CNT:8; - /// - /// [Bit 24] MCG_SER_P. - /// - UINT32 MCG_SER_P:1; - /// - /// [Bit 25] MCG_EM_P. - /// - UINT32 MCG_EM_P:1; - /// - /// [Bit 26] MCG_ELOG_P. - /// - UINT32 MCG_ELOG_P:1; - UINT32 Reserved2:5; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_IA32_MCG_CAP_REGISTER; - - -/** - THREAD. Enhanced SMM Capabilities (SMM-RO) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_XEON_D_SMM_MCA_CAP (0x0000017D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_SMM_MCA_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_SMM_MCA_CAP_REGISTER. - - Example usage - @code - MSR_XEON_D_SMM_MCA_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_SMM_MCA_CAP); - AsmWriteMsr64 (MSR_XEON_D_SMM_MCA_CAP, Msr.Uint64); - @endcode - @note MSR_XEON_D_SMM_MCA_CAP is defined as MSR_SMM_MCA_CAP in SDM. -**/ -#define MSR_XEON_D_SMM_MCA_CAP 0x0000017D - -/** - MSR information returned for MSR index #MSR_XEON_D_SMM_MCA_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:26; - /// - /// [Bit 58] SMM_Code_Access_Chk (SMM-RO) If set to 1 indicates that the - /// SMM code access restriction is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 SMM_Code_Access_Chk:1; - /// - /// [Bit 59] Long_Flow_Indication (SMM-RO) If set to 1 indicates that the - /// SMM long flow indicator is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 Long_Flow_Indication:1; - UINT32 Reserved3:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_SMM_MCA_CAP_REGISTER; - - -/** - Package. - - @param ECX MSR_XEON_D_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_XEON_D_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_XEON_D_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_XEON_D_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_XEON_D_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_XEON_D_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (RO) See Table 35-24. - /// - UINT32 TemperatureTarget:8; - /// - /// [Bits 27:24] TCC Activation Offset (R/W) See Table 35-24. - /// - UINT32 TCCActivationOffset:4; - UINT32 Reserved2:4; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_TEMPERATURE_TARGET_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_XEON_D_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_XEON_D_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT); - @endcode - @note MSR_XEON_D_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_XEON_D_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_XEON_D_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 1C. - /// - UINT32 Maximum1C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 2C. - /// - UINT32 Maximum2C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 3C. - /// - UINT32 Maximum3C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 4C. - /// - UINT32 Maximum4C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 5C. - /// - UINT32 Maximum5C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 6C. - /// - UINT32 Maximum6C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 7C. - /// - UINT32 Maximum7C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for 8C. - /// - UINT32 Maximum8C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Package. Maximum Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_XEON_D_TURBO_RATIO_LIMIT1 (0x000001AE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT1_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT1_REGISTER. - - Example usage - @code - MSR_XEON_D_TURBO_RATIO_LIMIT1_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT1); - @endcode - @note MSR_XEON_D_TURBO_RATIO_LIMIT1 is defined as MSR_TURBO_RATIO_LIMIT1 in SDM. -**/ -#define MSR_XEON_D_TURBO_RATIO_LIMIT1 0x000001AE - -/** - MSR information returned for MSR index #MSR_XEON_D_TURBO_RATIO_LIMIT1 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] Package. Maximum Ratio Limit for 9C. - /// - UINT32 Maximum9C:8; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for 10C. - /// - UINT32 Maximum10C:8; - /// - /// [Bits 23:16] Package. Maximum Ratio Limit for 11C. - /// - UINT32 Maximum11C:8; - /// - /// [Bits 31:24] Package. Maximum Ratio Limit for 12C. - /// - UINT32 Maximum12C:8; - /// - /// [Bits 39:32] Package. Maximum Ratio Limit for 13C. - /// - UINT32 Maximum13C:8; - /// - /// [Bits 47:40] Package. Maximum Ratio Limit for 14C. - /// - UINT32 Maximum14C:8; - /// - /// [Bits 55:48] Package. Maximum Ratio Limit for 15C. - /// - UINT32 Maximum15C:8; - /// - /// [Bits 63:56] Package. Maximum Ratio Limit for 16C. - /// - UINT32 Maximum16C:8; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_TURBO_RATIO_LIMIT1_REGISTER; - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O). - - @param ECX MSR_XEON_D_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_XEON_D_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_RAPL_POWER_UNIT); - @endcode - @note MSR_XEON_D_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_XEON_D_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_XEON_D_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package. Power Units See Section 14.9.1, "RAPL Interfaces.". - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Package. Energy Status Units Energy related information - /// (in Joules) is based on the multiplier, 1/2^ESU; where ESU is an - /// unsigned integer represented by bits 12:8. Default value is 0EH (or 61 - /// micro-joules). - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Package. Time Units See Section 14.9.1, "RAPL - /// Interfaces.". - /// - UINT32 TimeUnits:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_XEON_D_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_XEON_D_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_XEON_D_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_XEON_D_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) Energy consumed by DRAM devices. - - @param ECX MSR_XEON_D_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_DRAM_ENERGY_STATUS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_DRAM_ENERGY_STATUS_REGISTER. - - Example usage - @code - MSR_XEON_D_DRAM_ENERGY_STATUS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_DRAM_ENERGY_STATUS); - @endcode - @note MSR_XEON_D_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_XEON_D_DRAM_ENERGY_STATUS 0x00000619 - -/** - MSR information returned for MSR index #MSR_XEON_D_DRAM_ENERGY_STATUS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] Energy in 15.3 micro-joules. Requires BIOS configuration - /// to enable DRAM RAPL mode 0 (Direct VR). - /// - UINT32 Energy:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_DRAM_ENERGY_STATUS_REGISTER; - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_XEON_D_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_PERF_STATUS); - @endcode - @note MSR_XEON_D_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_XEON_D_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_XEON_D_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_XEON_D_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_XEON_D_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_XEON_D_DRAM_POWER_INFO 0x0000061C - - -/** - Package. Reserved (R/O) Reads return 0. - - @param ECX MSR_XEON_D_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_D_PP0_ENERGY_STATUS); - @endcode - @note MSR_XEON_D_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_XEON_D_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_XEON_D_CORE_PERF_LIMIT_REASONS (0x00000690) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_XEON_D_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_XEON_D_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_XEON_D_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_XEON_D_CORE_PERF_LIMIT_REASONS 0x00000690 - -/** - MSR information returned for MSR index #MSR_XEON_D_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0) When set, processor core frequency is - /// reduced below the operating system request due to assertion of - /// external PROCHOT. - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0) When set, frequency is reduced below the - /// operating system request due to a thermal event. - /// - UINT32 ThermalStatus:1; - /// - /// [Bit 2] Power Budget Management Status (R0) When set, frequency is - /// reduced below the operating system request due to PBM limit. - /// - UINT32 PowerBudgetManagementStatus:1; - /// - /// [Bit 3] Platform Configuration Services Status (R0) When set, - /// frequency is reduced below the operating system request due to PCS - /// limit. - /// - UINT32 PlatformConfigurationServicesStatus:1; - UINT32 Reserved1:1; - /// - /// [Bit 5] Autonomous Utilization-Based Frequency Control Status (R0) - /// When set, frequency is reduced below the operating system request - /// because the processor has detected that utilization is low. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlStatus:1; - /// - /// [Bit 6] VR Therm Alert Status (R0) When set, frequency is reduced - /// below the operating system request due to a thermal alert from the - /// Voltage Regulator. - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0) When set, frequency is - /// reduced below the operating system request due to electrical design - /// point constraints (e.g. maximum electrical current consumption). - /// - UINT32 ElectricalDesignPointStatus:1; - UINT32 Reserved3:1; - /// - /// [Bit 10] Multi-Core Turbo Status (R0) When set, frequency is reduced - /// below the operating system request due to Multi-Core Turbo limits. - /// - UINT32 MultiCoreTurboStatus:1; - UINT32 Reserved4:2; - /// - /// [Bit 13] Core Frequency P1 Status (R0) When set, frequency is reduced - /// below max non-turbo P1. - /// - UINT32 FrequencyP1Status:1; - /// - /// [Bit 14] Core Max n-core Turbo Frequency Limiting Status (R0) When - /// set, frequency is reduced below max n-core turbo frequency. - /// - UINT32 TurboFrequencyLimitingStatus:1; - /// - /// [Bit 15] Core Frequency Limiting Status (R0) When set, frequency is - /// reduced below the operating system request. - /// - UINT32 FrequencyLimitingStatus:1; - /// - /// [Bit 16] PROCHOT Log When set, indicates that the PROCHOT Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 PROCHOT_Log:1; - /// - /// [Bit 17] Thermal Log When set, indicates that the Thermal Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 ThermalLog:1; - /// - /// [Bit 18] Power Budget Management Log When set, indicates that the PBM - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 PowerBudgetManagementLog:1; - /// - /// [Bit 19] Platform Configuration Services Log When set, indicates that - /// the PCS Status bit has asserted since the log bit was last cleared. - /// This log bit will remain set until cleared by software writing 0. - /// - UINT32 PlatformConfigurationServicesLog:1; - UINT32 Reserved5:1; - /// - /// [Bit 21] Autonomous Utilization-Based Frequency Control Log When set, - /// indicates that the AUBFC Status bit has asserted since the log bit was - /// last cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 AutonomousUtilizationBasedFrequencyControlLog:1; - /// - /// [Bit 22] VR Therm Alert Log When set, indicates that the VR Therm - /// Alert Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 VRThermAlertLog:1; - UINT32 Reserved6:1; - /// - /// [Bit 24] Electrical Design Point Log When set, indicates that the EDP - /// Status bit has asserted since the log bit was last cleared. This log - /// bit will remain set until cleared by software writing 0. - /// - UINT32 ElectricalDesignPointLog:1; - UINT32 Reserved7:1; - /// - /// [Bit 26] Multi-Core Turbo Log When set, indicates that the Multi-Core - /// Turbo Status bit has asserted since the log bit was last cleared. This - /// log bit will remain set until cleared by software writing 0. - /// - UINT32 MultiCoreTurboLog:1; - UINT32 Reserved8:2; - /// - /// [Bit 29] Core Frequency P1 Log When set, indicates that the Core - /// Frequency P1 Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CoreFrequencyP1Log:1; - /// - /// [Bit 30] Core Max n-core Turbo Frequency Limiting Log When set, - /// indicates that the Core Max n-core Turbo Frequency Limiting Status bit - /// has asserted since the log bit was last cleared. This log bit will - /// remain set until cleared by software writing 0. - /// - UINT32 TurboFrequencyLimitingLog:1; - /// - /// [Bit 31] Core Frequency Limiting Log When set, indicates that the Core - /// Frequency Limiting Status bit has asserted since the log bit was last - /// cleared. This log bit will remain set until cleared by software - /// writing 0. - /// - UINT32 CoreFrequencyLimitingLog:1; - UINT32 Reserved9:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_CORE_PERF_LIMIT_REASONS_REGISTER; - - -/** - THREAD. Monitoring Event Select Register (R/W) if CPUID.(EAX=07H, - ECX=0):EBX.RDT-M[bit 12] = 1. - - @param ECX MSR_XEON_D_IA32_QM_EVTSEL (0x00000C8D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_QM_EVTSEL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_QM_EVTSEL_REGISTER. - - Example usage - @code - MSR_XEON_D_IA32_QM_EVTSEL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_QM_EVTSEL); - AsmWriteMsr64 (MSR_XEON_D_IA32_QM_EVTSEL, Msr.Uint64); - @endcode - @note MSR_XEON_D_IA32_QM_EVTSEL is defined as IA32_QM_EVTSEL in SDM. -**/ -#define MSR_XEON_D_IA32_QM_EVTSEL 0x00000C8D - -/** - MSR information returned for MSR index #MSR_XEON_D_IA32_QM_EVTSEL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 7:0] EventID (RW) Event encoding: 0x00: no monitoring 0x01: L3 - /// occupancy monitoring 0x02: Total memory bandwidth monitoring 0x03: - /// Local memory bandwidth monitoring All other encoding reserved. - /// - UINT32 EventID:8; - UINT32 Reserved1:24; - /// - /// [Bits 41:32] RMID (RW). - /// - UINT32 RMID:10; - UINT32 Reserved2:22; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_IA32_QM_EVTSEL_REGISTER; - - -/** - THREAD. Resource Association Register (R/W). - - @param ECX MSR_XEON_D_IA32_PQR_ASSOC (0x00000C8F) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_PQR_ASSOC_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_PQR_ASSOC_REGISTER. - - Example usage - @code - MSR_XEON_D_IA32_PQR_ASSOC_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_PQR_ASSOC); - AsmWriteMsr64 (MSR_XEON_D_IA32_PQR_ASSOC, Msr.Uint64); - @endcode - @note MSR_XEON_D_IA32_PQR_ASSOC is defined as IA32_PQR_ASSOC in SDM. -**/ -#define MSR_XEON_D_IA32_PQR_ASSOC 0x00000C8F - -/** - MSR information returned for MSR index #MSR_XEON_D_IA32_PQR_ASSOC -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 9:0] RMID. - /// - UINT32 RMID:10; - UINT32 Reserved1:22; - /// - /// [Bits 51:32] COS (R/W). - /// - UINT32 COS:20; - UINT32 Reserved2:12; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_IA32_PQR_ASSOC_REGISTER; - - -/** - Package. L3 Class Of Service Mask - COS n (R/W) if CPUID.(EAX=10H, - ECX=1):EDX.COS_MAX[15:0] >= n. - - @param ECX MSR_XEON_D_IA32_L3_QOS_MASK_n - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_L3_QOS_MASK_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_L3_QOS_MASK_REGISTER. - - Example usage - @code - MSR_XEON_D_IA32_L3_QOS_MASK_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_L3_QOS_MASK_0); - AsmWriteMsr64 (MSR_XEON_D_IA32_L3_QOS_MASK_0, Msr.Uint64); - @endcode - @note MSR_XEON_D_IA32_L3_QOS_MASK_0 is defined as IA32_L3_QOS_MASK_0 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_1 is defined as IA32_L3_QOS_MASK_1 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_2 is defined as IA32_L3_QOS_MASK_2 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_3 is defined as IA32_L3_QOS_MASK_3 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_4 is defined as IA32_L3_QOS_MASK_4 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_5 is defined as IA32_L3_QOS_MASK_5 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_6 is defined as IA32_L3_QOS_MASK_6 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_7 is defined as IA32_L3_QOS_MASK_7 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_8 is defined as IA32_L3_QOS_MASK_8 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_9 is defined as IA32_L3_QOS_MASK_9 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_10 is defined as IA32_L3_QOS_MASK_10 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_11 is defined as IA32_L3_QOS_MASK_11 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_12 is defined as IA32_L3_QOS_MASK_12 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_13 is defined as IA32_L3_QOS_MASK_13 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_14 is defined as IA32_L3_QOS_MASK_14 in SDM. - MSR_XEON_D_IA32_L3_QOS_MASK_15 is defined as IA32_L3_QOS_MASK_15 in SDM. - @{ -**/ -#define MSR_XEON_D_IA32_L3_QOS_MASK_0 0x00000C90 -#define MSR_XEON_D_IA32_L3_QOS_MASK_1 0x00000C91 -#define MSR_XEON_D_IA32_L3_QOS_MASK_2 0x00000C92 -#define MSR_XEON_D_IA32_L3_QOS_MASK_3 0x00000C93 -#define MSR_XEON_D_IA32_L3_QOS_MASK_4 0x00000C94 -#define MSR_XEON_D_IA32_L3_QOS_MASK_5 0x00000C95 -#define MSR_XEON_D_IA32_L3_QOS_MASK_6 0x00000C96 -#define MSR_XEON_D_IA32_L3_QOS_MASK_7 0x00000C97 -#define MSR_XEON_D_IA32_L3_QOS_MASK_8 0x00000C98 -#define MSR_XEON_D_IA32_L3_QOS_MASK_9 0x00000C99 -#define MSR_XEON_D_IA32_L3_QOS_MASK_10 0x00000C9A -#define MSR_XEON_D_IA32_L3_QOS_MASK_11 0x00000C9B -#define MSR_XEON_D_IA32_L3_QOS_MASK_12 0x00000C9C -#define MSR_XEON_D_IA32_L3_QOS_MASK_13 0x00000C9D -#define MSR_XEON_D_IA32_L3_QOS_MASK_14 0x00000C9E -#define MSR_XEON_D_IA32_L3_QOS_MASK_15 0x00000C9F -/// @} - -/** - MSR information returned for MSR indexes #MSR_XEON_D_IA32_L3_QOS_MASK_0 - to #MSR_XEON_D_IA32_L3_QOS_MASK_15. -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 19:0] CBM: Bit vector of available L3 ways for COS 0 enforcement. - /// - UINT32 CBM:20; - UINT32 Reserved2:12; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_IA32_L3_QOS_MASK_REGISTER; - - -/** - Package. Config Ratio Limit of Turbo Mode RO if MSR_PLATFORM_INFO.[28] = 0, - RW if MSR_PLATFORM_INFO.[28] = 1. - - @param ECX MSR_XEON_D_TURBO_RATIO_LIMIT3 (0x000001AC) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT3_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_TURBO_RATIO_LIMIT3_REGISTER. - - Example usage - @code - MSR_XEON_D_TURBO_RATIO_LIMIT3_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT3); - @endcode - @note MSR_XEON_D_TURBO_RATIO_LIMIT3 is defined as MSR_TURBO_RATIO_LIMIT3 in SDM. -**/ -#define MSR_XEON_D_TURBO_RATIO_LIMIT3 0x000001AC - -/** - MSR information returned for MSR index #MSR_XEON_D_TURBO_RATIO_LIMIT3 -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:31; - /// - /// [Bit 63] Package. Semaphore for Turbo Ratio Limit Configuration If 1, - /// the processor uses override configuration specified in - /// MSR_TURBO_RATIO_LIMIT, MSR_TURBO_RATIO_LIMIT1. If 0, the processor - /// uses factory-set configuration (Default). - /// - UINT32 TurboRatioLimitConfigurationSemaphore:1; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_TURBO_RATIO_LIMIT3_REGISTER; - - -/** - Package. Cache Allocation Technology Configuration (R/W). - - @param ECX MSR_XEON_D_IA32_L3_QOS_CFG (0x00000C81) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_L3_QOS_CFG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_D_IA32_L3_QOS_CFG_REGISTER. - - Example usage - @code - MSR_XEON_D_IA32_L3_QOS_CFG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_L3_QOS_CFG); - AsmWriteMsr64 (MSR_XEON_D_IA32_L3_QOS_CFG, Msr.Uint64); - @endcode - @note MSR_XEON_D_IA32_L3_QOS_CFG is defined as IA32_L3_QOS_CFG in SDM. -**/ -#define MSR_XEON_D_IA32_L3_QOS_CFG 0x00000C81 - -/** - MSR information returned for MSR index #MSR_XEON_D_IA32_L3_QOS_CFG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] CAT Enable. Set 1 to enable Cache Allocation Technology. - /// - UINT32 CAT:1; - UINT32 Reserved1:31; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_D_IA32_L3_QOS_CFG_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h deleted file mode 100644 index d509660c5..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h +++ /dev/null @@ -1,373 +0,0 @@ -/** @file - MSR Definitions for Intel(R) Xeon(R) Processor E7 Family. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.8. - -**/ - -#ifndef __XEON_E7_MSR_H__ -#define __XEON_E7_MSR_H__ - -#include - -/** - Is Intel(R) Xeon(R) Processor E7 Family? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_XEON_E7_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x2F \ - ) \ - ) - -/** - Core. AES Configuration (RW-L) Privileged post-BIOS agent must provide a #GP - handler to handle unsuccessful read of this MSR. - - @param ECX MSR_XEON_E7_FEATURE_CONFIG (0x0000013C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_E7_FEATURE_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_E7_FEATURE_CONFIG_REGISTER. - - Example usage - @code - MSR_XEON_E7_FEATURE_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_E7_FEATURE_CONFIG); - AsmWriteMsr64 (MSR_XEON_E7_FEATURE_CONFIG, Msr.Uint64); - @endcode - @note MSR_XEON_E7_FEATURE_CONFIG is defined as MSR_FEATURE_CONFIG in SDM. -**/ -#define MSR_XEON_E7_FEATURE_CONFIG 0x0000013C - -/** - MSR information returned for MSR index #MSR_XEON_E7_FEATURE_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] AES Configuration (RW-L) Upon a successful read of this - /// MSR, the configuration of AES instruction set availability is as - /// follows: 11b: AES instructions are not available until next RESET. - /// otherwise, AES instructions are available. Note, AES instruction set - /// is not available if read is unsuccessful. If the configuration is not - /// 01b, AES instruction can be mis-configured if a privileged agent - /// unintentionally writes 11b. - /// - UINT32 AESConfiguration:2; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_E7_FEATURE_CONFIG_REGISTER; - - -/** - Thread. Offcore Response Event Select Register (R/W). - - @param ECX MSR_XEON_E7_OFFCORE_RSP_1 (0x000001A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_OFFCORE_RSP_1); - AsmWriteMsr64 (MSR_XEON_E7_OFFCORE_RSP_1, Msr); - @endcode - @note MSR_XEON_E7_OFFCORE_RSP_1 is defined as MSR_OFFCORE_RSP_1 in SDM. -**/ -#define MSR_XEON_E7_OFFCORE_RSP_1 0x000001A7 - - -/** - Package. Reserved Attempt to read/write will cause #UD. - - @param ECX MSR_XEON_E7_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_TURBO_RATIO_LIMIT); - AsmWriteMsr64 (MSR_XEON_E7_TURBO_RATIO_LIMIT, Msr); - @endcode - @note MSR_XEON_E7_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_XEON_E7_TURBO_RATIO_LIMIT 0x000001AD - - -/** - Package. Uncore C-box 8 perfmon local box control MSR. - - @param ECX MSR_XEON_E7_C8_PMON_BOX_CTRL (0x00000F40) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_XEON_E7_C8_PMON_BOX_CTRL is defined as MSR_C8_PMON_BOX_CTRL in SDM. -**/ -#define MSR_XEON_E7_C8_PMON_BOX_CTRL 0x00000F40 - - -/** - Package. Uncore C-box 8 perfmon local box status MSR. - - @param ECX MSR_XEON_E7_C8_PMON_BOX_STATUS (0x00000F41) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_XEON_E7_C8_PMON_BOX_STATUS is defined as MSR_C8_PMON_BOX_STATUS in SDM. -**/ -#define MSR_XEON_E7_C8_PMON_BOX_STATUS 0x00000F41 - - -/** - Package. Uncore C-box 8 perfmon local box overflow control MSR. - - @param ECX MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL (0x00000F42) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL is defined as MSR_C8_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL 0x00000F42 - - -/** - Package. Uncore C-box 8 perfmon event select MSR. - - @param ECX MSR_XEON_E7_C8_PMON_EVNT_SELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_XEON_E7_C8_PMON_EVNT_SEL0 is defined as MSR_C8_PMON_EVNT_SEL0 in SDM. - MSR_XEON_E7_C8_PMON_EVNT_SEL1 is defined as MSR_C8_PMON_EVNT_SEL1 in SDM. - MSR_XEON_E7_C8_PMON_EVNT_SEL2 is defined as MSR_C8_PMON_EVNT_SEL2 in SDM. - MSR_XEON_E7_C8_PMON_EVNT_SEL3 is defined as MSR_C8_PMON_EVNT_SEL3 in SDM. - MSR_XEON_E7_C8_PMON_EVNT_SEL4 is defined as MSR_C8_PMON_EVNT_SEL4 in SDM. - MSR_XEON_E7_C8_PMON_EVNT_SEL5 is defined as MSR_C8_PMON_EVNT_SEL5 in SDM. - @{ -**/ -#define MSR_XEON_E7_C8_PMON_EVNT_SEL0 0x00000F50 -#define MSR_XEON_E7_C8_PMON_EVNT_SEL1 0x00000F52 -#define MSR_XEON_E7_C8_PMON_EVNT_SEL2 0x00000F54 -#define MSR_XEON_E7_C8_PMON_EVNT_SEL3 0x00000F56 -#define MSR_XEON_E7_C8_PMON_EVNT_SEL4 0x00000F58 -#define MSR_XEON_E7_C8_PMON_EVNT_SEL5 0x00000F5A -/// @} - - -/** - Package. Uncore C-box 8 perfmon counter MSR. - - @param ECX MSR_XEON_E7_C8_PMON_CTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_CTR0); - AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_CTR0, Msr); - @endcode - @note MSR_XEON_E7_C8_PMON_CTR0 is defined as MSR_C8_PMON_CTR0 in SDM. - MSR_XEON_E7_C8_PMON_CTR1 is defined as MSR_C8_PMON_CTR1 in SDM. - MSR_XEON_E7_C8_PMON_CTR2 is defined as MSR_C8_PMON_CTR2 in SDM. - MSR_XEON_E7_C8_PMON_CTR3 is defined as MSR_C8_PMON_CTR3 in SDM. - MSR_XEON_E7_C8_PMON_CTR4 is defined as MSR_C8_PMON_CTR4 in SDM. - MSR_XEON_E7_C8_PMON_CTR5 is defined as MSR_C8_PMON_CTR5 in SDM. - @{ -**/ -#define MSR_XEON_E7_C8_PMON_CTR0 0x00000F51 -#define MSR_XEON_E7_C8_PMON_CTR1 0x00000F53 -#define MSR_XEON_E7_C8_PMON_CTR2 0x00000F55 -#define MSR_XEON_E7_C8_PMON_CTR3 0x00000F57 -#define MSR_XEON_E7_C8_PMON_CTR4 0x00000F59 -#define MSR_XEON_E7_C8_PMON_CTR5 0x00000F5B -/// @} - - -/** - Package. Uncore C-box 9 perfmon local box control MSR. - - @param ECX MSR_XEON_E7_C9_PMON_BOX_CTRL (0x00000FC0) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_CTRL); - AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_CTRL, Msr); - @endcode - @note MSR_XEON_E7_C9_PMON_BOX_CTRL is defined as MSR_C9_PMON_BOX_CTRL in SDM. -**/ -#define MSR_XEON_E7_C9_PMON_BOX_CTRL 0x00000FC0 - - -/** - Package. Uncore C-box 9 perfmon local box status MSR. - - @param ECX MSR_XEON_E7_C9_PMON_BOX_STATUS (0x00000FC1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_STATUS); - AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_STATUS, Msr); - @endcode - @note MSR_XEON_E7_C9_PMON_BOX_STATUS is defined as MSR_C9_PMON_BOX_STATUS in SDM. -**/ -#define MSR_XEON_E7_C9_PMON_BOX_STATUS 0x00000FC1 - - -/** - Package. Uncore C-box 9 perfmon local box overflow control MSR. - - @param ECX MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL (0x00000FC2) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL); - AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL, Msr); - @endcode - @note MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL is defined as MSR_C9_PMON_BOX_OVF_CTRL in SDM. -**/ -#define MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL 0x00000FC2 - - -/** - Package. Uncore C-box 9 perfmon event select MSR. - - @param ECX MSR_XEON_E7_C9_PMON_EVNT_SELn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_EVNT_SEL0); - AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_EVNT_SEL0, Msr); - @endcode - @note MSR_XEON_E7_C9_PMON_EVNT_SEL0 is defined as MSR_C9_PMON_EVNT_SEL0 in SDM. - MSR_XEON_E7_C9_PMON_EVNT_SEL1 is defined as MSR_C9_PMON_EVNT_SEL1 in SDM. - MSR_XEON_E7_C9_PMON_EVNT_SEL2 is defined as MSR_C9_PMON_EVNT_SEL2 in SDM. - MSR_XEON_E7_C9_PMON_EVNT_SEL3 is defined as MSR_C9_PMON_EVNT_SEL3 in SDM. - MSR_XEON_E7_C9_PMON_EVNT_SEL4 is defined as MSR_C9_PMON_EVNT_SEL4 in SDM. - MSR_XEON_E7_C9_PMON_EVNT_SEL5 is defined as MSR_C9_PMON_EVNT_SEL5 in SDM. - @{ -**/ -#define MSR_XEON_E7_C9_PMON_EVNT_SEL0 0x00000FD0 -#define MSR_XEON_E7_C9_PMON_EVNT_SEL1 0x00000FD2 -#define MSR_XEON_E7_C9_PMON_EVNT_SEL2 0x00000FD4 -#define MSR_XEON_E7_C9_PMON_EVNT_SEL3 0x00000FD6 -#define MSR_XEON_E7_C9_PMON_EVNT_SEL4 0x00000FD8 -#define MSR_XEON_E7_C9_PMON_EVNT_SEL5 0x00000FDA -/// @} - - -/** - Package. Uncore C-box 9 perfmon counter MSR. - - @param ECX MSR_XEON_E7_C9_PMON_CTRn - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_CTR0); - AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_CTR0, Msr); - @endcode - @note MSR_XEON_E7_C9_PMON_CTR0 is defined as MSR_C9_PMON_CTR0 in SDM. - MSR_XEON_E7_C9_PMON_CTR1 is defined as MSR_C9_PMON_CTR1 in SDM. - MSR_XEON_E7_C9_PMON_CTR2 is defined as MSR_C9_PMON_CTR2 in SDM. - MSR_XEON_E7_C9_PMON_CTR3 is defined as MSR_C9_PMON_CTR3 in SDM. - MSR_XEON_E7_C9_PMON_CTR4 is defined as MSR_C9_PMON_CTR4 in SDM. - MSR_XEON_E7_C9_PMON_CTR5 is defined as MSR_C9_PMON_CTR5 in SDM. - @{ -**/ -#define MSR_XEON_E7_C9_PMON_CTR0 0x00000FD1 -#define MSR_XEON_E7_C9_PMON_CTR1 0x00000FD3 -#define MSR_XEON_E7_C9_PMON_CTR2 0x00000FD5 -#define MSR_XEON_E7_C9_PMON_CTR3 0x00000FD7 -#define MSR_XEON_E7_C9_PMON_CTR4 0x00000FD9 -#define MSR_XEON_E7_C9_PMON_CTR5 0x00000FDB -/// @} - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h b/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h deleted file mode 100644 index 43354d15c..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h +++ /dev/null @@ -1,1405 +0,0 @@ -/** @file - MSR Definitions for Intel(R) Xeon(R) Phi(TM) processor Family. - - Provides defines for Machine Specific Registers(MSR) indexes. Data structures - are provided for MSRs that contain one or more bit fields. If the MSR value - returned is a single 32-bit or 64-bit value, then a data structure is not - provided for that MSR. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3, - September 2016, Chapter 35 Model-Specific-Registers (MSR), Section 35.17. - -**/ - -#ifndef __XEON_PHI_MSR_H__ -#define __XEON_PHI_MSR_H__ - -#include - -/** - Is Intel(R) Xeon(R) Phi(TM) processor Family? - - @param DisplayFamily Display Family ID - @param DisplayModel Display Model ID - - @retval TRUE Yes, it is. - @retval FALSE No, it isn't. -**/ -#define IS_XEON_PHI_PROCESSOR(DisplayFamily, DisplayModel) \ - (DisplayFamily == 0x06 && \ - ( \ - DisplayModel == 0x57 \ - ) \ - ) - -/** - Thread. SMI Counter (R/O). - - @param ECX MSR_XEON_PHI_SMI_COUNT (0x00000034) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_SMI_COUNT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_SMI_COUNT_REGISTER. - - Example usage - @code - MSR_XEON_PHI_SMI_COUNT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_SMI_COUNT); - @endcode - @note MSR_XEON_PHI_SMI_COUNT is defined as MSR_SMI_COUNT in SDM. -**/ -#define MSR_XEON_PHI_SMI_COUNT 0x00000034 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_SMI_COUNT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 31:0] SMI Count (R/O). - /// - UINT32 SMICount:32; - UINT32 Reserved:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_SMI_COUNT_REGISTER; - - -/** - Package. See http://biosbits.org. - - @param ECX MSR_XEON_PHI_PLATFORM_INFO (0x000000CE) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PLATFORM_INFO_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PLATFORM_INFO_REGISTER. - - Example usage - @code - MSR_XEON_PHI_PLATFORM_INFO_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_PLATFORM_INFO); - AsmWriteMsr64 (MSR_XEON_PHI_PLATFORM_INFO, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_PLATFORM_INFO is defined as MSR_PLATFORM_INFO in SDM. -**/ -#define MSR_XEON_PHI_PLATFORM_INFO 0x000000CE - -/** - MSR information returned for MSR index #MSR_XEON_PHI_PLATFORM_INFO -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:8; - /// - /// [Bits 15:8] Package. Maximum Non-Turbo Ratio (R/O) The is the ratio - /// of the frequency that invariant TSC runs at. Frequency = ratio * 100 - /// MHz. - /// - UINT32 MaximumNonTurboRatio:8; - UINT32 Reserved2:12; - /// - /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) When - /// set to 1, indicates that Programmable Ratio Limits for Turbo mode is - /// enabled, and when set to 0, indicates Programmable Ratio Limits for - /// Turbo mode is disabled. - /// - UINT32 RatioLimit:1; - /// - /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) When - /// set to 1, indicates that TDP Limits for Turbo mode are programmable, - /// and when set to 0, indicates TDP Limit for Turbo mode is not - /// programmable. - /// - UINT32 TDPLimit:1; - UINT32 Reserved3:2; - UINT32 Reserved4:8; - /// - /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) The is the - /// minimum ratio (maximum efficiency) that the processor can operates, in - /// units of 100MHz. - /// - UINT32 MaximumEfficiencyRatio:8; - UINT32 Reserved5:16; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_PLATFORM_INFO_REGISTER; - - -/** - Module. C-State Configuration Control (R/W). - - @param ECX MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL (0x000000E2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL_REGISTER. - - Example usage - @code - MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL is defined as MSR_PKG_CST_CONFIG_CONTROL in SDM. -**/ -#define MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL 0x000000E2 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 2:0] Package C-State Limit (R/W) The following C-state code - /// name encodings are supported: 000b: C0/C1 001b: C2 010b: C6 No - /// Retention 011b: C6 Retention 111b: No limit. - /// - UINT32 Limit:3; - UINT32 Reserved1:7; - /// - /// [Bit 10] I/O MWAIT Redirection Enable (R/W). - /// - UINT32 IO_MWAIT:1; - UINT32 Reserved2:4; - /// - /// [Bit 15] CFG Lock (R/WO). - /// - UINT32 CFGLock:1; - UINT32 Reserved3:16; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_PKG_CST_CONFIG_CONTROL_REGISTER; - - -/** - Module. Power Management IO Redirection in C-state (R/W). - - @param ECX MSR_XEON_PHI_PMG_IO_CAPTURE_BASE (0x000000E4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PMG_IO_CAPTURE_BASE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_PMG_IO_CAPTURE_BASE_REGISTER. - - Example usage - @code - MSR_XEON_PHI_PMG_IO_CAPTURE_BASE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_PMG_IO_CAPTURE_BASE); - AsmWriteMsr64 (MSR_XEON_PHI_PMG_IO_CAPTURE_BASE, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_PMG_IO_CAPTURE_BASE is defined as MSR_PMG_IO_CAPTURE_BASE in SDM. -**/ -#define MSR_XEON_PHI_PMG_IO_CAPTURE_BASE 0x000000E4 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_PMG_IO_CAPTURE_BASE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 15:0] LVL_2 Base Address (R/W). - /// - UINT32 Lvl2Base:16; - /// - /// [Bits 18:16] C-state Range (R/W) Specifies the encoding value of the - /// maximum C-State code name to be included when IO read to MWAIT - /// redirection is enabled by MSR_PKG_CST_CONFIG_CONTROL[bit10]: 100b - C4 - /// is the max C-State to include 110b - C6 is the max C-State to include. - /// - UINT32 CStateRange:3; - UINT32 Reserved1:13; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_PMG_IO_CAPTURE_BASE_REGISTER; - - -/** - Core. AES Configuration (RW-L) Privileged post-BIOS agent must provide a #GP - handler to handle unsuccessful read of this MSR. - - @param ECX MSR_XEON_PHI_FEATURE_CONFIG (0x0000013C) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_FEATURE_CONFIG_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_FEATURE_CONFIG_REGISTER. - - Example usage - @code - MSR_XEON_PHI_FEATURE_CONFIG_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_FEATURE_CONFIG); - AsmWriteMsr64 (MSR_XEON_PHI_FEATURE_CONFIG, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_FEATURE_CONFIG is defined as MSR_FEATURE_CONFIG in SDM. -**/ -#define MSR_XEON_PHI_FEATURE_CONFIG 0x0000013C - -/** - MSR information returned for MSR index #MSR_XEON_PHI_FEATURE_CONFIG -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 1:0] AES Configuration (RW-L) Upon a successful read of this - /// MSR, the configuration of AES instruction set availability is as - /// follows: 11b: AES instructions are not available until next RESET. - /// otherwise, AES instructions are available. Note, AES instruction set - /// is not available if read is unsuccessful. If the configuration is not - /// 01b, AES instruction can be mis-configured if a privileged agent - /// unintentionally writes 11b. - /// - UINT32 AESConfiguration:2; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_FEATURE_CONFIG_REGISTER; - - -/** - THREAD. Enhanced SMM Capabilities (SMM-RO) Reports SMM capability - Enhancement. Accessible only while in SMM. - - @param ECX MSR_XEON_PHI_SMM_MCA_CAP (0x0000017D) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_SMM_MCA_CAP_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_SMM_MCA_CAP_REGISTER. - - Example usage - @code - MSR_XEON_PHI_SMM_MCA_CAP_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_SMM_MCA_CAP); - AsmWriteMsr64 (MSR_XEON_PHI_SMM_MCA_CAP, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_SMM_MCA_CAP is defined as MSR_SMM_MCA_CAP in SDM. -**/ -#define MSR_XEON_PHI_SMM_MCA_CAP 0x0000017D - -/** - MSR information returned for MSR index #MSR_XEON_PHI_SMM_MCA_CAP -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:32; - UINT32 Reserved2:26; - /// - /// [Bit 58] SMM_Code_Access_Chk (SMM-RO) If set to 1 indicates that the - /// SMM code access restriction is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 SMM_Code_Access_Chk:1; - /// - /// [Bit 59] Long_Flow_Indication (SMM-RO) If set to 1 indicates that the - /// SMM long flow indicator is supported and a host-space interface - /// available to SMM handler. - /// - UINT32 Long_Flow_Indication:1; - UINT32 Reserved3:4; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_SMM_MCA_CAP_REGISTER; - - -/** - Thread. Enable Misc. Processor Features (R/W) Allows a variety of processor - functions to be enabled and disabled. - - @param ECX MSR_XEON_PHI_IA32_MISC_ENABLE (0x000001A0) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_IA32_MISC_ENABLE_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_IA32_MISC_ENABLE_REGISTER. - - Example usage - @code - MSR_XEON_PHI_IA32_MISC_ENABLE_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_IA32_MISC_ENABLE); - AsmWriteMsr64 (MSR_XEON_PHI_IA32_MISC_ENABLE, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_IA32_MISC_ENABLE is defined as IA32_MISC_ENABLE in SDM. -**/ -#define MSR_XEON_PHI_IA32_MISC_ENABLE 0x000001A0 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_IA32_MISC_ENABLE -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Fast-Strings Enable. - /// - UINT32 FastStrings:1; - UINT32 Reserved1:2; - /// - /// [Bit 3] Automatic Thermal Control Circuit Enable (R/W) Default value - /// is 1. - /// - UINT32 AutomaticThermalControlCircuit:1; - UINT32 Reserved2:3; - /// - /// [Bit 7] Performance Monitoring Available (R). - /// - UINT32 PerformanceMonitoring:1; - UINT32 Reserved3:3; - /// - /// [Bit 11] Branch Trace Storage Unavailable (RO). - /// - UINT32 BTS:1; - /// - /// [Bit 12] Processor Event Based Sampling Unavailable (RO). - /// - UINT32 PEBS:1; - UINT32 Reserved4:3; - /// - /// [Bit 16] Enhanced Intel SpeedStep Technology Enable (R/W). - /// - UINT32 EIST:1; - UINT32 Reserved5:1; - /// - /// [Bit 18] ENABLE MONITOR FSM (R/W). - /// - UINT32 MONITOR:1; - UINT32 Reserved6:3; - /// - /// [Bit 22] Limit CPUID Maxval (R/W). - /// - UINT32 LimitCpuidMaxval:1; - /// - /// [Bit 23] xTPR Message Disable (R/W). - /// - UINT32 xTPR_Message_Disable:1; - UINT32 Reserved7:8; - UINT32 Reserved8:2; - /// - /// [Bit 34] XD Bit Disable (R/W). - /// - UINT32 XD:1; - UINT32 Reserved9:3; - /// - /// [Bit 38] Turbo Mode Disable (R/W). - /// - UINT32 TurboModeDisable:1; - UINT32 Reserved10:25; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_IA32_MISC_ENABLE_REGISTER; - - -/** - Package. - - @param ECX MSR_XEON_PHI_TEMPERATURE_TARGET (0x000001A2) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_TEMPERATURE_TARGET_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_TEMPERATURE_TARGET_REGISTER. - - Example usage - @code - MSR_XEON_PHI_TEMPERATURE_TARGET_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_TEMPERATURE_TARGET); - AsmWriteMsr64 (MSR_XEON_PHI_TEMPERATURE_TARGET, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_TEMPERATURE_TARGET is defined as MSR_TEMPERATURE_TARGET in SDM. -**/ -#define MSR_XEON_PHI_TEMPERATURE_TARGET 0x000001A2 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_TEMPERATURE_TARGET -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved1:16; - /// - /// [Bits 23:16] Temperature Target (R). - /// - UINT32 TemperatureTarget:8; - /// - /// [Bits 29:24] Target Offset (R/W). - /// - UINT32 TargetOffset:6; - UINT32 Reserved2:2; - UINT32 Reserved3:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_TEMPERATURE_TARGET_REGISTER; - - -/** - Miscellaneous Feature Control (R/W). - - @param ECX MSR_XEON_PHI_MISC_FEATURE_CONTROL (0x000001A4) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_MISC_FEATURE_CONTROL_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_MISC_FEATURE_CONTROL_REGISTER. - - Example usage - @code - MSR_XEON_PHI_MISC_FEATURE_CONTROL_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_MISC_FEATURE_CONTROL); - AsmWriteMsr64 (MSR_XEON_PHI_MISC_FEATURE_CONTROL, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_MISC_FEATURE_CONTROL is defined as MSR_MISC_FEATURE_CONTROL in SDM. -**/ -#define MSR_XEON_PHI_MISC_FEATURE_CONTROL 0x000001A4 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_MISC_FEATURE_CONTROL -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] Core. DCU Hardware Prefetcher Disable (R/W) If 1, disables the - /// L1 data cache prefetcher. - /// - UINT32 DCUHardwarePrefetcherDisable:1; - /// - /// [Bit 1] Core. L2 Hardware Prefetcher Disable (R/W) If 1, disables the - /// L2 hardware prefetcher. - /// - UINT32 L2HardwarePrefetcherDisable:1; - UINT32 Reserved1:30; - UINT32 Reserved2:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_MISC_FEATURE_CONTROL_REGISTER; - - -/** - Shared. Offcore Response Event Select Register (R/W). - - @param ECX MSR_XEON_PHI_OFFCORE_RSP_0 (0x000001A6) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_OFFCORE_RSP_0); - AsmWriteMsr64 (MSR_XEON_PHI_OFFCORE_RSP_0, Msr); - @endcode - @note MSR_XEON_PHI_OFFCORE_RSP_0 is defined as MSR_OFFCORE_RSP_0 in SDM. -**/ -#define MSR_XEON_PHI_OFFCORE_RSP_0 0x000001A6 - - -/** - Shared. Offcore Response Event Select Register (R/W). - - @param ECX MSR_XEON_PHI_OFFCORE_RSP_1 (0x000001A7) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_OFFCORE_RSP_1); - AsmWriteMsr64 (MSR_XEON_PHI_OFFCORE_RSP_1, Msr); - @endcode - @note MSR_XEON_PHI_OFFCORE_RSP_1 is defined as MSR_OFFCORE_RSP_1 in SDM. -**/ -#define MSR_XEON_PHI_OFFCORE_RSP_1 0x000001A7 - - -/** - Package. Maximum Ratio Limit of Turbo Mode for Groups of Cores (RW). - - @param ECX MSR_XEON_PHI_TURBO_RATIO_LIMIT (0x000001AD) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_TURBO_RATIO_LIMIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_TURBO_RATIO_LIMIT_REGISTER. - - Example usage - @code - MSR_XEON_PHI_TURBO_RATIO_LIMIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_TURBO_RATIO_LIMIT); - AsmWriteMsr64 (MSR_XEON_PHI_TURBO_RATIO_LIMIT, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_TURBO_RATIO_LIMIT is defined as MSR_TURBO_RATIO_LIMIT in SDM. -**/ -#define MSR_XEON_PHI_TURBO_RATIO_LIMIT 0x000001AD - -/** - MSR information returned for MSR index #MSR_XEON_PHI_TURBO_RATIO_LIMIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - UINT32 Reserved:1; - /// - /// [Bits 7:1] Package. Maximum Number of Cores in Group 0 Number active - /// processor cores which operates under the maximum ratio limit for group - /// 0. - /// - UINT32 MaxCoresGroup0:7; - /// - /// [Bits 15:8] Package. Maximum Ratio Limit for Group 0 Maximum turbo - /// ratio limit when the number of active cores are not more than the - /// group 0 maximum core count. - /// - UINT32 MaxRatioLimitGroup0:8; - /// - /// [Bits 20:16] Package. Number of Incremental Cores Added to Group 1 - /// Group 1, which includes the specified number of additional cores plus - /// the cores in group 0, operates under the group 1 turbo max ratio limit - /// = "group 0 Max ratio limit" - "group ratio delta for group 1". - /// - UINT32 MaxIncrementalCoresGroup1:5; - /// - /// [Bits 23:21] Package. Group Ratio Delta for Group 1 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// to Group 0. - /// - UINT32 DeltaRatioGroup1:3; - /// - /// [Bits 28:24] Package. Number of Incremental Cores Added to Group 2 - /// Group 2, which includes the specified number of additional cores plus - /// all the cores in group 1, operates under the group 2 turbo max ratio - /// limit = "group 1 Max ratio limit" - "group ratio delta for group 2". - /// - UINT32 MaxIncrementalCoresGroup2:5; - /// - /// [Bits 31:29] Package. Group Ratio Delta for Group 2 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// for Group 1. - /// - UINT32 DeltaRatioGroup2:3; - /// - /// [Bits 36:32] Package. Number of Incremental Cores Added to Group 3 - /// Group 3, which includes the specified number of additional cores plus - /// all the cores in group 2, operates under the group 3 turbo max ratio - /// limit = "group 2 Max ratio limit" - "group ratio delta for group 3". - /// - UINT32 MaxIncrementalCoresGroup3:5; - /// - /// [Bits 39:37] Package. Group Ratio Delta for Group 3 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// for Group 2. - /// - UINT32 DeltaRatioGroup3:3; - /// - /// [Bits 44:40] Package. Number of Incremental Cores Added to Group 4 - /// Group 4, which includes the specified number of additional cores plus - /// all the cores in group 3, operates under the group 4 turbo max ratio - /// limit = "group 3 Max ratio limit" - "group ratio delta for group 4". - /// - UINT32 MaxIncrementalCoresGroup4:5; - /// - /// [Bits 47:45] Package. Group Ratio Delta for Group 4 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// for Group 3. - /// - UINT32 DeltaRatioGroup4:3; - /// - /// [Bits 52:48] Package. Number of Incremental Cores Added to Group 5 - /// Group 5, which includes the specified number of additional cores plus - /// all the cores in group 4, operates under the group 5 turbo max ratio - /// limit = "group 4 Max ratio limit" - "group ratio delta for group 5". - /// - UINT32 MaxIncrementalCoresGroup5:5; - /// - /// [Bits 55:53] Package. Group Ratio Delta for Group 5 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// for Group 4. - /// - UINT32 DeltaRatioGroup5:3; - /// - /// [Bits 60:56] Package. Number of Incremental Cores Added to Group 6 - /// Group 6, which includes the specified number of additional cores plus - /// all the cores in group 5, operates under the group 6 turbo max ratio - /// limit = "group 5 Max ratio limit" - "group ratio delta for group 6". - /// - UINT32 MaxIncrementalCoresGroup6:5; - /// - /// [Bits 63:61] Package. Group Ratio Delta for Group 6 An unsigned - /// integer specifying the ratio decrement relative to the Max ratio limit - /// for Group 5. - /// - UINT32 DeltaRatioGroup6:3; - } Bits; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_TURBO_RATIO_LIMIT_REGISTER; - - -/** - Thread. Last Branch Record Filtering Select Register (R/W). - - @param ECX MSR_XEON_PHI_LBR_SELECT (0x000001C8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_LBR_SELECT); - AsmWriteMsr64 (MSR_XEON_PHI_LBR_SELECT, Msr); - @endcode - @note MSR_XEON_PHI_LBR_SELECT is defined as MSR_LBR_SELECT in SDM. -**/ -#define MSR_XEON_PHI_LBR_SELECT 0x000001C8 - - -/** - Thread. Last Branch Record Stack TOS (R/W). - - @param ECX MSR_XEON_PHI_LASTBRANCH_TOS (0x000001C9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_LASTBRANCH_TOS); - AsmWriteMsr64 (MSR_XEON_PHI_LASTBRANCH_TOS, Msr); - @endcode - @note MSR_XEON_PHI_LASTBRANCH_TOS is defined as MSR_LASTBRANCH_TOS in SDM. -**/ -#define MSR_XEON_PHI_LASTBRANCH_TOS 0x000001C9 - - -/** - Thread. Last Exception Record From Linear IP (R). - - @param ECX MSR_XEON_PHI_LER_FROM_LIP (0x000001DD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_LER_FROM_LIP); - @endcode - @note MSR_XEON_PHI_LER_FROM_LIP is defined as MSR_LER_FROM_LIP in SDM. -**/ -#define MSR_XEON_PHI_LER_FROM_LIP 0x000001DD - - -/** - Thread. Last Exception Record To Linear IP (R). - - @param ECX MSR_XEON_PHI_LER_TO_LIP (0x000001DE) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_LER_TO_LIP); - @endcode - @note MSR_XEON_PHI_LER_TO_LIP is defined as MSR_LER_TO_LIP in SDM. -**/ -#define MSR_XEON_PHI_LER_TO_LIP 0x000001DE - - -/** - Thread. See Table 35-2. - - @param ECX MSR_XEON_PHI_PEBS_ENABLE (0x000003F1) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PEBS_ENABLE); - AsmWriteMsr64 (MSR_XEON_PHI_PEBS_ENABLE, Msr); - @endcode - @note MSR_XEON_PHI_PEBS_ENABLE is defined as MSR_PEBS_ENABLE in SDM. -**/ -#define MSR_XEON_PHI_PEBS_ENABLE 0x000003F1 - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. Package C3 - Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_PKG_C3_RESIDENCY (0x000003F8) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C3_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_C3_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_PKG_C3_RESIDENCY is defined as MSR_PKG_C3_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_PKG_C3_RESIDENCY 0x000003F8 - - -/** - Package. Package C6 Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_PKG_C6_RESIDENCY (0x000003F9) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C6_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_C6_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_PKG_C6_RESIDENCY is defined as MSR_PKG_C6_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_PKG_C6_RESIDENCY 0x000003F9 - - -/** - Package. Package C7 Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_PKG_C7_RESIDENCY (0x000003FA) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C7_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_C7_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_PKG_C7_RESIDENCY is defined as MSR_PKG_C7_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_PKG_C7_RESIDENCY 0x000003FA - - -/** - Module. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. Module C0 - Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_MC0_RESIDENCY (0x000003FC) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_MC0_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_MC0_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_MC0_RESIDENCY is defined as MSR_MC0_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_MC0_RESIDENCY 0x000003FC - - -/** - Module. Module C6 Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_MC6_RESIDENCY (0x000003FD) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_MC6_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_MC6_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_MC6_RESIDENCY is defined as MSR_MC6_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_MC6_RESIDENCY 0x000003FD - - -/** - Core. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. CORE C6 - Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_CORE_C6_RESIDENCY (0x000003FF) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_CORE_C6_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_CORE_C6_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_CORE_C6_RESIDENCY is defined as MSR_CORE_C6_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_CORE_C6_RESIDENCY 0x000003FF - - -/** - Core. Capability Reporting Register of EPT and VPID (R/O) See Table 35-2. - - @param ECX MSR_XEON_PHI_IA32_VMX_EPT_VPID_ENUM (0x0000048C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_IA32_VMX_EPT_VPID_ENUM); - @endcode - @note MSR_XEON_PHI_IA32_VMX_EPT_VPID_ENUM is defined as IA32_VMX_EPT_VPID_ENUM in SDM. -**/ -#define MSR_XEON_PHI_IA32_VMX_EPT_VPID_ENUM 0x0000048C - - -/** - Core. Capability Reporting Register of VM-function Controls (R/O) See Table - 35-2. - - @param ECX MSR_XEON_PHI_IA32_VMX_FMFUNC (0x00000491) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_IA32_VMX_FMFUNC); - @endcode - @note MSR_XEON_PHI_IA32_VMX_FMFUNC is defined as IA32_VMX_FMFUNC in SDM. -**/ -#define MSR_XEON_PHI_IA32_VMX_FMFUNC 0x00000491 - - -/** - Package. Unit Multipliers used in RAPL Interfaces (R/O). - - @param ECX MSR_XEON_PHI_RAPL_POWER_UNIT (0x00000606) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_RAPL_POWER_UNIT_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_RAPL_POWER_UNIT_REGISTER. - - Example usage - @code - MSR_XEON_PHI_RAPL_POWER_UNIT_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_RAPL_POWER_UNIT); - @endcode - @note MSR_XEON_PHI_RAPL_POWER_UNIT is defined as MSR_RAPL_POWER_UNIT in SDM. -**/ -#define MSR_XEON_PHI_RAPL_POWER_UNIT 0x00000606 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_RAPL_POWER_UNIT -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bits 3:0] Package. Power Units See Section 14.9.1, "RAPL Interfaces.". - /// - UINT32 PowerUnits:4; - UINT32 Reserved1:4; - /// - /// [Bits 12:8] Package. Energy Status Units Energy related information - /// (in Joules) is based on the multiplier, 1/2^ESU; where ESU is an - /// unsigned integer represented by bits 12:8. Default value is 0EH (or 61 - /// micro-joules). - /// - UINT32 EnergyStatusUnits:5; - UINT32 Reserved2:3; - /// - /// [Bits 19:16] Package. Time Units See Section 14.9.1, "RAPL - /// Interfaces.". - /// - UINT32 TimeUnits:4; - UINT32 Reserved3:12; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_RAPL_POWER_UNIT_REGISTER; - - -/** - Package. Note: C-state values are processor specific C-state code names, - unrelated to MWAIT extension C-state parameters or ACPI C-States. Package C2 - Residency Counter. (R/O). - - @param ECX MSR_XEON_PHI_PKG_C2_RESIDENCY (0x0000060D) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C2_RESIDENCY); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_C2_RESIDENCY, Msr); - @endcode - @note MSR_XEON_PHI_PKG_C2_RESIDENCY is defined as MSR_PKG_C2_RESIDENCY in SDM. -**/ -#define MSR_XEON_PHI_PKG_C2_RESIDENCY 0x0000060D - - -/** - Package. PKG RAPL Power Limit Control (R/W) See Section 14.9.3, "Package - RAPL Domain.". - - @param ECX MSR_XEON_PHI_PKG_POWER_LIMIT (0x00000610) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_POWER_LIMIT); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_POWER_LIMIT, Msr); - @endcode - @note MSR_XEON_PHI_PKG_POWER_LIMIT is defined as MSR_PKG_POWER_LIMIT in SDM. -**/ -#define MSR_XEON_PHI_PKG_POWER_LIMIT 0x00000610 - - -/** - Package. PKG Energy Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_XEON_PHI_PKG_ENERGY_STATUS (0x00000611) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_ENERGY_STATUS); - @endcode - @note MSR_XEON_PHI_PKG_ENERGY_STATUS is defined as MSR_PKG_ENERGY_STATUS in SDM. -**/ -#define MSR_XEON_PHI_PKG_ENERGY_STATUS 0x00000611 - - -/** - Package. PKG Perf Status (R/O) See Section 14.9.3, "Package RAPL Domain.". - - @param ECX MSR_XEON_PHI_PKG_PERF_STATUS (0x00000613) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_PERF_STATUS); - @endcode - @note MSR_XEON_PHI_PKG_PERF_STATUS is defined as MSR_PKG_PERF_STATUS in SDM. -**/ -#define MSR_XEON_PHI_PKG_PERF_STATUS 0x00000613 - - -/** - Package. PKG RAPL Parameters (R/W) See Section 14.9.3, "Package RAPL - Domain.". - - @param ECX MSR_XEON_PHI_PKG_POWER_INFO (0x00000614) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_POWER_INFO); - AsmWriteMsr64 (MSR_XEON_PHI_PKG_POWER_INFO, Msr); - @endcode - @note MSR_XEON_PHI_PKG_POWER_INFO is defined as MSR_PKG_POWER_INFO in SDM. -**/ -#define MSR_XEON_PHI_PKG_POWER_INFO 0x00000614 - - -/** - Package. DRAM RAPL Power Limit Control (R/W) See Section 14.9.5, "DRAM RAPL - Domain.". - - @param ECX MSR_XEON_PHI_DRAM_POWER_LIMIT (0x00000618) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_POWER_LIMIT); - AsmWriteMsr64 (MSR_XEON_PHI_DRAM_POWER_LIMIT, Msr); - @endcode - @note MSR_XEON_PHI_DRAM_POWER_LIMIT is defined as MSR_DRAM_POWER_LIMIT in SDM. -**/ -#define MSR_XEON_PHI_DRAM_POWER_LIMIT 0x00000618 - - -/** - Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_XEON_PHI_DRAM_ENERGY_STATUS (0x00000619) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_ENERGY_STATUS); - @endcode - @note MSR_XEON_PHI_DRAM_ENERGY_STATUS is defined as MSR_DRAM_ENERGY_STATUS in SDM. -**/ -#define MSR_XEON_PHI_DRAM_ENERGY_STATUS 0x00000619 - - -/** - Package. DRAM Performance Throttling Status (R/O) See Section 14.9.5, "DRAM - RAPL Domain.". - - @param ECX MSR_XEON_PHI_DRAM_PERF_STATUS (0x0000061B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_PERF_STATUS); - @endcode - @note MSR_XEON_PHI_DRAM_PERF_STATUS is defined as MSR_DRAM_PERF_STATUS in SDM. -**/ -#define MSR_XEON_PHI_DRAM_PERF_STATUS 0x0000061B - - -/** - Package. DRAM RAPL Parameters (R/W) See Section 14.9.5, "DRAM RAPL Domain.". - - @param ECX MSR_XEON_PHI_DRAM_POWER_INFO (0x0000061C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_POWER_INFO); - AsmWriteMsr64 (MSR_XEON_PHI_DRAM_POWER_INFO, Msr); - @endcode - @note MSR_XEON_PHI_DRAM_POWER_INFO is defined as MSR_DRAM_POWER_INFO in SDM. -**/ -#define MSR_XEON_PHI_DRAM_POWER_INFO 0x0000061C - - -/** - Package. PP0 RAPL Power Limit Control (R/W) See Section 14.9.4, "PP0/PP1 - RAPL Domains.". - - @param ECX MSR_XEON_PHI_PP0_POWER_LIMIT (0x00000638) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PP0_POWER_LIMIT); - AsmWriteMsr64 (MSR_XEON_PHI_PP0_POWER_LIMIT, Msr); - @endcode - @note MSR_XEON_PHI_PP0_POWER_LIMIT is defined as MSR_PP0_POWER_LIMIT in SDM. -**/ -#define MSR_XEON_PHI_PP0_POWER_LIMIT 0x00000638 - - -/** - Package. PP0 Energy Status (R/O) See Section 14.9.4, "PP0/PP1 RAPL - Domains.". - - @param ECX MSR_XEON_PHI_PP0_ENERGY_STATUS (0x00000639) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_PP0_ENERGY_STATUS); - @endcode - @note MSR_XEON_PHI_PP0_ENERGY_STATUS is defined as MSR_PP0_ENERGY_STATUS in SDM. -**/ -#define MSR_XEON_PHI_PP0_ENERGY_STATUS 0x00000639 - - -/** - Package. Base TDP Ratio (R/O) See Table 35-23. - - @param ECX MSR_XEON_PHI_CONFIG_TDP_NOMINAL (0x00000648) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_NOMINAL); - @endcode - @note MSR_XEON_PHI_CONFIG_TDP_NOMINAL is defined as MSR_CONFIG_TDP_NOMINAL in SDM. -**/ -#define MSR_XEON_PHI_CONFIG_TDP_NOMINAL 0x00000648 - - -/** - Package. ConfigTDP Level 1 ratio and power level (R/O). See Table 35-23. - - @param ECX MSR_XEON_PHI_CONFIG_TDP_LEVEL1 (0x00000649) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_LEVEL1); - @endcode - @note MSR_XEON_PHI_CONFIG_TDP_LEVEL1 is defined as MSR_CONFIG_TDP_LEVEL1 in SDM. -**/ -#define MSR_XEON_PHI_CONFIG_TDP_LEVEL1 0x00000649 - - -/** - Package. ConfigTDP Level 2 ratio and power level (R/O). See Table 35-23. - - @param ECX MSR_XEON_PHI_CONFIG_TDP_LEVEL2 (0x0000064A) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_LEVEL2); - @endcode - @note MSR_XEON_PHI_CONFIG_TDP_LEVEL2 is defined as MSR_CONFIG_TDP_LEVEL2 in SDM. -**/ -#define MSR_XEON_PHI_CONFIG_TDP_LEVEL2 0x0000064A - - -/** - Package. ConfigTDP Control (R/W) See Table 35-23. - - @param ECX MSR_XEON_PHI_CONFIG_TDP_CONTROL (0x0000064B) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_CONTROL); - AsmWriteMsr64 (MSR_XEON_PHI_CONFIG_TDP_CONTROL, Msr); - @endcode - @note MSR_XEON_PHI_CONFIG_TDP_CONTROL is defined as MSR_CONFIG_TDP_CONTROL in SDM. -**/ -#define MSR_XEON_PHI_CONFIG_TDP_CONTROL 0x0000064B - - -/** - Package. ConfigTDP Control (R/W) See Table 35-23. - - @param ECX MSR_XEON_PHI_TURBO_ACTIVATION_RATIO (0x0000064C) - @param EAX Lower 32-bits of MSR value. - @param EDX Upper 32-bits of MSR value. - - Example usage - @code - UINT64 Msr; - - Msr = AsmReadMsr64 (MSR_XEON_PHI_TURBO_ACTIVATION_RATIO); - AsmWriteMsr64 (MSR_XEON_PHI_TURBO_ACTIVATION_RATIO, Msr); - @endcode - @note MSR_XEON_PHI_TURBO_ACTIVATION_RATIO is defined as MSR_TURBO_ACTIVATION_RATIO in SDM. -**/ -#define MSR_XEON_PHI_TURBO_ACTIVATION_RATIO 0x0000064C - - -/** - Package. Indicator of Frequency Clipping in Processor Cores (R/W) (frequency - refers to processor core frequency). - - @param ECX MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS (0x00000690) - @param EAX Lower 32-bits of MSR value. - Described by the type MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS_REGISTER. - @param EDX Upper 32-bits of MSR value. - Described by the type MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS_REGISTER. - - Example usage - @code - MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS_REGISTER Msr; - - Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS); - AsmWriteMsr64 (MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS, Msr.Uint64); - @endcode - @note MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS is defined as MSR_CORE_PERF_LIMIT_REASONS in SDM. -**/ -#define MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS 0x00000690 - -/** - MSR information returned for MSR index #MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS -**/ -typedef union { - /// - /// Individual bit fields - /// - struct { - /// - /// [Bit 0] PROCHOT Status (R0). - /// - UINT32 PROCHOT_Status:1; - /// - /// [Bit 1] Thermal Status (R0). - /// - UINT32 ThermalStatus:1; - UINT32 Reserved1:4; - /// - /// [Bit 6] VR Therm Alert Status (R0). - /// - UINT32 VRThermAlertStatus:1; - UINT32 Reserved2:1; - /// - /// [Bit 8] Electrical Design Point Status (R0). - /// - UINT32 ElectricalDesignPointStatus:1; - UINT32 Reserved3:23; - UINT32 Reserved4:32; - } Bits; - /// - /// All bit fields as a 32-bit value - /// - UINT32 Uint32; - /// - /// All bit fields as a 64-bit value - /// - UINT64 Uint64; -} MSR_XEON_PHI_CORE_PERF_LIMIT_REASONS_REGISTER; - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/SmramSaveStateMap.h b/CloverEFI/UefiCpuPkg/Include/Register/SmramSaveStateMap.h deleted file mode 100644 index a7c7562df..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/SmramSaveStateMap.h +++ /dev/null @@ -1,190 +0,0 @@ -/** @file -SMRAM Save State Map Definitions. - -SMRAM Save State Map definitions based on contents of the -Intel(R) 64 and IA-32 Architectures Software Developer's Manual - Volume 3C, Section 34.4 SMRAM - Volume 3C, Section 34.5 SMI Handler Execution Environment - Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs - -Copyright (c) 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __SMRAM_SAVE_STATE_MAP_H__ -#define __SMRAM_SAVE_STATE_MAP_H__ - -/// -/// Default SMBASE address -/// -#define SMM_DEFAULT_SMBASE 0x30000 - -/// -/// Offset of SMM handler from SMBASE -/// -#define SMM_HANDLER_OFFSET 0x8000 - -/// -/// Offset of SMRAM Save State Map from SMBASE -/// -#define SMRAM_SAVE_STATE_MAP_OFFSET 0xfc00 - -#pragma pack (1) - -/// -/// 32-bit SMRAM Save State Map -/// -typedef struct { - UINT8 Reserved[0x200]; // 7c00h - // Padded an extra 0x200 bytes so 32-bit and 64-bit - // SMRAM Save State Maps are the same size - UINT8 Reserved1[0xf8]; // 7e00h - UINT32 SMBASE; // 7ef8h - UINT32 SMMRevId; // 7efch - UINT16 IORestart; // 7f00h - UINT16 AutoHALTRestart; // 7f02h - UINT8 Reserved2[0x9C]; // 7f08h - UINT32 IOMemAddr; // 7fa0h - UINT32 IOMisc; // 7fa4h - UINT32 _ES; // 7fa8h - UINT32 _CS; // 7fach - UINT32 _SS; // 7fb0h - UINT32 _DS; // 7fb4h - UINT32 _FS; // 7fb8h - UINT32 _GS; // 7fbch - UINT32 Reserved3; // 7fc0h - UINT32 _TR; // 7fc4h - UINT32 _DR7; // 7fc8h - UINT32 _DR6; // 7fcch - UINT32 _EAX; // 7fd0h - UINT32 _ECX; // 7fd4h - UINT32 _EDX; // 7fd8h - UINT32 _EBX; // 7fdch - UINT32 _ESP; // 7fe0h - UINT32 _EBP; // 7fe4h - UINT32 _ESI; // 7fe8h - UINT32 _EDI; // 7fech - UINT32 _EIP; // 7ff0h - UINT32 _EFLAGS; // 7ff4h - UINT32 _CR3; // 7ff8h - UINT32 _CR0; // 7ffch -} SMRAM_SAVE_STATE_MAP32; - -/// -/// 64-bit SMRAM Save State Map -/// -typedef struct { - UINT8 Reserved1[0x1d0]; // 7c00h - UINT32 GdtBaseHiDword; // 7dd0h - UINT32 LdtBaseHiDword; // 7dd4h - UINT32 IdtBaseHiDword; // 7dd8h - UINT8 Reserved2[0xc]; // 7ddch - UINT64 IO_EIP; // 7de8h - UINT8 Reserved3[0x50]; // 7df0h - UINT32 _CR4; // 7e40h - UINT8 Reserved4[0x48]; // 7e44h - UINT32 GdtBaseLoDword; // 7e8ch - UINT32 Reserved5; // 7e90h - UINT32 IdtBaseLoDword; // 7e94h - UINT32 Reserved6; // 7e98h - UINT32 LdtBaseLoDword; // 7e9ch - UINT8 Reserved7[0x38]; // 7ea0h - UINT64 EptVmxControl; // 7ed8h - UINT32 EnEptVmxControl; // 7ee0h - UINT8 Reserved8[0x14]; // 7ee4h - UINT32 SMBASE; // 7ef8h - UINT32 SMMRevId; // 7efch - UINT16 IORestart; // 7f00h - UINT16 AutoHALTRestart; // 7f02h - UINT8 Reserved9[0x18]; // 7f04h - UINT64 _R15; // 7f1ch - UINT64 _R14; - UINT64 _R13; - UINT64 _R12; - UINT64 _R11; - UINT64 _R10; - UINT64 _R9; - UINT64 _R8; - UINT64 _RAX; // 7f5ch - UINT64 _RCX; - UINT64 _RDX; - UINT64 _RBX; - UINT64 _RSP; - UINT64 _RBP; - UINT64 _RSI; - UINT64 _RDI; - UINT64 IOMemAddr; // 7f9ch - UINT32 IOMisc; // 7fa4h - UINT32 _ES; // 7fa8h - UINT32 _CS; - UINT32 _SS; - UINT32 _DS; - UINT32 _FS; - UINT32 _GS; - UINT32 _LDTR; // 7fc0h - UINT32 _TR; - UINT64 _DR7; // 7fc8h - UINT64 _DR6; - UINT64 _RIP; // 7fd8h - UINT64 IA32_EFER; // 7fe0h - UINT64 _RFLAGS; // 7fe8h - UINT64 _CR3; // 7ff0h - UINT64 _CR0; // 7ff8h -} SMRAM_SAVE_STATE_MAP64; - -/// -/// Union of 32-bit and 64-bit SMRAM Save State Maps -/// -typedef union { - SMRAM_SAVE_STATE_MAP32 x86; - SMRAM_SAVE_STATE_MAP64 x64; -} SMRAM_SAVE_STATE_MAP; - -/// -/// Minimum SMM Revision ID that supports IOMisc field in SMRAM Save State Map -/// -#define SMRAM_SAVE_STATE_MIN_REV_ID_IOMISC 0x30004 - -/// -/// SMRAM Save State Map IOMisc I/O Length Values -/// -#define SMM_IO_LENGTH_BYTE 0x01 -#define SMM_IO_LENGTH_WORD 0x02 -#define SMM_IO_LENGTH_DWORD 0x04 - -/// -/// SMRAM Save State Map IOMisc I/O Instruction Type Values -/// -#define SMM_IO_TYPE_IN_IMMEDIATE 0x9 -#define SMM_IO_TYPE_IN_DX 0x1 -#define SMM_IO_TYPE_OUT_IMMEDIATE 0x8 -#define SMM_IO_TYPE_OUT_DX 0x0 -#define SMM_IO_TYPE_INS 0x3 -#define SMM_IO_TYPE_OUTS 0x2 -#define SMM_IO_TYPE_REP_INS 0x7 -#define SMM_IO_TYPE_REP_OUTS 0x6 - -/// -/// SMRAM Save State Map IOMisc structure -/// -typedef union { - struct { - UINT32 SmiFlag:1; - UINT32 Length:3; - UINT32 Type:4; - UINT32 Reserved1:8; - UINT32 Port:16; - } Bits; - UINT32 Uint32; -} SMRAM_SAVE_STATE_IOMISC; - -#pragma pack () - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/StmApi.h b/CloverEFI/UefiCpuPkg/Include/Register/StmApi.h deleted file mode 100644 index 6fb5971b4..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/StmApi.h +++ /dev/null @@ -1,954 +0,0 @@ -/** @file - STM API definition - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - SMI Transfer Monitor (STM) User Guide Revision 1.00 - -**/ - -#ifndef _STM_API_H_ -#define _STM_API_H_ - -#include -#include -#include - -#pragma pack (1) - -/** - STM Header Structures -**/ - -typedef struct { - UINT32 Intel64ModeSupported :1; ///> bitfield - UINT32 EptSupported :1; ///> bitfield - UINT32 Reserved :30; ///> must be 0 -} STM_FEAT; - -#define STM_SPEC_VERSION_MAJOR 1 -#define STM_SPEC_VERSION_MINOR 0 - -typedef struct { - UINT8 StmSpecVerMajor; - UINT8 StmSpecVerMinor; - /// - /// Must be zero - /// - UINT16 Reserved; - UINT32 StaticImageSize; - UINT32 PerProcDynamicMemorySize; - UINT32 AdditionalDynamicMemorySize; - STM_FEAT StmFeatures; - UINT32 NumberOfRevIDs; - UINT32 StmSmmRevID[1]; - /// - /// The total STM_HEADER should be 4K. - /// -} SOFTWARE_STM_HEADER; - -typedef struct { - MSEG_HEADER HwStmHdr; - SOFTWARE_STM_HEADER SwStmHdr; -} STM_HEADER; - - -/** - VMCALL API Numbers - API number convention: BIOS facing VMCALL interfaces have bit 16 clear -**/ - -/** - StmMapAddressRange enables a SMM guest to create a non-1:1 virtual to - physical mapping of an address range into the SMM guest's virtual - memory space. - - @param EAX #STM_API_MAP_ADDRESS_RANGE (0x00000001) - @param EBX Low 32 bits of physical address of caller allocated - STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure. - @param ECX High 32 bits of physical address of caller allocated - STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is - clear (0), ECX must be 0. - - @note All fields of STM_MAP_ADDRESS_RANGE_DESCRIPTOR are inputs only. They - are not modified by StmMapAddressRange. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. - The memory range was mapped as requested. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_SECURITY_VIOLATION - The requested mapping contains a protected resource. - @retval EAX #ERROR_STM_CACHE_TYPE_NOT_SUPPORTED - The requested cache type could not be satisfied. - @retval EAX #ERROR_STM_PAGE_NOT_FOUND - Page count must not be zero. - @retval EAX #ERROR_STM_FUNCTION_NOT_SUPPORTED - STM supports EPT and has not implemented StmMapAddressRange(). - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_MAP_ADDRESS_RANGE 0x00000001 - -/** - STM Map Address Range Descriptor for #STM_API_MAP_ADDRESS_RANGE VMCALL -**/ -typedef struct { - UINT64 PhysicalAddress; - UINT64 VirtualAddress; - UINT32 PageCount; - UINT32 PatCacheType; -} STM_MAP_ADDRESS_RANGE_DESCRIPTOR; - -/** - Define values for PatCacheType field of #STM_MAP_ADDRESS_RANGE_DESCRIPTOR - @{ -**/ -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_ST_UC 0x00 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WC 0x01 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WT 0x04 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WP 0x05 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WB 0x06 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_UC 0x07 -#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_FOLLOW_MTRR 0xFFFFFFFF -/// @} - -/** - StmUnmapAddressRange enables a SMM guest to remove mappings from its page - table. - - If TXT_PROCESSOR_SMM_DESCRIPTOR.EptEnabled bit is set by the STM, BIOS can - control its own page tables. In this case, the STM implementation may - optionally return ERROR_STM_FUNCTION_NOT_SUPPORTED. - - @param EAX #STM_API_UNMAP_ADDRESS_RANGE (0x00000002) - @param EBX Low 32 bits of virtual address of caller allocated - STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure. - @param ECX High 32 bits of virtual address of caller allocated - STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is - clear (0), ECX must be zero. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The memory range was unmapped - as requested. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_FUNCTION_NOT_SUPPORTED - STM supports EPT and has not implemented StmUnmapAddressRange(). - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_UNMAP_ADDRESS_RANGE 0x00000002 - -/** - STM Unmap Address Range Descriptor for #STM_API_UNMAP_ADDRESS_RANGE VMCALL -**/ -typedef struct { - UINT64 VirtualAddress; - UINT32 Length; -} STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR; - - -/** - Since the normal OS environment runs with a different set of page tables than - the SMM guest, virtual mappings will certainly be different. In order to do a - guest virtual to host physical translation of an address from the normal OS - code (EIP for example), it is necessary to walk the page tables governing the - OS page mappings. Since the SMM guest has no direct access to the page tables, - it must ask the STM to do this page table walk. This is supported via the - StmAddressLookup VMCALL. All OS page table formats need to be supported, - (e.g. PAE, PSE, Intel64, EPT, etc.) - - StmAddressLookup takes a CR3 value and a virtual address from the interrupted - code as input and returns the corresponding physical address. It also - optionally maps the physical address into the SMM guest's virtual address - space. This new mapping persists ONLY for the duration of the SMI and if - needed in subsequent SMIs it must be remapped. PAT cache types follow the - interrupted environment's page table. - - If EPT is enabled, OS CR3 only provides guest physical address information, - but the SMM guest might also need to know the host physical address. Since - SMM does not have direct access rights to EPT (it is protected by the STM), - SMM can input InterruptedEptp to let STM help to walk through it, and output - the host physical address. - - @param EAX #STM_API_ADDRESS_LOOKUP (0x00000003) - @param EBX Low 32 bits of virtual address of caller allocated - STM_ADDRESS_LOOKUP_DESCRIPTOR structure. - @param ECX High 32 bits of virtual address of caller allocated - STM_ADDRESS_LOOKUP_DESCRIPTOR structure. If Intel64Mode is - clear (0), ECX must be zero. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. PhysicalAddress contains the - host physical address determined by walking the interrupted SMM - guest's page tables. SmmGuestVirtualAddress contains the SMM - guest's virtual mapping of the requested address. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_SECURITY_VIOLATION - The requested page was a protected page. - @retval EAX #ERROR_STM_PAGE_NOT_FOUND - The requested virtual address did not exist in the page given - page table. - @retval EAX #ERROR_STM_BAD_CR3 - The CR3 input was invalid. CR3 values must be from one of the - interrupted guest, or from the interrupted guest of another - processor. - @retval EAX #ERROR_STM_PHYSICAL_OVER_4G - The resulting physical address is greater than 4G and no virtual - address was supplied. The STM could not determine what address - within the SMM guest's virtual address space to do the mapping. - STM_ADDRESS_LOOKUP_DESCRIPTOR field PhysicalAddress contains the - physical address determined by walking the interrupted - environment's page tables. - @retval EAX #ERROR_STM_VIRTUAL_SPACE_TOO_SMALL - A specific virtual mapping was requested, but - SmmGuestVirtualAddress + Length exceeds 4G and the SMI handler - is running in 32 bit mode. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_ADDRESS_LOOKUP 0x00000003 - -/** - STM Lookup Address Range Descriptor for #STM_API_ADDRESS_LOOKUP VMCALL -**/ -typedef struct { - UINT64 InterruptedGuestVirtualAddress; - UINT32 Length; - UINT64 InterruptedCr3; - UINT64 InterruptedEptp; - UINT32 MapToSmmGuest:2; - UINT32 InterruptedCr4Pae:1; - UINT32 InterruptedCr4Pse:1; - UINT32 InterruptedIa32eMode:1; - UINT32 Reserved1:27; - UINT32 Reserved2; - UINT64 PhysicalAddress; - UINT64 SmmGuestVirtualAddress; -} STM_ADDRESS_LOOKUP_DESCRIPTOR; - -/** - Define values for the MapToSmmGuest field of #STM_ADDRESS_LOOKUP_DESCRIPTOR - @{ -**/ -#define STM_ADDRESS_LOOKUP_DESCRIPTOR_DO_NOT_MAP 0 -#define STM_ADDRESS_LOOKUP_DESCRIPTOR_ONE_TO_ONE 1 -#define STM_ADDRESS_LOOKUP_DESCRIPTOR_VIRTUAL_ADDRESS_SPECIFIED 3 -/// @} - - -/** - When returning from a protection exception (see section 6.2), the SMM guest - can instruct the STM to take one of two paths. It can either request a value - be logged to the TXT.ERRORCODE register and subsequently reset the machine - (indicating it couldn't resolve the problem), or it can request that the STM - resume the SMM guest again with the specified register state. - - Unlike other VMCALL interfaces, StmReturnFromProtectionException behaves more - like a jump or an IRET instruction than a "call". It does not return directly - to the caller, but indirectly to a different location specified on the - caller's stack (see section 6.2) or not at all. - - If the SMM guest STM protection exception handler itself causes a protection - exception (e.g. a single nested exception), or more than 100 un-nested - exceptions occur within the scope of a single SMI event, the STM must write - STM_CRASH_PROTECTION_EXCEPTION_FAILURE to the TXT.ERRORCODE register and - assert TXT.CMD.SYS_RESET. The reason for these restrictions is to simplify - the code requirements while still enabling a reasonable debugging capability. - - @param EAX #STM_API_RETURN_FROM_PROTECTION_EXCEPTION (0x00000004) - @param EBX If 0, resume SMM guest using register state found on exception - stack. If in range 0x01..0x0F, EBX contains a BIOS error code - which the STM must record in the TXT.ERRORCODE register and - subsequently reset the system via TXT.CMD.SYS_RESET. The value - of the TXT.ERRORCODE register is calculated as follows: - - TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC - - Values 0x10..0xFFFFFFFF are reserved, do not use. - -**/ -#define STM_API_RETURN_FROM_PROTECTION_EXCEPTION 0x00000004 - - -/** - VMCALL API Numbers - API number convention: MLE facing VMCALL interfaces have bit 16 set. - - The STM configuration lifecycle is as follows: - 1. SENTER->SINIT->MLE: MLE begins execution with SMI disabled (masked). - 2. MLE invokes #STM_API_INITIALIZE_PROTECTION VMCALL to prepare STM for - setup of initial protection profile. This is done on a single CPU and - has global effect. - 3. MLE invokes #STM_API_PROTECT_RESOURCE VMCALL to define the initial - protection profile. The protection profile is global across all CPUs. - 4. MLE invokes #STM_API_START VMCALL to enable the STM to begin receiving - SMI events. This must be done on every logical CPU. - 5. MLE may invoke #STM_API_PROTECT_RESOURCE VMCALL or - #STM_API_UNPROTECT_RESOURCE VMCALL during runtime as many times as - necessary. - 6. MLE invokes #STM_API_STOP VMCALL to disable the STM. SMI is again masked - following #STM_API_STOP VMCALL. -**/ - -/** - StartStmVmcall() is used to configure an STM that is present in MSEG. SMIs - should remain disabled from the invocation of GETSEC[SENTER] until they are - re-enabled by StartStmVMCALL(). When StartStmVMCALL() returns, SMI is - enabled and the STM has been started and is active. Prior to invoking - StartStmVMCALL(), the MLE root should first invoke - InitializeProtectionVMCALL() followed by as many iterations of - ProtectResourceVMCALL() as necessary to establish the initial protection - profile. StartStmVmcall() must be invoked on all processor threads. - - @param EAX #STM_API_START (0x00010001) - @param EDX STM configuration options. These provide the MLE with the - ability to pass configuration parameters to the STM. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The STM has been configured - and is now active and the guarding all requested resources. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_ALREADY_STARTED - The STM is already configured and active. STM remains active and - guarding previously enabled resource list. - @retval EAX #ERROR_STM_WITHOUT_SMX_UNSUPPORTED - The StartStmVMCALL() was invoked from VMX root mode, but outside - of SMX. This error code indicates the STM or platform does not - support the STM outside of SMX. The SMI handler remains active - and operates in legacy mode. See Appendix C - @retval EAX #ERROR_STM_UNSUPPORTED_MSR_BIT - The CPU doesn't support the MSR bit. The STM is not active. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_START (BIT16 | 1) - -/** - Bit values for EDX input parameter to #STM_API_START VMCALL - @{ -**/ -#define STM_CONFIG_SMI_UNBLOCKING_BY_VMX_OFF BIT0 -/// @} - - -/** - The StopStmVMCALL() is invoked by the MLE to teardown an active STM. This is - normally done as part of a full teardown of the SMX environment when the - system is being shut down. At the time the call is invoked, SMI is enabled - and the STM is active. When the call returns, the STM has been stopped and - all STM context is discarded and SMI is disabled. - - @param EAX #STM_API_STOP (0x00010002) - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The STM has been stopped and - is no longer processing SMI events. SMI is blocked. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_STOPPED - The STM was not active. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_STOP (BIT16 | 2) - - -/** - The ProtectResourceVMCALL() is invoked by the MLE root to request protection - of specific resources. The request is defined by a STM_RESOURCE_LIST, which - may contain more than one resource descriptor. Each resource descriptor is - processed separately by the STM. Whether or not protection for any specific - resource is granted is returned by the STM via the ReturnStatus bit in the - associated STM_RSC_DESC_HEADER. - - @param EAX #STM_API_PROTECT_RESOURCE (0x00010003) - @param EBX Low 32 bits of physical address of caller allocated - STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero, - making the buffer 4K aligned. - @param ECX High 32 bits of physical address of caller allocated - STM_RESOURCE_LIST. - - @note All fields of STM_RESOURCE_LIST are inputs only, except for the - ReturnStatus bit. On input, the ReturnStatus bit must be clear. On - return, the ReturnStatus bit is set for each resource request granted, - and clear for each resource request denied. There are no other fields - modified by ProtectResourceVMCALL(). The STM_RESOURCE_LIST must be - contained entirely within a single 4K page. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The STM has successfully - merged the entire protection request into the active protection - profile. There is therefore no need to check the ReturnStatus - bits in the STM_RESOURCE_LIST. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_UNPROTECTABLE_RESOURCE - At least one of the requested resource protections intersects a - BIOS required resource. Therefore, the caller must walk through - the STM_RESOURCE_LIST to determine which of the requested - resources was not granted protection. The entire list must be - traversed since there may be multiple failures. - @retval EAX #ERROR_STM_MALFORMED_RESOURCE_LIST - The resource list could not be parsed correctly, or did not - terminate before crossing a 4K page boundary. The caller must - walk through the STM_RESOURCE_LIST to determine which of the - requested resources was not granted protection. The entire list - must be traversed since there may be multiple failures. - @retval EAX #ERROR_STM_OUT_OF_RESOURCES - The STM has encountered an internal error and cannot complete - the request. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_PROTECT_RESOURCE (BIT16 | 3) - - -/** - The UnProtectResourceVMCALL() is invoked by the MLE root to request that the - STM allow the SMI handler access to the specified resources. - - @param EAX #STM_API_UNPROTECT_RESOURCE (0x00010004) - @param EBX Low 32 bits of physical address of caller allocated - STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero, - making the buffer 4K aligned. - @param ECX High 32 bits of physical address of caller allocated - STM_RESOURCE_LIST. - - @note All fields of STM_RESOURCE_LIST are inputs only, except for the - ReturnStatus bit. On input, the ReturnStatus bit must be clear. On - return, the ReturnStatus bit is set for each resource processed. For - a properly formed STM_RESOURCE_LIST, this should be all resources - listed. There are no other fields modified by - UnProtectResourceVMCALL(). The STM_RESOURCE_LIST must be contained - entirely within a single 4K page. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The requested resources are - not being guarded by the STM. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_MALFORMED_RESOURCE_LIST - The resource list could not be parsed correctly, or did not - terminate before crossing a 4K page boundary. The caller must - walk through the STM_RESOURCE_LIST to determine which of the - requested resources were not able to be unprotected. The entire - list must be traversed since there may be multiple failures. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_UNPROTECT_RESOURCE (BIT16 | 4) - - -/** - The GetBiosResourcesVMCALL() is invoked by the MLE root to request the list - of BIOS required resources from the STM. - - @param EAX #STM_API_GET_BIOS_RESOURCES (0x00010005) - @param EBX Low 32 bits of physical address of caller allocated destination - buffer. Bits 11:0 are ignored and assumed to be zero, making the - buffer 4K aligned. - @param ECX High 32 bits of physical address of caller allocated destination - buffer. - @param EDX Indicates which page of the BIOS resource list to copy into the - destination buffer. The first page is indicated by 0, the second - page by 1, etc. - - @retval CF 0 - No error, EAX set to STM_SUCCESS. The destination buffer - contains the BIOS required resources. If the page retrieved is - the last page, EDX will be cleared to 0. If there are more pages - to retrieve, EDX is incremented to the next page index. Calling - software should iterate on GetBiosResourcesVMCALL() until EDX is - returned cleared to 0. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_PAGE_NOT_FOUND - The page index supplied in EDX input was out of range. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - @retval EDX Page index of next page to read. A return of EDX=0 signifies - that the entire list has been read. - @note EDX is both an input and an output register. - - @note All other registers unmodified. -**/ -#define STM_API_GET_BIOS_RESOURCES (BIT16 | 5) - - -/** - The ManageVmcsDatabaseVMCALL() is invoked by the MLE root to add or remove an - MLE guest (including the MLE root) from the list of protected domains. - - @param EAX #STM_API_MANAGE_VMCS_DATABASE (0x00010006) - @param EBX Low 32 bits of physical address of caller allocated - STM_VMCS_DATABASE_REQUEST. Bits 11:0 are ignored and assumed to - be zero, making the buffer 4K aligned. - @param ECX High 32 bits of physical address of caller allocated - STM_VMCS_DATABASE_REQUEST. - - @note All fields of STM_VMCS_DATABASE_REQUEST are inputs only. They are not - modified by ManageVmcsDatabaseVMCALL(). - - @retval CF 0 - No error, EAX set to STM_SUCCESS. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_INVALID_VMCS - Indicates a request to remove a VMCS from the database was made, - but the referenced VMCS was not found in the database. - @retval EAX #ERROR_STM_VMCS_PRESENT - Indicates a request to add a VMCS to the database was made, but - the referenced VMCS was already present in the database. - @retval EAX #ERROR_INVALID_PARAMETER - Indicates non-zero reserved field. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred - - @note All other registers unmodified. -**/ -#define STM_API_MANAGE_VMCS_DATABASE (BIT16 | 6) - -/** - STM VMCS Database Request for #STM_API_MANAGE_VMCS_DATABASE VMCALL -**/ -typedef struct { - /// - /// bits 11:0 are reserved and must be 0 - /// - UINT64 VmcsPhysPointer; - UINT32 DomainType :4; - UINT32 XStatePolicy :2; - UINT32 DegradationPolicy :4; - /// - /// Must be 0 - /// - UINT32 Reserved1 :22; - UINT32 AddOrRemove; -} STM_VMCS_DATABASE_REQUEST; - -/** - Values for the DomainType field of #STM_VMCS_DATABASE_REQUEST - @{ -**/ -#define DOMAIN_UNPROTECTED 0 -#define DOMAIN_DISALLOWED_IO_OUT BIT0 -#define DOMAIN_DISALLOWED_IO_IN BIT1 -#define DOMAIN_INTEGRITY BIT2 -#define DOMAIN_CONFIDENTIALITY BIT3 -#define DOMAIN_INTEGRITY_PROT_OUT_IN (DOMAIN_INTEGRITY) -#define DOMAIN_FULLY_PROT_OUT_IN (DOMAIN_CONFIDENTIALITY | DOMAIN_INTEGRITY) -#define DOMAIN_FULLY_PROT (DOMAIN_FULLY_PROT_OUT_IN | DOMAIN_DISALLOWED_IO_IN | DOMAIN_DISALLOWED_IO_OUT) -/// @} - -/** - Values for the XStatePolicy field of #STM_VMCS_DATABASE_REQUEST - @{ -**/ -#define XSTATE_READWRITE 0x00 -#define XSTATE_READONLY 0x01 -#define XSTATE_SCRUB 0x03 -/// @} - -/** - Values for the AddOrRemove field of #STM_VMCS_DATABASE_REQUEST - @{ -**/ -#define STM_VMCS_DATABASE_REQUEST_ADD 1 -#define STM_VMCS_DATABASE_REQUEST_REMOVE 0 -/// @} - - -/** - InitializeProtectionVMCALL() prepares the STM for setup of the initial - protection profile which is subsequently communicated via one or more - invocations of ProtectResourceVMCALL(), prior to invoking StartStmVMCALL(). - It is only necessary to invoke InitializeProtectionVMCALL() on one processor - thread. InitializeProtectionVMCALL() does not alter whether SMIs are masked - or unmasked. The STM should return back to the MLE with "Blocking by SMI" set - to 1 in the GUEST_INTERRUPTIBILITY field for the VMCS the STM created for the - MLE guest. - - @param EAX #STM_API_INITIALIZE_PROTECTION (0x00010007) - - @retval CF 0 - No error, EAX set to STM_SUCCESS, EBX bits set to indicate STM - capabilities as defined below. The STM has set up an empty - protection profile, except for the resources that it sets up to - protect itself. The STM must not allow the SMI handler to map - any pages from the MSEG Base to the top of TSEG. The STM must - also not allow SMI handler access to those MSRs which the STM - requires for its own protection. - @retval CF 1 - An error occurred, EAX holds relevant error value. - @retval EAX #ERROR_STM_ALREADY_STARTED - The STM is already configured and active. The STM remains active - and guarding the previously enabled resource list. - @retval EAX #ERROR_STM_UNPROTECTABLE - The STM determines that based on the platform configuration, the - STM is unable to protect itself. For example, the BIOS required - resource list contains memory pages in MSEG. - @retval EAX #ERROR_STM_UNSPECIFIED - An unspecified error occurred. - - @note All other registers unmodified. -**/ -#define STM_API_INITIALIZE_PROTECTION (BIT16 | 7) - -/** - Byte granular support bits returned in EBX from #STM_API_INITIALIZE_PROTECTION - @{ -**/ -#define STM_RSC_BGI BIT1 -#define STM_RSC_BGM BIT2 -#define STM_RSC_MSR BIT3 -/// @} - - -/** - The ManageEventLogVMCALL() is invoked by the MLE root to control the logging - feature. It consists of several sub-functions to facilitate establishment of - the log itself, configuring what events will be logged, and functions to - start, stop, and clear the log. - - @param EAX #STM_API_MANAGE_EVENT_LOG (0x00010008) - @param EBX Low 32 bits of physical address of caller allocated - STM_EVENT_LOG_MANAGEMENT_REQUEST. Bits 11:0 are ignored and - assumed to be zero, making the buffer 4K aligned. - @param ECX High 32 bits of physical address of caller allocated - STM_EVENT_LOG_MANAGEMENT_REQUEST. - - @retval CF=0 - No error, EAX set to STM_SUCCESS. - @retval CF=1 - An error occurred, EAX holds relevant error value. See subfunction - descriptions below for details. - - @note All other registers unmodified. -**/ -#define STM_API_MANAGE_EVENT_LOG (BIT16 | 8) - -/// -/// STM Event Log Management Request for #STM_API_MANAGE_EVENT_LOG VMCALL -/// -typedef struct { - UINT32 SubFunctionIndex; - union { - struct { - UINT32 PageCount; - // - // number of elements is PageCount - // - UINT64 Pages[]; - } LogBuffer; - // - // bitmap of EVENT_TYPE - // - UINT32 EventEnableBitmap; - } Data; -} STM_EVENT_LOG_MANAGEMENT_REQUEST; - -/** - Defines values for the SubFunctionIndex field of - #STM_EVENT_LOG_MANAGEMENT_REQUEST - @{ -**/ -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_NEW_LOG 1 -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CONFIGURE_LOG 2 -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_START_LOG 3 -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_STOP_LOG 4 -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CLEAR_LOG 5 -#define STM_EVENT_LOG_MANAGEMENT_REQUEST_DELETE_LOG 6 -/// @} - -/** - Log Entry Header -**/ -typedef struct { - UINT32 EventSerialNumber; - UINT16 Type; - UINT16 Lock :1; - UINT16 Valid :1; - UINT16 ReadByMle :1; - UINT16 Wrapped :1; - UINT16 Reserved :12; -} LOG_ENTRY_HEADER; - -/** - Enum values for the Type field of #LOG_ENTRY_HEADER -**/ -typedef enum { - EvtLogStarted, - EvtLogStopped, - EvtLogInvalidParameterDetected, - EvtHandledProtectionException, - /// - /// unhandled protection exceptions result in reset & cannot be logged - /// - EvtBiosAccessToUnclaimedResource, - EvtMleResourceProtectionGranted, - EvtMleResourceProtectionDenied, - EvtMleResourceUnprotect, - EvtMleResourceUnprotectError, - EvtMleDomainTypeDegraded, - /// - /// add more here - /// - EvtMleMax, - /// - /// Not used - /// - EvtInvalid = 0xFFFFFFFF, -} EVENT_TYPE; - -typedef struct { - UINT32 Reserved; -} ENTRY_EVT_LOG_STARTED; - -typedef struct { - UINT32 Reserved; -} ENTRY_EVT_LOG_STOPPED; - -typedef struct { - UINT32 VmcallApiNumber; -} ENTRY_EVT_LOG_INVALID_PARAM; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_MLE_RSC_PROT_GRANTED; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_MLE_RSC_PROT_DENIED; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_MLE_RSC_UNPROT; - -typedef struct { - STM_RSC Resource; -} ENTRY_EVT_MLE_RSC_UNPROT_ERROR; - -typedef struct { - UINT64 VmcsPhysPointer; - UINT8 ExpectedDomainType; - UINT8 DegradedDomainType; -} ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED; - -typedef union { - ENTRY_EVT_LOG_STARTED Started; - ENTRY_EVT_LOG_STOPPED Stopped; - ENTRY_EVT_LOG_INVALID_PARAM InvalidParam; - ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION HandledProtectionException; - ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC BiosUnclaimedRsc; - ENTRY_EVT_MLE_RSC_PROT_GRANTED MleRscProtGranted; - ENTRY_EVT_MLE_RSC_PROT_DENIED MleRscProtDenied; - ENTRY_EVT_MLE_RSC_UNPROT MleRscUnprot; - ENTRY_EVT_MLE_RSC_UNPROT_ERROR MleRscUnprotError; - ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED MleDomainTypeDegraded; -} LOG_ENTRY_DATA; - -typedef struct { - LOG_ENTRY_HEADER Hdr; - LOG_ENTRY_DATA Data; -} STM_LOG_ENTRY; - -/** - Maximum STM Log Entry Size -**/ -#define STM_LOG_ENTRY_SIZE 256 - - -/** - STM Protection Exception Stack Frame Structures -**/ - -typedef struct { - UINT32 Rdi; - UINT32 Rsi; - UINT32 Rbp; - UINT32 Rdx; - UINT32 Rcx; - UINT32 Rbx; - UINT32 Rax; - UINT32 Cr3; - UINT32 Cr2; - UINT32 Cr0; - UINT32 VmcsExitInstructionInfo; - UINT32 VmcsExitInstructionLength; - UINT64 VmcsExitQualification; - /// - /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value - /// - UINT32 ErrorCode; - UINT32 Rip; - UINT32 Cs; - UINT32 Rflags; - UINT32 Rsp; - UINT32 Ss; -} STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32; - -typedef struct { - UINT64 R15; - UINT64 R14; - UINT64 R13; - UINT64 R12; - UINT64 R11; - UINT64 R10; - UINT64 R9; - UINT64 R8; - UINT64 Rdi; - UINT64 Rsi; - UINT64 Rbp; - UINT64 Rdx; - UINT64 Rcx; - UINT64 Rbx; - UINT64 Rax; - UINT64 Cr8; - UINT64 Cr3; - UINT64 Cr2; - UINT64 Cr0; - UINT64 VmcsExitInstructionInfo; - UINT64 VmcsExitInstructionLength; - UINT64 VmcsExitQualification; - /// - /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value - /// - UINT64 ErrorCode; - UINT64 Rip; - UINT64 Cs; - UINT64 Rflags; - UINT64 Rsp; - UINT64 Ss; -} STM_PROTECTION_EXCEPTION_STACK_FRAME_X64; - -typedef union { - STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 *Ia32StackFrame; - STM_PROTECTION_EXCEPTION_STACK_FRAME_X64 *X64StackFrame; -} STM_PROTECTION_EXCEPTION_STACK_FRAME; - -/** - Enum values for the ErrorCode field in - #STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 and - #STM_PROTECTION_EXCEPTION_STACK_FRAME_X64 -**/ -typedef enum { - TxtSmmPageViolation = 1, - TxtSmmMsrViolation, - TxtSmmRegisterViolation, - TxtSmmIoViolation, - TxtSmmPciViolation -} TXT_SMM_PROTECTION_EXCEPTION_TYPE; - -/** - TXT Pocessor SMM Descriptor (PSD) structures -**/ - -typedef struct { - UINT64 SpeRip; - UINT64 SpeRsp; - UINT16 SpeSs; - UINT16 PageViolationException:1; - UINT16 MsrViolationException:1; - UINT16 RegisterViolationException:1; - UINT16 IoViolationException:1; - UINT16 PciViolationException:1; - UINT16 Reserved1:11; - UINT32 Reserved2; -} STM_PROTECTION_EXCEPTION_HANDLER; - -typedef struct { - UINT8 ExecutionDisableOutsideSmrr:1; - UINT8 Intel64Mode:1; - UINT8 Cr4Pae : 1; - UINT8 Cr4Pse : 1; - UINT8 Reserved1 : 4; -} STM_SMM_ENTRY_STATE; - -typedef struct { - UINT8 SmramToVmcsRestoreRequired : 1; ///> BIOS restore hint - UINT8 ReinitializeVmcsRequired : 1; ///> BIOS request - UINT8 Reserved2 : 6; -} STM_SMM_RESUME_STATE; - -typedef struct { - UINT8 DomainType : 4; ///> STM input to BIOS on each SMI - UINT8 XStatePolicy : 2; ///> STM input to BIOS on each SMI - UINT8 EptEnabled : 1; - UINT8 Reserved3 : 1; -} STM_SMM_STATE; - -#define TXT_SMM_PSD_OFFSET 0xfb00 -#define TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE SIGNATURE_64('T', 'X', 'T', 'P', 'S', 'S', 'I', 'G') -#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR 1 -#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR 0 - -typedef struct { - UINT64 Signature; - UINT16 Size; - UINT8 SmmDescriptorVerMajor; - UINT8 SmmDescriptorVerMinor; - UINT32 LocalApicId; - STM_SMM_ENTRY_STATE SmmEntryState; - STM_SMM_RESUME_STATE SmmResumeState; - STM_SMM_STATE StmSmmState; - UINT8 Reserved4; - UINT16 SmmCs; - UINT16 SmmDs; - UINT16 SmmSs; - UINT16 SmmOtherSegment; - UINT16 SmmTr; - UINT16 Reserved5; - UINT64 SmmCr3; - UINT64 SmmStmSetupRip; - UINT64 SmmStmTeardownRip; - UINT64 SmmSmiHandlerRip; - UINT64 SmmSmiHandlerRsp; - UINT64 SmmGdtPtr; - UINT32 SmmGdtSize; - UINT32 RequiredStmSmmRevId; - STM_PROTECTION_EXCEPTION_HANDLER StmProtectionExceptionHandler; - UINT64 Reserved6; - UINT64 BiosHwResourceRequirementsPtr; - // extend area - UINT64 AcpiRsdp; - UINT8 PhysicalAddressBits; -} TXT_PROCESSOR_SMM_DESCRIPTOR; - -#pragma pack () - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/StmResourceDescriptor.h b/CloverEFI/UefiCpuPkg/Include/Register/StmResourceDescriptor.h deleted file mode 100644 index 1518462ec..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/StmResourceDescriptor.h +++ /dev/null @@ -1,228 +0,0 @@ -/** @file - STM Resource Descriptor - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - SMI Transfer Monitor (STM) User Guide Revision 1.00 - -**/ - -#ifndef _STM_RESOURCE_DESCRIPTOR_H_ -#define _STM_RESOURCE_DESCRIPTOR_H_ - -#pragma pack (1) - -/** - STM Resource Descriptor Header -**/ -typedef struct { - UINT32 RscType; - UINT16 Length; - UINT16 ReturnStatus:1; - UINT16 Reserved:14; - UINT16 IgnoreResource:1; -} STM_RSC_DESC_HEADER; - -/** - Define values for the RscType field of #STM_RSC_DESC_HEADER - @{ -**/ -#define END_OF_RESOURCES 0 -#define MEM_RANGE 1 -#define IO_RANGE 2 -#define MMIO_RANGE 3 -#define MACHINE_SPECIFIC_REG 4 -#define PCI_CFG_RANGE 5 -#define TRAPPED_IO_RANGE 6 -#define ALL_RESOURCES 7 -#define REGISTER_VIOLATION 8 -#define MAX_DESC_TYPE 8 -/// @} - -/** - STM Resource End Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT64 ResourceListContinuation; -} STM_RSC_END; - -/** - STM Resource Memory Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT64 Base; - UINT64 Length; - UINT32 RWXAttributes:3; - UINT32 Reserved:29; - UINT32 Reserved_2; -} STM_RSC_MEM_DESC; - -/** - Define values for the RWXAttributes field of #STM_RSC_MEM_DESC - @{ -**/ -#define STM_RSC_MEM_R 0x1 -#define STM_RSC_MEM_W 0x2 -#define STM_RSC_MEM_X 0x4 -/// @} - -/** - STM Resource I/O Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT16 Base; - UINT16 Length; - UINT32 Reserved; -} STM_RSC_IO_DESC; - -/** - STM Resource MMIO Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT64 Base; - UINT64 Length; - UINT32 RWXAttributes:3; - UINT32 Reserved:29; - UINT32 Reserved_2; -} STM_RSC_MMIO_DESC; - -/** - Define values for the RWXAttributes field of #STM_RSC_MMIO_DESC - @{ -**/ -#define STM_RSC_MMIO_R 0x1 -#define STM_RSC_MMIO_W 0x2 -#define STM_RSC_MMIO_X 0x4 -/// @} - -/** - STM Resource MSR Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT32 MsrIndex; - UINT32 KernelModeProcessing:1; - UINT32 Reserved:31; - UINT64 ReadMask; - UINT64 WriteMask; -} STM_RSC_MSR_DESC; - -/** - STM PCI Device Path node used for the PciDevicePath field of - #STM_RSC_PCI_CFG_DESC -**/ -typedef struct { - /// - /// Must be 1, indicating Hardware Device Path - /// - UINT8 Type; - /// - /// Must be 1, indicating PCI - /// - UINT8 Subtype; - /// - /// sizeof(STM_PCI_DEVICE_PATH_NODE) which is 6 - /// - UINT16 Length; - UINT8 PciFunction; - UINT8 PciDevice; -} STM_PCI_DEVICE_PATH_NODE; - -/** - STM Resource PCI Configuration Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT16 RWAttributes:2; - UINT16 Reserved:14; - UINT16 Base; - UINT16 Length; - UINT8 OriginatingBusNumber; - UINT8 LastNodeIndex; - STM_PCI_DEVICE_PATH_NODE PciDevicePath[1]; -//STM_PCI_DEVICE_PATH_NODE PciDevicePath[LastNodeIndex + 1]; -} STM_RSC_PCI_CFG_DESC; - -/** - Define values for the RWAttributes field of #STM_RSC_PCI_CFG_DESC - @{ -**/ -#define STM_RSC_PCI_CFG_R 0x1 -#define STM_RSC_PCI_CFG_W 0x2 -/// @} - -/** - STM Resource Trapped I/O Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT16 Base; - UINT16 Length; - UINT16 In:1; - UINT16 Out:1; - UINT16 Api:1; - UINT16 Reserved1:13; - UINT16 Reserved2; -} STM_RSC_TRAPPED_IO_DESC; - -/** - STM Resource All Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; -} STM_RSC_ALL_RESOURCES_DESC; - -/** - STM Register Volation Descriptor -**/ -typedef struct { - STM_RSC_DESC_HEADER Hdr; - UINT32 RegisterType; - UINT32 Reserved; - UINT64 ReadMask; - UINT64 WriteMask; -} STM_REGISTER_VIOLATION_DESC; - -/** - Enum values for the RWAttributes field of #STM_REGISTER_VIOLATION_DESC -**/ -typedef enum { - StmRegisterCr0, - StmRegisterCr2, - StmRegisterCr3, - StmRegisterCr4, - StmRegisterCr8, - StmRegisterMax, -} STM_REGISTER_VIOLATION_TYPE; - -/** - Union of all STM resource types -**/ -typedef union { - STM_RSC_DESC_HEADER Header; - STM_RSC_END End; - STM_RSC_MEM_DESC Mem; - STM_RSC_IO_DESC Io; - STM_RSC_MMIO_DESC Mmio; - STM_RSC_MSR_DESC Msr; - STM_RSC_PCI_CFG_DESC PciCfg; - STM_RSC_TRAPPED_IO_DESC TrappedIo; - STM_RSC_ALL_RESOURCES_DESC All; - STM_REGISTER_VIOLATION_DESC RegisterViolation; -} STM_RSC; - -#pragma pack () - -#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Register/StmStatusCode.h b/CloverEFI/UefiCpuPkg/Include/Register/StmStatusCode.h deleted file mode 100644 index f1fcb8b6e..000000000 --- a/CloverEFI/UefiCpuPkg/Include/Register/StmStatusCode.h +++ /dev/null @@ -1,78 +0,0 @@ -/** @file - STM Status Codes - - Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - @par Specification Reference: - SMI Transfer Monitor (STM) User Guide Revision 1.00 - -**/ - -#ifndef _STM_STATUS_CODE_H_ -#define _STM_STATUS_CODE_H_ - -/** - STM Status Codes -**/ -typedef UINT32 STM_STATUS; - -/** - Success code have BIT31 clear. - All error codes have BIT31 set. - STM errors have BIT16 set. - SMM errors have BIT17 set - Errors that apply to both STM and SMM have bits BIT15, BT16, and BIT17 set. - STM TXT.ERRORCODE codes have BIT30 set. - @{ -**/ -#define STM_SUCCESS 0x00000000 -#define SMM_SUCCESS 0x00000000 -#define ERROR_STM_SECURITY_VIOLATION (BIT31 | BIT16 | 0x0001) -#define ERROR_STM_CACHE_TYPE_NOT_SUPPORTED (BIT31 | BIT16 | 0x0002) -#define ERROR_STM_PAGE_NOT_FOUND (BIT31 | BIT16 | 0x0003) -#define ERROR_STM_BAD_CR3 (BIT31 | BIT16 | 0x0004) -#define ERROR_STM_PHYSICAL_OVER_4G (BIT31 | BIT16 | 0x0005) -#define ERROR_STM_VIRTUAL_SPACE_TOO_SMALL (BIT31 | BIT16 | 0x0006) -#define ERROR_STM_UNPROTECTABLE_RESOURCE (BIT31 | BIT16 | 0x0007) -#define ERROR_STM_ALREADY_STARTED (BIT31 | BIT16 | 0x0008) -#define ERROR_STM_WITHOUT_SMX_UNSUPPORTED (BIT31 | BIT16 | 0x0009) -#define ERROR_STM_STOPPED (BIT31 | BIT16 | 0x000A) -#define ERROR_STM_BUFFER_TOO_SMALL (BIT31 | BIT16 | 0x000B) -#define ERROR_STM_INVALID_VMCS_DATABASE (BIT31 | BIT16 | 0x000C) -#define ERROR_STM_MALFORMED_RESOURCE_LIST (BIT31 | BIT16 | 0x000D) -#define ERROR_STM_INVALID_PAGECOUNT (BIT31 | BIT16 | 0x000E) -#define ERROR_STM_LOG_ALLOCATED (BIT31 | BIT16 | 0x000F) -#define ERROR_STM_LOG_NOT_ALLOCATED (BIT31 | BIT16 | 0x0010) -#define ERROR_STM_LOG_NOT_STOPPED (BIT31 | BIT16 | 0x0011) -#define ERROR_STM_LOG_NOT_STARTED (BIT31 | BIT16 | 0x0012) -#define ERROR_STM_RESERVED_BIT_SET (BIT31 | BIT16 | 0x0013) -#define ERROR_STM_NO_EVENTS_ENABLED (BIT31 | BIT16 | 0x0014) -#define ERROR_STM_OUT_OF_RESOURCES (BIT31 | BIT16 | 0x0015) -#define ERROR_STM_FUNCTION_NOT_SUPPORTED (BIT31 | BIT16 | 0x0016) -#define ERROR_STM_UNPROTECTABLE (BIT31 | BIT16 | 0x0017) -#define ERROR_STM_UNSUPPORTED_MSR_BIT (BIT31 | BIT16 | 0x0018) -#define ERROR_STM_UNSPECIFIED (BIT31 | BIT16 | 0xFFFF) -#define ERROR_SMM_BAD_BUFFER (BIT31 | BIT17 | 0x0001) -#define ERROR_SMM_INVALID_RSC (BIT31 | BIT17 | 0x0004) -#define ERROR_SMM_INVALID_BUFFER_SIZE (BIT31 | BIT17 | 0x0005) -#define ERROR_SMM_BUFFER_TOO_SHORT (BIT31 | BIT17 | 0x0006) -#define ERROR_SMM_INVALID_LIST (BIT31 | BIT17 | 0x0007) -#define ERROR_SMM_OUT_OF_MEMORY (BIT31 | BIT17 | 0x0008) -#define ERROR_SMM_AFTER_INIT (BIT31 | BIT17 | 0x0009) -#define ERROR_SMM_UNSPECIFIED (BIT31 | BIT17 | 0xFFFF) -#define ERROR_INVALID_API (BIT31 | BIT17 | BIT16 | BIT15 | 0x0001) -#define ERROR_INVALID_PARAMETER (BIT31 | BIT17 | BIT16 | BIT15 | 0x0002) -#define STM_CRASH_PROTECTION_EXCEPTION (BIT31 | BIT30 | 0xF001) -#define STM_CRASH_PROTECTION_EXCEPTION_FAILURE (BIT31 | BIT30 | 0xF002) -#define STM_CRASH_DOMAIN_DEGRADATION_FAILURE (BIT31 | BIT30 | 0xF003) -#define STM_CRASH_BIOS_PANIC (BIT31 | BIT30 | 0xE000) -/// @} - -#endif diff --git a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf b/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf deleted file mode 100644 index 442eb07e9..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf +++ /dev/null @@ -1,44 +0,0 @@ -## @file -# This library defines some routines that are generic for IA32 family CPU -# to be UEFI specification compliant. -# -# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = BaseUefiCpuLib - FILE_GUID = 34C24FD7-7A90-45c2-89FD-946473D9CE98 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = UefiCpuLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources.IA32] - Ia32/InitializeFpu.asm - Ia32/InitializeFpu.S - -[Sources.X64] - X64/InitializeFpu.asm - X64/InitializeFpu.S - -[Packages] - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - UefiCpuLib - diff --git a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S b/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S deleted file mode 100644 index 4972bc2e7..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S +++ /dev/null @@ -1,73 +0,0 @@ -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* -#------------------------------------------------------------------------------ - -# -# Float control word initial value: -# all exceptions masked, double-precision, round-to-nearest -# -ASM_PFX(mFpuControlWord): .word 0x027F -# -# Multimedia-extensions control word: -# all exceptions masked, round-to-nearest, flush to zero for masked underflow -# -ASM_PFX(mMmxControlWord): .long 0x01F80 - -# -# Initializes floating point units for requirement of UEFI specification. -# -# This function initializes floating-point control word to 0x027F (all exceptions -# masked,double-precision, round-to-nearest) and multimedia-extensions control word -# (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero -# for masked underflow). -# -ASM_GLOBAL ASM_PFX(InitializeFloatingPointUnits) -ASM_PFX(InitializeFloatingPointUnits): - - pushl %ebx - - # - # Initialize floating point units - # - finit - fldcw ASM_PFX(mFpuControlWord) - - # - # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test - # whether the processor supports SSE instruction. - # - movl $1, %eax - cpuid - btl $25, %edx - jnc Done - - # - # Set OSFXSR bit 9 in CR4 - # - movl %cr4, %eax - or $0x200, %eax - movl %eax, %cr4 - - # - # The processor should support SSE instruction and we can use - # ldmxcsr instruction - # - ldmxcsr ASM_PFX(mMmxControlWord) - -Done: - popl %ebx - - ret - -#END - diff --git a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S b/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S deleted file mode 100644 index 64750afb8..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S +++ /dev/null @@ -1,57 +0,0 @@ -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* -#------------------------------------------------------------------------------ - -# -# Initializes floating point units for requirement of UEFI specification. -# -# This function initializes floating-point control word to 0x027F (all exceptions -# masked,double-precision, round-to-nearest) and multimedia-extensions control word -# (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero -# for masked underflow). -# -ASM_GLOBAL ASM_PFX(InitializeFloatingPointUnits) -ASM_PFX(InitializeFloatingPointUnits): - - # - # Initialize floating point units - # - finit - - # - # Float control word initial value: - # all exceptions masked, double-precision, round-to-nearest - # - pushq $0x027F - lea (%rsp), %rax - fldcw (%rax) - popq %rax - - # - # Set OSFXSR bit 9 in CR4 - # - movq %cr4, %rax - or $0x200, %rax - movq %rax, %cr4 - - # - # Multimedia-extensions control word: - # all exceptions masked, round-to-nearest, flush to zero for masked underflow - # - pushq $0x01F80 - lea (%rsp), %rax - ldmxcsr (%rax) - popq %rax - - ret - diff --git a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm b/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm deleted file mode 100644 index 0a036b6ae..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm +++ /dev/null @@ -1,62 +0,0 @@ -;------------------------------------------------------------------------------ -;* -;* Copyright (c) 2009, Intel Corporation. All rights reserved.
-;* This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php -;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;* -;* -;------------------------------------------------------------------------------ - - -.const -; -; Float control word initial value: -; all exceptions masked, double-precision, round-to-nearest -; -mFpuControlWord DW 027Fh -; -; Multimedia-extensions control word: -; all exceptions masked, round-to-nearest, flush to zero for masked underflow -; -mMmxControlWord DD 01F80h - -.code - - -; -; Initializes floating point units for requirement of UEFI specification. -; -; This function initializes floating-point control word to 0x027F (all exceptions -; masked,double-precision, round-to-nearest) and multimedia-extensions control word -; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero -; for masked underflow). -; -InitializeFloatingPointUnits PROC PUBLIC - - ; - ; Initialize floating point units - ; - ; The following opcodes stand for instruction 'finit' - ; to be supported by some 64-bit assemblers - ; - DB 9Bh, 0DBh, 0E3h - fldcw mFpuControlWord - - ; - ; Set OSFXSR bit 9 in CR4 - ; - mov rax, cr4 - or rax, BIT9 - mov cr4, rax - - ldmxcsr mMmxControlWord - - ret -InitializeFloatingPointUnits ENDP - -END diff --git a/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c deleted file mode 100644 index 77c24deed..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ /dev/null @@ -1,754 +0,0 @@ -/** @file - Local APIC Library. - - This local APIC library instance supports xAPIC mode only. - - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include -#include - -// -// Library internal functions -// - -/** - Read from a local APIC register. - - This function reads from a local APIC register either in xAPIC or x2APIC mode. - It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be - accessed using multiple 32-bit loads or stores, so this function only performs - 32-bit read. - - @param MmioOffset The MMIO offset of the local APIC register in xAPIC mode. - It must be 16-byte aligned. - - @return 32-bit Value read from the register. -**/ -UINT32 -EFIAPI -ReadLocalApicReg ( - IN UINTN MmioOffset - ) -{ - ASSERT ((MmioOffset & 0xf) == 0); - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); - - return MmioRead32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset); -} - -/** - Write to a local APIC register. - - This function writes to a local APIC register either in xAPIC or x2APIC mode. - It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be - accessed using multiple 32-bit loads or stores, so this function only performs - 32-bit write. - - if the register index is invalid or unsupported in current APIC mode, then ASSERT. - - @param MmioOffset The MMIO offset of the local APIC register in xAPIC mode. - It must be 16-byte aligned. - @param Value Value to be written to the register. -**/ -VOID -EFIAPI -WriteLocalApicReg ( - IN UINTN MmioOffset, - IN UINT32 Value - ) -{ - ASSERT ((MmioOffset & 0xf) == 0); - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); - - MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset, Value); -} - -/** - Send an IPI by writing to ICR. - - This function returns after the IPI has been accepted by the target processor. - - @param IcrLow 32-bit value to be written to the low half of ICR. - @param ApicId APIC ID of the target processor if this IPI is targeted for a specific processor. -**/ -VOID -SendIpi ( - IN UINT32 IcrLow, - IN UINT32 ApicId - ) -{ - LOCAL_APIC_ICR_LOW IcrLowReg; - - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); - ASSERT (ApicId <= 0xff); - - // - // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. - // - WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, ApicId << 24); - WriteLocalApicReg (XAPIC_ICR_LOW_OFFSET, IcrLow); - do { - IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET); - } while (IcrLowReg.Bits.DeliveryStatus != 0); -} - -// -// Library API implementation functions -// - -/** - Get the current local APIC mode. - - If local APIC is disabled, then ASSERT. - - @retval LOCAL_APIC_MODE_XAPIC current APIC mode is xAPIC. - @retval LOCAL_APIC_MODE_X2APIC current APIC mode is x2APIC. -**/ -UINTN -EFIAPI -GetApicMode ( - VOID - ) -{ - DEBUG_CODE ( - { - MSR_IA32_APIC_BASE ApicBaseMsr; - - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); - // - // Local APIC should have been enabled - // - ASSERT (ApicBaseMsr.Bits.En != 0); - ASSERT (ApicBaseMsr.Bits.Extd == 0); - } - ); - return LOCAL_APIC_MODE_XAPIC; -} - -/** - Set the current local APIC mode. - - If the specified local APIC mode is not valid, then ASSERT. - If the specified local APIC mode can't be set as current, then ASSERT. - - @param ApicMode APIC mode to be set. -**/ -VOID -EFIAPI -SetApicMode ( - IN UINTN ApicMode - ) -{ - ASSERT (ApicMode == LOCAL_APIC_MODE_XAPIC); - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); -} - -/** - Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. - - In xAPIC mode, the initial local APIC ID is 8-bit, and may be different from current APIC ID. - In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, - the 32-bit local APIC ID is returned as initial APIC ID. - - @return 32-bit initial local APIC ID of the executing processor. -**/ -UINT32 -EFIAPI -GetInitialApicId ( - VOID - ) -{ - UINT32 RegEbx; - - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); - - AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); - return RegEbx >> 24; -} - -/** - Get the local APIC ID of the executing processor. - - @return 32-bit local APIC ID of the executing processor. -**/ -UINT32 -EFIAPI -GetApicId ( - VOID - ) -{ - UINT32 ApicId; - - ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); - - ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); - ApicId >>= 24; - return ApicId; -} - -/** - Get the value of the local APIC version register. - - @return the value of the local APIC version register. -**/ -UINT32 -EFIAPI -GetApicVersion ( - VOID - ) -{ - return ReadLocalApicReg (XAPIC_VERSION_OFFSET); -} - -/** - Send a Fixed IPI to a specified target processor. - - This function returns after the IPI has been accepted by the target processor. - - @param ApicId The local APIC ID of the target processor. - @param Vector The vector number of the interrupt being sent. -**/ -VOID -EFIAPI -SendFixedIpi ( - IN UINT32 ApicId, - IN UINT8 Vector - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED; - IcrLow.Bits.Level = 1; - IcrLow.Bits.Vector = Vector; - SendIpi (IcrLow.Uint32, ApicId); -} - -/** - Send a Fixed IPI to all processors excluding self. - - This function returns after the IPI has been accepted by the target processors. - - @param Vector The vector number of the interrupt being sent. -**/ -VOID -EFIAPI -SendFixedIpiAllExcludingSelf ( - IN UINT8 Vector - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED; - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - IcrLow.Bits.Vector = Vector; - SendIpi (IcrLow.Uint32, 0); -} - -/** - Send a SMI IPI to a specified target processor. - - This function returns after the IPI has been accepted by the target processor. - - @param ApicId Specify the local APIC ID of the target processor. -**/ -VOID -EFIAPI -SendSmiIpi ( - IN UINT32 ApicId - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI; - IcrLow.Bits.Level = 1; - SendIpi (IcrLow.Uint32, ApicId); -} - -/** - Send a SMI IPI to all processors excluding self. - - This function returns after the IPI has been accepted by the target processors. -**/ -VOID -EFIAPI -SendSmiIpiAllExcludingSelf ( - VOID - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI; - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - SendIpi (IcrLow.Uint32, 0); -} - -/** - Send an INIT IPI to a specified target processor. - - This function returns after the IPI has been accepted by the target processor. - - @param ApicId Specify the local APIC ID of the target processor. -**/ -VOID -EFIAPI -SendInitIpi ( - IN UINT32 ApicId - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT; - IcrLow.Bits.Level = 1; - SendIpi (IcrLow.Uint32, ApicId); -} - -/** - Send an INIT IPI to all processors excluding self. - - This function returns after the IPI has been accepted by the target processors. -**/ -VOID -EFIAPI -SendInitIpiAllExcludingSelf ( - VOID - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - IcrLow.Uint32 = 0; - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT; - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - SendIpi (IcrLow.Uint32, 0); -} - -/** - Send an INIT-Start-up-Start-up IPI sequence to a specified target processor. - - This function returns after the IPI has been accepted by the target processor. - - if StartupRoutine >= 1M, then ASSERT. - if StartupRoutine is not multiple of 4K, then ASSERT. - - @param ApicId Specify the local APIC ID of the target processor. - @param StartupRoutine Points to a start-up routine which is below 1M physical - address and 4K aligned. -**/ -VOID -EFIAPI -SendInitSipiSipi ( - IN UINT32 ApicId, - IN UINT32 StartupRoutine - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - ASSERT (StartupRoutine < 0x100000); - ASSERT ((StartupRoutine & 0xfff) == 0); - - SendInitIpi (ApicId); - MicroSecondDelay (10); - IcrLow.Uint32 = 0; - IcrLow.Bits.Vector = (StartupRoutine >> 12); - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; - IcrLow.Bits.Level = 1; - SendIpi (IcrLow.Uint32, ApicId); - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, ApicId); -} - -/** - Send an INIT-Start-up-Start-up IPI sequence to all processors excluding self. - - This function returns after the IPI has been accepted by the target processors. - - if StartupRoutine >= 1M, then ASSERT. - if StartupRoutine is not multiple of 4K, then ASSERT. - - @param StartupRoutine Points to a start-up routine which is below 1M physical - address and 4K aligned. -**/ -VOID -EFIAPI -SendInitSipiSipiAllExcludingSelf ( - IN UINT32 StartupRoutine - ) -{ - LOCAL_APIC_ICR_LOW IcrLow; - - ASSERT (StartupRoutine < 0x100000); - ASSERT ((StartupRoutine & 0xfff) == 0); - - SendInitIpiAllExcludingSelf (); - MicroSecondDelay (10); - IcrLow.Uint32 = 0; - IcrLow.Bits.Vector = (StartupRoutine >> 12); - IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; - IcrLow.Bits.Level = 1; - IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; - SendIpi (IcrLow.Uint32, 0); - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, 0); -} - -/** - Programming Virtual Wire Mode. - - This function programs the local APIC for virtual wire mode following - the example described in chapter A.3 of the MP 1.4 spec. - - IOxAPIC is not involved in this type of virtual wire mode. -**/ -VOID -EFIAPI -ProgramVirtualWireMode ( - VOID - ) -{ - LOCAL_APIC_SVR Svr; - LOCAL_APIC_LVT_LINT Lint; - - // - // Enable the APIC via SVR and set the spurious interrupt to use Int 00F. - // - Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); - Svr.Bits.SpuriousVector = 0xf; - Svr.Bits.SoftwareEnable = 1; - WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); - - // - // Program the LINT0 vector entry as ExtInt. Not masked, edge, active high. - // - Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET); - Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT; - Lint.Bits.InputPinPolarity = 0; - Lint.Bits.TriggerMode = 0; - Lint.Bits.Mask = 0; - WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32); - - // - // Program the LINT0 vector entry as NMI. Not masked, edge, active high. - // - Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET); - Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI; - Lint.Bits.InputPinPolarity = 0; - Lint.Bits.TriggerMode = 0; - Lint.Bits.Mask = 0; - WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32); -} - -/** - Disable LINT0 & LINT1 interrupts. - - This function sets the mask flag in the LVT LINT0 & LINT1 registers. -**/ -VOID -EFIAPI -DisableLvtInterrupts ( - VOID - ) -{ - LOCAL_APIC_LVT_LINT LvtLint; - - LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET); - LvtLint.Bits.Mask = 1; - WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, LvtLint.Uint32); - - LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET); - LvtLint.Bits.Mask = 1; - WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, LvtLint.Uint32); -} - -/** - Read the initial count value from the init-count register. - - @return The initial count value read from the init-count register. -**/ -UINT32 -EFIAPI -GetApicTimerInitCount ( - VOID - ) -{ - return ReadLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET); -} - -/** - Read the current count value from the current-count register. - - @return The current count value read from the current-count register. -**/ -UINT32 -EFIAPI -GetApicTimerCurrentCount ( - VOID - ) -{ - return ReadLocalApicReg (XAPIC_TIMER_CURRENT_COUNT_OFFSET); -} - -/** - Initialize the local APIC timer. - - The local APIC timer is initialized and enabled. - - @param DivideValue The divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. - If it is 0, then use the current divide value in the DCR. - @param InitCount The initial count value. - @param PeriodicMode If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. - @param Vector The timer interrupt vector number. -**/ -VOID -EFIAPI -InitializeApicTimer ( - IN UINTN DivideValue, - IN UINT32 InitCount, - IN BOOLEAN PeriodicMode, - IN UINT8 Vector - ) -{ - LOCAL_APIC_SVR Svr; - LOCAL_APIC_DCR Dcr; - LOCAL_APIC_LVT_TIMER LvtTimer; - UINT32 Divisor; - - // - // Ensure local APIC is in software-enabled state. - // - Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); - Svr.Bits.SoftwareEnable = 1; - WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); - - // - // Program init-count register. - // - WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount); - - if (DivideValue != 0) { - ASSERT (DivideValue <= 128); - ASSERT (DivideValue == GetPowerOfTwo32((UINT32)DivideValue)); - Divisor = (UINT32)((HighBitSet32 ((UINT32)DivideValue) - 1) & 0x7); - - Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); - Dcr.Bits.DivideValue1 = (Divisor & 0x3); - Dcr.Bits.DivideValue2 = (Divisor >> 2); - WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32); - } - - // - // Enable APIC timer interrupt with specified timer mode. - // - LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); - if (PeriodicMode) { - LvtTimer.Bits.TimerMode = 1; - } else { - LvtTimer.Bits.TimerMode = 0; - } - LvtTimer.Bits.Mask = 0; - LvtTimer.Bits.Vector = Vector; - WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); -} - -/** - Get the state of the local APIC timer. - - @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. - @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. - @param Vector Return the timer interrupt vector number. -**/ -VOID -EFIAPI -GetApicTimerState ( - OUT UINTN *DivideValue OPTIONAL, - OUT BOOLEAN *PeriodicMode OPTIONAL, - OUT UINT8 *Vector OPTIONAL - ) -{ - UINT32 Divisor; - LOCAL_APIC_DCR Dcr; - LOCAL_APIC_LVT_TIMER LvtTimer; - - if (DivideValue != NULL) { - Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); - Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2); - Divisor = (Divisor + 1) & 0x7; - *DivideValue = ((UINTN)1) << Divisor; - } - - if (PeriodicMode != NULL || Vector != NULL) { - LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); - if (PeriodicMode != NULL) { - if (LvtTimer.Bits.TimerMode == 1) { - *PeriodicMode = TRUE; - } else { - *PeriodicMode = FALSE; - } - } - if (Vector != NULL) { - *Vector = (UINT8) LvtTimer.Bits.Vector; - } - } -} - -/** - Enable the local APIC timer interrupt. -**/ -VOID -EFIAPI -EnableApicTimerInterrupt ( - VOID - ) -{ - LOCAL_APIC_LVT_TIMER LvtTimer; - - LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); - LvtTimer.Bits.Mask = 0; - WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); -} - -/** - Disable the local APIC timer interrupt. -**/ -VOID -EFIAPI -DisableApicTimerInterrupt ( - VOID - ) -{ - LOCAL_APIC_LVT_TIMER LvtTimer; - - LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); - LvtTimer.Bits.Mask = 1; - WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); -} - -/** - Get the local APIC timer interrupt state. - - @retval TRUE The local APIC timer interrupt is enabled. - @retval FALSE The local APIC timer interrupt is disabled. -**/ -BOOLEAN -EFIAPI -GetApicTimerInterruptState ( - VOID - ) -{ - LOCAL_APIC_LVT_TIMER LvtTimer; - - LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); - return (BOOLEAN)(LvtTimer.Bits.Mask == 0); -} - -/** - Send EOI to the local APIC. -**/ -VOID -EFIAPI -SendApicEoi ( - VOID - ) -{ - WriteLocalApicReg (XAPIC_EOI_OFFSET, 0); -} - -/** - Get the 32-bit address that a device should use to send a Message Signaled - Interrupt (MSI) to the Local APIC of the currently executing processor. - - @return 32-bit address used to send an MSI to the Local APIC. -**/ -UINT32 -EFIAPI -GetApicMsiAddress ( - VOID - ) -{ - LOCAL_APIC_MSI_ADDRESS MsiAddress; - - // - // Return address for an MSI interrupt to be delivered only to the APIC ID - // of the currently executing processor. - // - MsiAddress.Uint32 = 0; - MsiAddress.Bits.BaseAddress = 0xFEE; - MsiAddress.Bits.DestinationId = GetApicId (); - return MsiAddress.Uint32; -} - -/** - Get the 64-bit data value that a device should use to send a Message Signaled - Interrupt (MSI) to the Local APIC of the currently executing processor. - - If Vector is not in range 0x10..0xFE, then ASSERT(). - If DeliveryMode is not supported, then ASSERT(). - - @param Vector The 8-bit interrupt vector associated with the MSI. - Must be in the range 0x10..0xFE - @param DeliveryMode A 3-bit value that specifies how the recept of the MSI - is handled. The only supported values are: - 0: LOCAL_APIC_DELIVERY_MODE_FIXED - 1: LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY - 2: LOCAL_APIC_DELIVERY_MODE_SMI - 4: LOCAL_APIC_DELIVERY_MODE_NMI - 5: LOCAL_APIC_DELIVERY_MODE_INIT - 7: LOCAL_APIC_DELIVERY_MODE_EXTINT - - @param LevelTriggered TRUE specifies a level triggered interrupt. - FALSE specifies an edge triggered interrupt. - @param AssertionLevel Ignored if LevelTriggered is FALSE. - TRUE specifies a level triggered interrupt that active - when the interrupt line is asserted. - FALSE specifies a level triggered interrupt that active - when the interrupt line is deasserted. - - @return 64-bit data value used to send an MSI to the Local APIC. -**/ -UINT64 -EFIAPI -GetApicMsiValue ( - IN UINT8 Vector, - IN UINTN DeliveryMode, - IN BOOLEAN LevelTriggered, - IN BOOLEAN AssertionLevel - ) -{ - LOCAL_APIC_MSI_DATA MsiData; - - ASSERT (Vector >= 0x10 && Vector <= 0xFE); - ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3); - - MsiData.Uint64 = 0; - MsiData.Bits.Vector = Vector; - MsiData.Bits.DeliveryMode = (UINT32)DeliveryMode; - if (LevelTriggered) { - MsiData.Bits.TriggerMode = 1; - if (AssertionLevel) { - MsiData.Bits.Level = 1; - } - } - return MsiData.Uint64; -} diff --git a/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf b/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf deleted file mode 100644 index a86789b5f..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf +++ /dev/null @@ -1,46 +0,0 @@ -## @file -# Component description file for CPU Local APIC Library. -# -# This library instance supports xAPIC mode only. -# -# Copyright (c) 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = BaseXApicLib - FILE_GUID = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = LocalApicLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - BaseXApicLib.c - -[Packages] - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - DebugLib - TimerLib - IoLib - -[Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress - diff --git a/CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf deleted file mode 100644 index 9fa2f0950..000000000 --- a/CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf +++ /dev/null @@ -1,47 +0,0 @@ -## @file -# Component description file for CPU Local APIC Library. -# -# This library instance supports x2APIC capable processors -# which have xAPIC and x2APIC modes. -# -# Copyright (c) 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = BaseXApicX2ApicLib - FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = LocalApicLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - BaseXApicX2ApicLib.c - -[Packages] - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - DebugLib - TimerLib - IoLib - -[Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress - diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c deleted file mode 100644 index d3e3eb6d4..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c +++ /dev/null @@ -1,173 +0,0 @@ -/** @file - CPU Exception Handler Library common functions. - - Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "CpuExceptionCommon.h" - -// -// Error code flag indicating whether or not an error code will be -// pushed on the stack if an exception occurs. -// -// 1 means an error code will be pushed, otherwise 0 -// -CONST UINT32 mErrorCodeFlag = 0x00027d00; -RESERVED_VECTORS_DATA *mReservedVectors = NULL; - -// -// Define the maximum message length -// -#define MAX_DEBUG_MESSAGE_LENGTH 0x100 - -/** - Prints a message to the serial port. - - @param Format Format string for the message to print. - @param ... Variable argument list whose contents are accessed - based on the format string specified by Format. - -**/ -VOID -EFIAPI -InternalPrintMessage ( - IN CONST CHAR8 *Format, - ... - ) -{ - CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; - VA_LIST Marker; - - // - // Convert the message to an ASCII String - // - VA_START (Marker, Format); - AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); - VA_END (Marker); - - // - // Send the print string to a Serial Port - // - SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen(Buffer)); -} - -/** - Find and display image base address and return image base and its entry point. - - @param CurrentEip Current instruction pointer. - @param EntryPoint Return module entry point if module header is found. - - @return !0 Image base address. - @return 0 Image header cannot be found. -**/ -UINTN -FindModuleImageBase ( - IN UINTN CurrentEip, - OUT UINTN *EntryPoint - ) -{ - UINTN Pe32Data; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - VOID *PdbPointer; - - // - // Find Image Base - // - Pe32Data = CurrentEip & ~(mImageAlignSize - 1); - while (Pe32Data != 0) { - DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - // - // Make sure PE header address does not overflow and is less than the initial address. - // - if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CurrentEip)) { - if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - // - // It's PE image. - // - InternalPrintMessage ("!!!! Find PE image "); - *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff); - break; - } - } - } else { - // - // DOS image header is not present, TE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) && - ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) { - // - // It's TE image, it TE header and Machine type match - // - InternalPrintMessage ("!!!! Find TE image "); - *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; - break; - } - } - - // - // Not found the image base, check the previous aligned address - // - Pe32Data -= mImageAlignSize; - } - - if (Pe32Data != 0) { - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data); - if (PdbPointer != NULL) { - InternalPrintMessage ("%a", PdbPointer); - } else { - InternalPrintMessage ("(No PDB) " ); - } - } else { - InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); - } - - return Pe32Data; -} - -/** - Read and save reserved vector information - - @param[in] VectorInfo Pointer to reserved vector list. - @param[out] ReservedVector Pointer to reserved vector data buffer. - @param[in] VectorCount Vector number to be updated. - - @return EFI_SUCCESS Read and save vector info successfully. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - -**/ -EFI_STATUS -ReadAndVerifyVectorInfo ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo, - OUT RESERVED_VECTORS_DATA *ReservedVector, - IN UINTN VectorCount - ) -{ - while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { - if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) { - // - // If vector attrubute is invalid - // - return EFI_INVALID_PARAMETER; - } - if (VectorInfo->VectorNumber < VectorCount) { - ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute; - } - VectorInfo ++; - } - return EFI_SUCCESS; -} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h deleted file mode 100644 index d72ecb692..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ /dev/null @@ -1,242 +0,0 @@ -/** @file - Common header file for CPU Exception Handler Library. - - Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _CPU_EXCEPTION_COMMON_H_ -#define _CPU_EXCEPTION_COMMON_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CPU_EXCEPTION_NUM 32 -#define CPU_INTERRUPT_NUM 256 -#define HOOKAFTER_STUB_SIZE 16 - -#include "ArchInterruptDefs.h" - -// -// Record exception handler information -// -typedef struct { - UINTN ExceptionStart; - UINTN ExceptionStubHeaderSize; - UINTN HookAfterStubHeaderStart; -} EXCEPTION_HANDLER_TEMPLATE_MAP; - -extern CONST UINT32 mErrorCodeFlag; -extern CONST UINTN mImageAlignSize; -extern CONST UINTN mDoFarReturnFlag; -extern RESERVED_VECTORS_DATA *mReservedVectors; - -/** - Return address map of exception handler template so that C code can generate - exception tables. - - @param AddressMap Pointer to a buffer where the address map is returned. -**/ -VOID -EFIAPI -AsmGetTemplateAddressMap ( - OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap - ); - -/** - Return address map of exception handler template so that C code can generate - exception tables. - - @param IdtEntry Pointer to IDT entry to be updated. - @param InterruptHandler IDT handler value. - -**/ -VOID -ArchUpdateIdtEntry ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, - IN UINTN InterruptHandler - ); - -/** - Read IDT handler value from IDT entry. - - @param IdtEntry Pointer to IDT entry to be read. - -**/ -UINTN -ArchGetIdtHandler ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry - ); - -/** - Prints a message to the serial port. - - @param Format Format string for the message to print. - @param ... Variable argument list whose contents are accessed - based on the format string specified by Format. - -**/ -VOID -EFIAPI -InternalPrintMessage ( - IN CONST CHAR8 *Format, - ... - ); - -/** - Find and display image base address and return image base and its entry point. - - @param CurrentEip Current instruction pointer. - @param EntryPoint Return module entry point if module header is found. - - @return !0 Image base address. - @return 0 Image header cannot be found. -**/ -UINTN -FindModuleImageBase ( - IN UINTN CurrentEip, - OUT UINTN *EntryPoint - ); - -/** - Display CPU information. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -DumpCpuContent ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ); - -/** - Internal worker function to initialize exception handler. - - @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized - with default exception handlers. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - @retval EFI_UNSUPPORTED This function is not supported. - -**/ -EFI_STATUS -InitializeCpuExceptionHandlersWorker ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL - ); - -/** - Registers a function to be called from the processor interrupt handler. - - @param[in] InterruptType Defines which interrupt or exception to hook. - @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called - when a processor interrupt occurs. If this parameter is NULL, then the handler - will be uninstalled. - - @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. - @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was - previously installed. - @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not - previously installed. - @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, - or this function is not supported. -**/ -EFI_STATUS -RegisterCpuInterruptHandlerWorker ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler - ); - -/** - Internal worker function to update IDT entries accordling to vector attributes. - - @param[in] IdtTable Pointer to IDT table. - @param[in] TemplateMap Pointer to a buffer where the address map is returned. - @param[in] IdtEntryCount IDT entries number to be updated. - -**/ -VOID -UpdateIdtTable ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, - IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, - IN UINTN IdtEntryCount - ); - -/** - Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param[in] ExceptionType Exception type. - @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. - -**/ -VOID -ArchSaveExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ); - -/** - Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param[in] ExceptionType Exception type. - @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. - -**/ -VOID -ArchRestoreExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ); - -/** - Fix up the vector number in the vector code. - - @param[in] VectorBase Base address of the vector handler. - @param[in] VectorNum Index of vector. - @param[in] HookStub TRUE HookAfterStubHeaderEnd. - FALSE HookAfterStubHeaderEnd - -**/ -VOID -EFIAPI -AsmVectorNumFixup ( - IN VOID *VectorBase, - IN UINT8 VectorNum, - IN BOOLEAN HookStub - ); - -/** - Read and save reserved vector information - - @param[in] VectorInfo Pointer to reserved vector list. - @param[out] ReservedVector Pointer to reserved vector data buffer. - @param[in] VectorCount Vector number to be updated. - - @return EFI_SUCCESS Read and save vector info successfully. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - -**/ -EFI_STATUS -ReadAndVerifyVectorInfo ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo, - OUT RESERVED_VECTORS_DATA *ReservedVector, - IN UINTN VectorCount - ); - -#endif - diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni deleted file mode 100644 index 7aaaa5b53..000000000 Binary files a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni and /dev/null differ diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c deleted file mode 100644 index e6889c749..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ /dev/null @@ -1,170 +0,0 @@ -/** @file - CPU exception handler library implemenation for DXE modules. - - Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include "CpuExceptionCommon.h" -#include -#include - -CONST UINTN mDoFarReturnFlag = 0; - -extern SPIN_LOCK mDisplayMessageSpinLock; -extern EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler; - -/** - Initializes all CPU exceptions entries and provides the default exception handlers. - - Caller should try to get an array of interrupt and/or exception vectors that are in use and need to - persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. - If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. - - @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized - with default exception handlers. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - @retval EFI_UNSUPPORTED This function is not supported. - -**/ -EFI_STATUS -EFIAPI -InitializeCpuExceptionHandlers ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL - ) -{ - return InitializeCpuExceptionHandlersWorker (VectorInfo); -} - -/** - Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers. - - Caller should try to get an array of interrupt and/or exception vectors that are in use and need to - persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. - If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. - - @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized - with default interrupt/exception handlers. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - @retval EFI_UNSUPPORTED This function is not supported. - -**/ -EFI_STATUS -EFIAPI -InitializeCpuInterruptHandlers ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL - ) -{ - EFI_STATUS Status; - IA32_IDT_GATE_DESCRIPTOR *IdtTable; - IA32_DESCRIPTOR IdtDescriptor; - UINTN IdtEntryCount; - EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; - UINTN Index; - UINTN InterruptEntry; - UINT8 *InterruptEntryCode; - - mReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM); - ASSERT (mReservedVectors != NULL); - SetMem((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff); - if (VectorInfo != NULL) { - Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_INTERRUPT_NUM); - if (EFI_ERROR(Status)) { - FreePool(mReservedVectors); - return EFI_INVALID_PARAMETER; - } - } - InitializeSpinLock (&mDisplayMessageSpinLock); - mExternalInterruptHandler = AllocateZeroPool(sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM); - ASSERT (mExternalInterruptHandler != NULL); - - // - // Read IDT descriptor and calculate IDT size - // - AsmReadIdtr (&IdtDescriptor); - IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); - if (IdtEntryCount > CPU_INTERRUPT_NUM) { - IdtEntryCount = CPU_INTERRUPT_NUM; - } - // - // Create Interrupt Descriptor Table and Copy the old IDT table in - // - IdtTable = AllocateZeroPool(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM); - ASSERT (IdtTable != NULL); - CopyMem(IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount); - - AsmGetTemplateAddressMap (&TemplateMap); - ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); - InterruptEntryCode = AllocatePool (TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM); - ASSERT (InterruptEntryCode != NULL); - - InterruptEntry = (UINTN) InterruptEntryCode; - for (Index = 0; Index < CPU_INTERRUPT_NUM; Index ++) { - CopyMem( - (VOID *) InterruptEntry, - (VOID *) TemplateMap.ExceptionStart, - TemplateMap.ExceptionStubHeaderSize - ); - AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index, FALSE); - InterruptEntry += TemplateMap.ExceptionStubHeaderSize; - } - - TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode; - UpdateIdtTable (IdtTable, &TemplateMap, CPU_INTERRUPT_NUM); - - // - // Load Interrupt Descriptor Table - // - IdtDescriptor.Base = (UINTN) IdtTable; - IdtDescriptor.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1); - AsmWriteIdtr ((IA32_DESCRIPTOR *) &IdtDescriptor); - - return EFI_SUCCESS; -} - -/** - Registers a function to be called from the processor interrupt handler. - - This function registers and enables the handler specified by InterruptHandler for a processor - interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the - handler for the processor interrupt or exception type specified by InterruptType is uninstalled. - The installed handler is called once for each processor interrupt or exception. - NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or - InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned. - - @param[in] InterruptType Defines which interrupt or exception to hook. - @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called - when a processor interrupt occurs. If this parameter is NULL, then the handler - will be uninstalled. - - @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. - @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was - previously installed. - @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not - previously installed. - @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, - or this function is not supported. -**/ -EFI_STATUS -EFIAPI -RegisterCpuInterruptHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler - ) -{ - return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler); -} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c deleted file mode 100644 index a552656d5..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c +++ /dev/null @@ -1,288 +0,0 @@ -/** @file - CPU Exception Library provides DXE/SMM CPU common exception handler. - -Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that accompanies this distribution. -The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "CpuExceptionCommon.h" -#include - -// -// Spinlock for CPU information display -// -SPIN_LOCK mDisplayMessageSpinLock; - -// -// Image align size for DXE/SMM -// -CONST UINTN mImageAlignSize = SIZE_4KB; - -RESERVED_VECTORS_DATA mReservedVectorsData[CPU_INTERRUPT_NUM]; -EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_INTERRUPT_NUM]; -EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler = NULL; -UINTN mEnabledInterruptNum = 0; - -/** - Common exception handler. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -EFIAPI -CommonExceptionHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - EXCEPTION_HANDLER_CONTEXT *ExceptionHandlerContext; - - ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32); - - switch (mReservedVectors[ExceptionType].Attribute) { - case EFI_VECTOR_HANDOFF_HOOK_BEFORE: - // - // Need to jmp to old IDT handler after this exception handler - // - ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; - ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler; - break; - case EFI_VECTOR_HANDOFF_HOOK_AFTER: - while (TRUE) { - // - // If if anyone has gotten SPIN_LOCK for owner running hook after - // - if (AcquireSpinLockOrFail (&mReservedVectors[ExceptionType].SpinLock)) { - // - // Need to execute old IDT handler before running this exception handler - // - mReservedVectors[ExceptionType].ApicId = GetApicId (); - ArchSaveExceptionContext (ExceptionType, SystemContext); - ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; - ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler; - return; - } - // - // If failed to acquire SPIN_LOCK, check if it was locked by processor itself - // - if (mReservedVectors[ExceptionType].ApicId == GetApicId ()) { - // - // Old IDT handler has been executed, then retore CPU exception content to - // run new exception handler. - // - ArchRestoreExceptionContext (ExceptionType, SystemContext); - // - // Rlease spin lock for ApicId - // - ReleaseSpinLock (&mReservedVectors[ExceptionType].SpinLock); - break; - } - CpuPause (); - } - break; - case 0xffffffff: - break; - default: - // - // It should never reach here - // - CpuDeadLoop (); - break; - } - - if (mExternalInterruptHandler[ExceptionType] != NULL) { - (mExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext); - } else if (ExceptionType < CPU_EXCEPTION_NUM) { - // - // Get Spinlock to display CPU information - // - while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) { - CpuPause (); - } - // - // Display ExceptionType, CPU information and Image information - // - DumpCpuContent (ExceptionType, SystemContext); - // - // Release Spinlock of output message - // - ReleaseSpinLock (&mDisplayMessageSpinLock); - // - // Enter a dead loop if needn't to execute old IDT handler further - // - if (mReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) { - CpuDeadLoop (); - } - } -} - -/** - Internal worker function to update IDT entries accordling to vector attributes. - - @param[in] IdtTable Pointer to IDT table. - @param[in] TemplateMap Pointer to a buffer where the address map is returned. - @param[in] IdtEntryCount IDT entries number to be updated. - -**/ -VOID -UpdateIdtTable ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, - IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, - IN UINTN IdtEntryCount - ) -{ - UINT16 CodeSegment; - UINTN Index; - UINTN InterruptHandler; - - // - // Use current CS as the segment selector of interrupt gate in IDT - // - CodeSegment = AsmReadCs (); - - for (Index = 0; Index < IdtEntryCount; Index ++) { - IdtTable[Index].Bits.Selector = CodeSegment; - // - // Check reserved vectors attributes - // - switch (mReservedVectors[Index].Attribute) { - case EFI_VECTOR_HANDOFF_DO_NOT_HOOK: - // - // Keep original IDT entry - // - continue; - case EFI_VECTOR_HANDOFF_HOOK_AFTER: - InitializeSpinLock (&mReservedVectors[Index].SpinLock); - CopyMem( - (VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, - (VOID *) TemplateMap->HookAfterStubHeaderStart, - TemplateMap->ExceptionStubHeaderSize - ); - AsmVectorNumFixup ((VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index, TRUE); - // - // Go on the following code - // - case EFI_VECTOR_HANDOFF_HOOK_BEFORE: - // - // Save original IDT handler address - // - mReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]); - // - // Go on the following code - // - default: - // - // Update new IDT entry - // - InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize; - ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler); - break; - } - } - - // - // Save Interrupt number to global variable used for RegisterCpuInterruptHandler () - // - mEnabledInterruptNum = IdtEntryCount; -} - -/** - Internal worker function to initialize exception handler. - - @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized - with default exception handlers. - @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. - @retval EFI_UNSUPPORTED This function is not supported. - -**/ -EFI_STATUS -InitializeCpuExceptionHandlersWorker ( - IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL - ) -{ - EFI_STATUS Status; - IA32_DESCRIPTOR IdtDescriptor; - UINTN IdtEntryCount; - EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; - IA32_IDT_GATE_DESCRIPTOR *IdtTable; - - mReservedVectors = mReservedVectorsData; - SetMem((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff); - if (VectorInfo != NULL) { - Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_EXCEPTION_NUM); - if (EFI_ERROR(Status)) { - return EFI_INVALID_PARAMETER; - } - } - InitializeSpinLock (&mDisplayMessageSpinLock); - - mExternalInterruptHandler = mExternalInterruptHandlerTable; - // - // Read IDT descriptor and calculate IDT size - // - AsmReadIdtr (&IdtDescriptor); - IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); - if (IdtEntryCount > CPU_EXCEPTION_NUM) { - // - // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most - // - IdtEntryCount = CPU_EXCEPTION_NUM; - } - - IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; - AsmGetTemplateAddressMap (&TemplateMap); - ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); - UpdateIdtTable (IdtTable, &TemplateMap, IdtEntryCount); - mEnabledInterruptNum = IdtEntryCount; - return EFI_SUCCESS; -} - -/** - Registers a function to be called from the processor interrupt handler. - - @param[in] InterruptType Defines which interrupt or exception to hook. - @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called - when a processor interrupt occurs. If this parameter is NULL, then the handler - will be uninstalled. - - @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. - @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was - previously installed. - @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not - previously installed. - @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, - or this function is not supported. -**/ -EFI_STATUS -RegisterCpuInterruptHandlerWorker ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler - ) -{ - if (InterruptType < 0 || InterruptType >= (EFI_EXCEPTION_TYPE)mEnabledInterruptNum || - mReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) { - return EFI_UNSUPPORTED; - } - - if (InterruptHandler == NULL && mExternalInterruptHandler[InterruptType] == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (InterruptHandler != NULL && mExternalInterruptHandler[InterruptType] != NULL) { - return EFI_ALREADY_STARTED; - } - - mExternalInterruptHandler[InterruptType] = InterruptHandler; - return EFI_SUCCESS; -} - diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c deleted file mode 100644 index 40cdedfac..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ /dev/null @@ -1,202 +0,0 @@ -/** @file - IA32 CPU Exception Handler functons. - - Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "CpuExceptionCommon.h" - -/** - Return address map of exception handler template so that C code can generate - exception tables. - - @param IdtEntry Pointer to IDT entry to be updated. - @param InterruptHandler IDT handler value. - -**/ -VOID -ArchUpdateIdtEntry ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, - IN UINTN InterruptHandler - ) -{ - IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; - IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); - IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; -} - -/** - Read IDT handler value from IDT entry. - - @param IdtEntry Pointer to IDT entry to be read. - -**/ -UINTN -ArchGetIdtHandler ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry - ) -{ - return (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16); -} - -/** - Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. - -**/ -VOID -ArchSaveExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - IA32_EFLAGS32 Eflags; - // - // Save Exception context in global variable - // - mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextIa32->Eflags; - mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextIa32->Cs; - mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextIa32->Eip; - mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData; - // - // Clear IF flag to avoid old IDT handler enable interrupt by IRET - // - Eflags.UintN = SystemContext.SystemContextIa32->Eflags; - Eflags.Bits.IF = 0; - SystemContext.SystemContextIa32->Eflags = Eflags.UintN; - // - // Modify the EIP in stack, then old IDT handler will return to the stub code - // - SystemContext.SystemContextIa32->Eip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode; -} - -/** - Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -ArchRestoreExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - SystemContext.SystemContextIa32->Eflags = mReservedVectors[ExceptionType].OldFlags; - SystemContext.SystemContextIa32->Cs = mReservedVectors[ExceptionType].OldCs; - SystemContext.SystemContextIa32->Eip = mReservedVectors[ExceptionType].OldIp; - SystemContext.SystemContextIa32->ExceptionData = mReservedVectors[ExceptionType].ExceptionData; -} - -/** - Display CPU information. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -DumpCpuContent ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINTN ImageBase; - UINTN EntryPoint; - - InternalPrintMessage ( - "!!!! IA32 Exception Type - %08x CPU Apic ID - %08x !!!!\n", - ExceptionType, - GetApicId () - ); - InternalPrintMessage ( - "EIP - %08x, CS - %08x, EFLAGS - %08x\n", - SystemContext.SystemContextIa32->Eip, - SystemContext.SystemContextIa32->Cs, - SystemContext.SystemContextIa32->Eflags - ); - if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) { - InternalPrintMessage ( - "ExceptionData - %08x\n", - SystemContext.SystemContextIa32->ExceptionData - ); - } - InternalPrintMessage ( - "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n", - SystemContext.SystemContextIa32->Eax, - SystemContext.SystemContextIa32->Ecx, - SystemContext.SystemContextIa32->Edx, - SystemContext.SystemContextIa32->Ebx - ); - InternalPrintMessage ( - "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n", - SystemContext.SystemContextIa32->Esp, - SystemContext.SystemContextIa32->Ebp, - SystemContext.SystemContextIa32->Esi, - SystemContext.SystemContextIa32->Edi - ); - InternalPrintMessage ( - "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n", - SystemContext.SystemContextIa32->Ds, - SystemContext.SystemContextIa32->Es, - SystemContext.SystemContextIa32->Fs, - SystemContext.SystemContextIa32->Gs, - SystemContext.SystemContextIa32->Ss - ); - InternalPrintMessage ( - "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n", - SystemContext.SystemContextIa32->Cr0, - SystemContext.SystemContextIa32->Cr2, - SystemContext.SystemContextIa32->Cr3, - SystemContext.SystemContextIa32->Cr4 - ); - InternalPrintMessage ( - "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n", - SystemContext.SystemContextIa32->Dr0, - SystemContext.SystemContextIa32->Dr1, - SystemContext.SystemContextIa32->Dr2, - SystemContext.SystemContextIa32->Dr3 - ); - InternalPrintMessage ( - "DR6 - %08x, DR7 - %08x\n", - SystemContext.SystemContextIa32->Dr6, - SystemContext.SystemContextIa32->Dr7 - ); - InternalPrintMessage ( - "GDTR - %08x %08x, IDTR - %08x %08x\n", - SystemContext.SystemContextIa32->Gdtr[0], - SystemContext.SystemContextIa32->Gdtr[1], - SystemContext.SystemContextIa32->Idtr[0], - SystemContext.SystemContextIa32->Idtr[1] - ); - InternalPrintMessage ( - "LDTR - %08x, TR - %08x\n", - SystemContext.SystemContextIa32->Ldtr, - SystemContext.SystemContextIa32->Tr - ); - InternalPrintMessage ( - "FXSAVE_STATE - %08x\n", - &SystemContext.SystemContextIa32->FxSaveState - ); - - // - // Find module image base and module entry point by RIP - // - ImageBase = FindModuleImageBase (SystemContext.SystemContextIa32->Eip, &EntryPoint); - if (ImageBase != 0) { - InternalPrintMessage ( - " (ImageBase=%08x, EntryPoint=%08x) !!!!\n", - ImageBase, - EntryPoint - ); - } -} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S deleted file mode 100644 index 086e896e4..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S +++ /dev/null @@ -1,642 +0,0 @@ -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
-#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* ExceptionHandlerAsm.S -#* -#* Abstract: -#* -#* IA32 CPU Exception Handler -# -#------------------------------------------------------------------------------ - - -#.MMX -#.XMM - -ASM_GLOBAL ASM_PFX(CommonExceptionHandler) -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions -#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD # Do far return flag - -.text - -# -# exception handler stub table -# -Exception0Handle: - .byte 0x6a # push #VectorNum - .byte 0 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception1Handle: - .byte 0x6a # push #VectorNum - .byte 1 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception2Handle: - .byte 0x6a # push #VectorNum - .byte 2 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception3Handle: - .byte 0x6a # push #VectorNum - .byte 3 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception4Handle: - .byte 0x6a # push #VectorNum - .byte 4 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception5Handle: - .byte 0x6a # push #VectorNum - .byte 5 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception6Handle: - .byte 0x6a # push #VectorNum - .byte 6 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception7Handle: - .byte 0x6a # push #VectorNum - .byte 7 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception8Handle: - .byte 0x6a # push #VectorNum - .byte 8 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception9Handle: - .byte 0x6a # push #VectorNum - .byte 9 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception10Handle: - .byte 0x6a # push #VectorNum - .byte 10 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception11Handle: - .byte 0x6a # push #VectorNum - .byte 11 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception12Handle: - .byte 0x6a # push #VectorNum - .byte 12 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception13Handle: - .byte 0x6a # push #VectorNum - .byte 13 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception14Handle: - .byte 0x6a # push #VectorNum - .byte 14 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception15Handle: - .byte 0x6a # push #VectorNum - .byte 15 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception16Handle: - .byte 0x6a # push #VectorNum - .byte 16 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception17Handle: - .byte 0x6a # push #VectorNum - .byte 17 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception18Handle: - .byte 0x6a # push #VectorNum - .byte 18 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception19Handle: - .byte 0x6a # push #VectorNum - .byte 19 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception20Handle: - .byte 0x6a # push #VectorNum - .byte 20 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception21Handle: - .byte 0x6a # push #VectorNum - .byte 21 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception22Handle: - .byte 0x6a # push #VectorNum - .byte 22 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception23Handle: - .byte 0x6a # push #VectorNum - .byte 23 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception24Handle: - .byte 0x6a # push #VectorNum - .byte 24 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception25Handle: - .byte 0x6a # push #VectorNum - .byte 25 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception26Handle: - .byte 0x6a # push #VectorNum - .byte 26 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception27Handle: - .byte 0x6a # push #VectorNum - .byte 27 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception28Handle: - .byte 0x6a # push #VectorNum - .byte 28 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception29Handle: - .byte 0x6a # push #VectorNum - .byte 29 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception30Handle: - .byte 0x6a # push #VectorNum - .byte 30 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception31Handle: - .byte 0x6a # push #VectorNum - .byte 31 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax - -HookAfterStubBegin: - .byte 0x6a # push -VectorNum: - .byte 0 # 0 will be fixed - pushl %eax - .byte 0xB8 # movl ASM_PFX(HookAfterStubHeaderEnd), %eax - .long ASM_PFX(HookAfterStubHeaderEnd) - jmp *%eax -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) -ASM_PFX(HookAfterStubHeaderEnd): - popl %eax - subl $8, %esp # reserve room for filling exception data later - pushl 8(%esp) - xchgl (%esp), %ecx # get vector number - bt %ecx, ASM_PFX(mErrorCodeFlag) - jnc NoErrorData - pushl (%esp) # addition push if exception data needed -NoErrorData: - xchg (%esp), %ecx # restore ecx - pushl %eax - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - popl %eax - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - - # - # Get vector number from top of stack - # - xchgl (%esp), %ecx - andl $0x0FF, %ecx # Vector number should be less than 256 - cmpl $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - bt %ecx, ASM_PFX(mErrorCodeFlag) - jc HasErrorCode - -NoErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack - # - pushl %ecx - - # - # Put 0 (dummy) error code on stack, and restore ECX - # - xorl %ecx, %ecx # ECX = 0 - xchgl 4(%esp), %ecx - - jmp ErrorCodeAndVectorOnStack - -HasErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack and restore ECX - # - xchgl (%esp), %ecx - -ErrorCodeAndVectorOnStack: - pushl %ebp - movl %esp, %ebp - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + Vector Number + - # +---------------------+ - # + EBP + - # +---------------------+ <-- EBP - # - - # - # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 - # is 16-byte aligned - # - andl $0x0fffffff0, %esp - subl $12, %esp - - subl $8, %esp - pushl $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - pushl $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushl %eax - pushl %ecx - pushl %edx - pushl %ebx - leal 24(%ebp), %ecx - pushl %ecx # ESP - pushl (%ebp) # EBP - pushl %esi - pushl %edi - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; - movl %ss, %eax - pushl %eax - movzwl 16(%ebp), %eax - pushl %eax - movl %ds, %eax - pushl %eax - movl %es, %eax - pushl %eax - movl %fs, %eax - pushl %eax - movl %gs, %eax - pushl %eax - -#; UINT32 Eip; - movl 12(%ebp), %eax - pushl %eax - -#; UINT32 Gdtr[2], Idtr[2]; - subl $8, %esp - sidt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - - subl $8, %esp - sgdt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - -#; UINT32 Ldtr, Tr; - xorl %eax, %eax - str %ax - pushl %eax - sldt %ax - pushl %eax - -#; UINT32 EFlags; - movl 20(%ebp), %eax - pushl %eax - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - movl %cr4, %eax - orl $0x208, %eax - movl %eax, %cr4 - pushl %eax - movl %cr3, %eax - pushl %eax - movl %cr2, %eax - pushl %eax - xorl %eax, %eax - pushl %eax - movl %cr0, %eax - pushl %eax - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movl %dr7, %eax - pushl %eax - movl %dr6, %eax - pushl %eax - movl %dr3, %eax - pushl %eax - movl %dr2, %eax - pushl %eax - movl %dr1, %eax - pushl %eax - movl %dr0, %eax - pushl %eax - -#; FX_SAVE_STATE_IA32 FxSaveState; - subl $512, %esp - movl %esp, %edi - .byte 0x0f, 0x0ae, 0x07 #fxsave [edi] - -#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushl 8(%ebp) - -#; Prepare parameter and call - movl %esp, %edx - pushl %edx - movl 4(%ebp), %edx - pushl %edx - - # - # Call External Exception Handler - # - call ASM_PFX(CommonExceptionHandler) - addl $8, %esp - - cli -#; UINT32 ExceptionData; - addl $4, %esp - -#; FX_SAVE_STATE_IA32 FxSaveState; - movl %esp, %esi - .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi] - addl $512, %esp - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addl $24, %esp - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - popl %eax - movl %eax, %cr0 - addl $4, %esp # not for Cr1 - popl %eax - movl %eax, %cr2 - popl %eax - movl %eax, %cr3 - popl %eax - movl %eax, %cr4 - -#; UINT32 EFlags; - popl 20(%ebp) - -#; UINT32 Ldtr, Tr; -#; UINT32 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addl $24, %esp - -#; UINT32 Eip; - popl 12(%ebp) - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -#; NOTE - modified segment registers could hang the debugger... We -#; could attempt to insulate ourselves against this possibility, -#; but that poses risks as well. -#; - popl %gs - popl %fs - popl %es - popl %ds - popl 16(%ebp) - popl %ss - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popl %edi - popl %esi - addl $4, %esp # not for ebp - addl $4, %esp # not for esp - popl %ebx - popl %edx - popl %ecx - popl %eax - - popl -8(%ebp) - popl -4(%ebp) - movl %ebp, %esp - popl %ebp - addl $8, %esp - cmpl $0, -16(%esp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - jz DoReturn - cmpl $1, -20(%esp) # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - jz ErrorCode - jmp *-16(%esp) -ErrorCode: - subl $4, %esp - jmp *-12(%esp) - -DoReturn: - cmpl $0, ASM_PFX(mDoFarReturnFlag) - jz DoIret - pushl 8(%esp) # save EFLAGS - addl $16, %esp - pushl -8(%esp) # save CS in new location - pushl -8(%esp) # save EIP in new location - pushl -8(%esp) # save EFLAGS in new location - popfl # restore EFLAGS - retf # far return - -DoIret: - iretl - - -#---------------------------------------; -# _AsmGetTemplateAddressMap ; -#---------------------------------------; -# -# Protocol prototype -# AsmGetTemplateAddressMap ( -# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap -# ); -# -# Routine Description: -# -# Return address map of interrupt handler template so that C code can generate -# interrupt table. -# -# Arguments: -# -# -# Returns: -# -# Nothing -# -# -# Input: [ebp][0] = Original ebp -# [ebp][4] = Return address -# -# Output: Nothing -# -# Destroys: Nothing -#-----------------------------------------------------------------------------; -#------------------------------------------------------------------------------------- -# AsmGetAddressMap (&AddressMap); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap) -ASM_PFX(AsmGetTemplateAddressMap): - - pushl %ebp - movl %esp,%ebp - pushal - - movl 0x8(%ebp), %ebx - movl $Exception0Handle, (%ebx) - movl $(Exception1Handle - Exception0Handle), 0x4(%ebx) - movl $(HookAfterStubBegin), 0x8(%ebx) - - popal - popl %ebp - ret -#------------------------------------------------------------------------------------- -# AsmVectorNumFixup (*VectorBase, VectorNum, HookStub); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmVectorNumFixup) -ASM_PFX(AsmVectorNumFixup): - movl 8(%esp), %eax - movl 4(%esp), %ecx - movb %al, (VectorNum - HookAfterStubBegin)(%ecx) - ret diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni deleted file mode 100644 index af45a3387..000000000 Binary files a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni and /dev/null differ diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni deleted file mode 100644 index 6d3ee1c9e..000000000 Binary files a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni and /dev/null differ diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c deleted file mode 100644 index ee16ea856..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ /dev/null @@ -1,233 +0,0 @@ -/** @file - x64 CPU Exception Handler. - - Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "CpuExceptionCommon.h" - -/** - Return address map of exception handler template so that C code can generate - exception tables. - - @param IdtEntry Pointer to IDT entry to be updated. - @param InterruptHandler IDT handler value. -**/ -VOID -ArchUpdateIdtEntry ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, - IN UINTN InterruptHandler - ) -{ - IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; - IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); - IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); - IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; -} - -/** - Read IDT handler value from IDT entry. - - @param IdtEntry Pointer to IDT entry to be read. - -**/ -UINTN -ArchGetIdtHandler ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry - ) -{ - return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh) << 16) + - (((UINTN) IdtEntry->Bits.OffsetUpper) << 32); -} - -/** - Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -ArchSaveExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - IA32_EFLAGS32 Eflags; - // - // Save Exception context in global variable - // - mReservedVectors[ExceptionType].OldSs = SystemContext.SystemContextX64->Ss; - mReservedVectors[ExceptionType].OldSp = SystemContext.SystemContextX64->Rsp; - mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextX64->Rflags; - mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextX64->Cs; - mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextX64->Rip; - mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData; - // - // Clear IF flag to avoid old IDT handler enable interrupt by IRET - // - Eflags.UintN = SystemContext.SystemContextX64->Rflags; - Eflags.Bits.IF = 0; - SystemContext.SystemContextX64->Rflags = Eflags.UintN; - // - // Modify the EIP in stack, then old IDT handler will return to the stub code - // - SystemContext.SystemContextX64->Rip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode; -} - -/** - Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -ArchRestoreExceptionContext ( - IN UINTN ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - SystemContext.SystemContextX64->Ss = mReservedVectors[ExceptionType].OldSs; - SystemContext.SystemContextX64->Rsp = mReservedVectors[ExceptionType].OldSp; - SystemContext.SystemContextX64->Rflags = mReservedVectors[ExceptionType].OldFlags; - SystemContext.SystemContextX64->Cs = mReservedVectors[ExceptionType].OldCs; - SystemContext.SystemContextX64->Rip = mReservedVectors[ExceptionType].OldIp; - SystemContext.SystemContextX64->ExceptionData = mReservedVectors[ExceptionType].ExceptionData; -} - -/** - Display CPU information. - - @param ExceptionType Exception type. - @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. -**/ -VOID -DumpCpuContent ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINTN ImageBase; - UINTN EntryPoint; - - InternalPrintMessage ( - "!!!! X64 Exception Type - %016lx CPU Apic ID - %08x !!!!\n", - ExceptionType, - GetApicId () - ); - InternalPrintMessage ( - "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n", - SystemContext.SystemContextX64->Rip, - SystemContext.SystemContextX64->Cs, - SystemContext.SystemContextX64->Rflags - ); - if (mErrorCodeFlag & (1 << ExceptionType)) { - InternalPrintMessage ( - "ExceptionData - %016lx\n", - SystemContext.SystemContextX64->ExceptionData - ); - } - InternalPrintMessage ( - "RAX - %016lx, RCX - %016lx, RDX - %016lx\n", - SystemContext.SystemContextX64->Rax, - SystemContext.SystemContextX64->Rcx, - SystemContext.SystemContextX64->Rdx - ); - InternalPrintMessage ( - "RBX - %016lx, RSP - %016lx, RBP - %016lx\n", - SystemContext.SystemContextX64->Rbx, - SystemContext.SystemContextX64->Rsp, - SystemContext.SystemContextX64->Rbp - ); - InternalPrintMessage ( - "RSI - %016lx, RDI - %016lx\n", - SystemContext.SystemContextX64->Rsi, - SystemContext.SystemContextX64->Rdi - ); - InternalPrintMessage ( - "R8 - %016lx, R9 - %016lx, R10 - %016lx\n", - SystemContext.SystemContextX64->R8, - SystemContext.SystemContextX64->R9, - SystemContext.SystemContextX64->R10 - ); - InternalPrintMessage ( - "R11 - %016lx, R12 - %016lx, R13 - %016lx\n", - SystemContext.SystemContextX64->R11, - SystemContext.SystemContextX64->R12, - SystemContext.SystemContextX64->R13 - ); - InternalPrintMessage ( - "R14 - %016lx, R15 - %016lx\n", - SystemContext.SystemContextX64->R14, - SystemContext.SystemContextX64->R15 - ); - InternalPrintMessage ( - "DS - %016lx, ES - %016lx, FS - %016lx\n", - SystemContext.SystemContextX64->Ds, - SystemContext.SystemContextX64->Es, - SystemContext.SystemContextX64->Fs - ); - InternalPrintMessage ( - "GS - %016lx, SS - %016lx\n", - SystemContext.SystemContextX64->Gs, - SystemContext.SystemContextX64->Ss - ); - InternalPrintMessage ( - "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n", - SystemContext.SystemContextX64->Cr0, - SystemContext.SystemContextX64->Cr2, - SystemContext.SystemContextX64->Cr3 - ); - InternalPrintMessage ( - "CR4 - %016lx, CR8 - %016lx\n", - SystemContext.SystemContextX64->Cr4, - SystemContext.SystemContextX64->Cr8 - ); - InternalPrintMessage ( - "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n", - SystemContext.SystemContextX64->Dr0, - SystemContext.SystemContextX64->Dr1, - SystemContext.SystemContextX64->Dr2 - ); - InternalPrintMessage ( - "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n", - SystemContext.SystemContextX64->Dr3, - SystemContext.SystemContextX64->Dr6, - SystemContext.SystemContextX64->Dr7 - ); - InternalPrintMessage ( - "GDTR - %016lx %016lx, LDTR - %016lx\n", - SystemContext.SystemContextX64->Gdtr[0], - SystemContext.SystemContextX64->Gdtr[1], - SystemContext.SystemContextX64->Ldtr - ); - InternalPrintMessage ( - "IDTR - %016lx %016lx, TR - %016lx\n", - SystemContext.SystemContextX64->Idtr[0], - SystemContext.SystemContextX64->Idtr[1], - SystemContext.SystemContextX64->Tr - ); - InternalPrintMessage ( - "FXSAVE_STATE - %016lx\n", - &SystemContext.SystemContextX64->FxSaveState - ); - - // - // Find module image base and module entry point by RIP - // - ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint); - if (ImageBase != 0) { - InternalPrintMessage ( - " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n", - ImageBase, - EntryPoint - ); - } -} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S deleted file mode 100644 index 7711d274b..000000000 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S +++ /dev/null @@ -1,641 +0,0 @@ -#------------------------------------------------------------------------------ ; -# Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# Module Name: -# -# ExceptionHandlerAsm.S -# -# Abstract: -# -# x64 CPU Exception Handler -# -# Notes: -# -#------------------------------------------------------------------------------ - - - -ASM_GLOBAL ASM_PFX(CommonExceptionHandler) -#ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -#ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions -#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag -.text -.align 3 - -# -# exception handler stub table -# -Exception0Handle: - .byte 0x6a # push #VectorNum - .byte 0 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception1Handle: - .byte 0x6a # push #VectorNum - .byte 1 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception2Handle: - .byte 0x6a # push #VectorNum - .byte 2 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception3Handle: - .byte 0x6a # push #VectorNum - .byte 3 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception4Handle: - .byte 0x6a # push #VectorNum - .byte 4 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception5Handle: - .byte 0x6a # push #VectorNum - .byte 5 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception6Handle: - .byte 0x6a # push #VectorNum - .byte 6 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception7Handle: - .byte 0x6a # push #VectorNum - .byte 7 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception8Handle: - .byte 0x6a # push #VectorNum - .byte 8 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception9Handle: - .byte 0x6a # push #VectorNum - .byte 9 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception10Handle: - .byte 0x6a # push #VectorNum - .byte 10 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception11Handle: - .byte 0x6a # push #VectorNum - .byte 11 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception12Handle: - .byte 0x6a # push #VectorNum - .byte 12 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception13Handle: - .byte 0x6a # push #VectorNum - .byte 13 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception14Handle: - .byte 0x6a # push #VectorNum - .byte 14 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception15Handle: - .byte 0x6a # push #VectorNum - .byte 15 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception16Handle: - .byte 0x6a # push #VectorNum - .byte 16 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception17Handle: - .byte 0x6a # push #VectorNum - .byte 17 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception18Handle: - .byte 0x6a # push #VectorNum - .byte 18 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception19Handle: - .byte 0x6a # push #VectorNum - .byte 19 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception20Handle: - .byte 0x6a # push #VectorNum - .byte 20 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception21Handle: - .byte 0x6a # push #VectorNum - .byte 21 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception22Handle: - .byte 0x6a # push #VectorNum - .byte 22 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception23Handle: - .byte 0x6a # push #VectorNum - .byte 23 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception24Handle: - .byte 0x6a # push #VectorNum - .byte 24 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception25Handle: - .byte 0x6a # push #VectorNum - .byte 25 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception26Handle: - .byte 0x6a # push #VectorNum - .byte 26 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception27Handle: - .byte 0x6a # push #VectorNum - .byte 27 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception28Handle: - .byte 0x6a # push #VectorNum - .byte 28 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception29Handle: - .byte 0x6a # push #VectorNum - .byte 29 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception30Handle: - .byte 0x6a # push #VectorNum - .byte 30 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax -Exception31Handle: - .byte 0x6a # push #VectorNum - .byte 31 - pushq %rax - .byte 0x48, 0xB8 - .quad 0 #ASM_PFX(CommonInterruptEntry) - jmp *%rax - -HookAfterStubHeaderBegin: - .byte 0x6a # push -#VectorNum: -PatchVectorNum: - .byte 0 # 0 will be fixed - pushq %rax - .byte 0x48, 0xB8 # movq ASM_PFX(HookAfterStubHeaderEnd), %rax -# .quad ASM_PFX(HookAfterStubHeaderEnd) -PatchFuncAddress: - .quad 0 - jmp *%rax -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) -ASM_PFX(HookAfterStubHeaderEnd): - movq %rsp, %rax - andl $0x0fffffff0, %esp # make sure 16-byte aligned for exception context - subq $0x18, %rsp # reserve room for filling exception data later - pushq %rcx - movq 8(%rax), %rcx -# pushq %rax -# movabsl ASM_PFX(mErrorCodeFlag), %eax -# bt %ecx, %eax -# popq %rax - bt %ecx, ASM_PFX(mErrorCodeFlag)(%rip) - jnc NoErrorData - pushq (%rsp) # push additional rcx to make stack alignment -NoErrorData: - xchgq (%rsp), %rcx # restore rcx, save Exception Number in stack - pushq (%rax) # push rax into stack to keep code consistence - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - popq %rax - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - # - # Calculate vector number - # - xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number. - andq $0x0FF, %rcx - cmp $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - pushq %rax -# movabsl ASM_PFX(mErrorCodeFlag), %eax - movl ASM_PFX(mErrorCodeFlag)(%rip), %eax - bt %ecx, %eax - popq %rax - jc CommonInterruptEntry_al_0000 - -NoErrorCode: - - # - # Push a dummy error code on the stack - # to maintain coherent stack map - # - pushq (%rsp) - movq $0, 8(%rsp) -CommonInterruptEntry_al_0000: - pushq %rbp - movq %rsp, %rbp - pushq $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - pushq $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - - # - # Stack: - # +---------------------+ <-- 16-byte aligned ensured by processor - # + Old SS + - # +---------------------+ - # + Old RSP + - # +---------------------+ - # + RFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + RIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + RCX / Vector Number + - # +---------------------+ - # + RBP + - # +---------------------+ <-- RBP, 16-byte aligned - # - - - # - # Since here the stack pointer is 16-byte aligned, so - # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 - # is 16-byte aligned - # - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pushq %r15 - pushq %r14 - pushq %r13 - pushq %r12 - pushq %r11 - pushq %r10 - pushq %r9 - pushq %r8 - pushq %rax - pushq 8(%rbp) # RCX - pushq %rdx - pushq %rbx - pushq 48(%rbp) # RSP - pushq (%rbp) # RBP - pushq %rsi - pushq %rdi - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzwq 56(%rbp), %rax - pushq %rax # for ss - movzwq 32(%rbp), %rax - pushq %rax # for cs - movl %ds, %eax - pushq %rax - movl %es, %eax - pushq %rax - movl %fs, %eax - pushq %rax - movl %gs, %eax - pushq %rax - - movq %rcx, 8(%rbp) # save vector number - -#; UINT64 Rip; - pushq 24(%rbp) - -#; UINT64 Gdtr[2], Idtr[2]; - xorq %rax, %rax - pushq %rax - pushq %rax - sidt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - - xorq %rax, %rax - pushq %rax - pushq %rax - sgdt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - -#; UINT64 Ldtr, Tr; - xorq %rax, %rax - str %ax - pushq %rax - sldt %ax - pushq %rax - -#; UINT64 RFlags; - pushq 40(%rbp) - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - movq %cr8, %rax - pushq %rax - movq %cr4, %rax - orq $0x208, %rax - movq %rax, %cr4 - pushq %rax - mov %cr3, %rax - pushq %rax - mov %cr2, %rax - pushq %rax - xorq %rax, %rax - pushq %rax - mov %cr0, %rax - pushq %rax - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movq %dr7, %rax - pushq %rax - movq %dr6, %rax - pushq %rax - movq %dr3, %rax - pushq %rax - movq %dr2, %rax - pushq %rax - movq %dr1, %rax - pushq %rax - movq %dr0, %rax - pushq %rax - -#; FX_SAVE_STATE_X64 FxSaveState; - subq $512, %rsp - movq %rsp, %rdi - .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi] - -#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushq 16(%rbp) - -#; Prepare parameter and call - mov 8(%rbp), %rcx - mov %rsp, %rdx - # - # Per X64 calling convention, allocate maximum parameter stack space - # and make sure RSP is 16-byte aligned - # - subq $40, %rsp - call ASM_PFX(CommonExceptionHandler) - addq $40, %rsp - - cli -#; UINT64 ExceptionData; - addq $8, %rsp - -#; FX_SAVE_STATE_X64 FxSaveState; - - movq %rsp, %rsi - .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi] - addq $512, %rsp - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addq $48, %rsp - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - popq %rax - movq %rax, %cr0 - addq $8, %rsp # not for Cr1 - popq %rax - movq %rax, %cr2 - popq %rax - movq %rax, %cr3 - popq %rax - movq %rax, %cr4 - popq %rax - movq %rax, %cr8 - -#; UINT64 RFlags; - popq 40(%rbp) - -#; UINT64 Ldtr, Tr; -#; UINT64 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addq $48, %rsp - -#; UINT64 Rip; - popq 24(%rbp) - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; - popq %rax - # mov %rax, %gs ; not for gs - popq %rax - # mov %rax, %fs ; not for fs - # (X64 will not use fs and gs, so we do not restore it) - popq %rax - movl %eax, %es - popq %rax - movl %eax, %ds - popq 32(%rbp) # for cs - popq 56(%rbp) # for ss - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - popq %rdi - popq %rsi - addq $8, %rsp # not for rbp - popq 48(%rbp) # for rsp - popq %rbx - popq %rdx - popq %rcx - popq %rax - popq %r8 - popq %r9 - popq %r10 - popq %r11 - popq %r12 - popq %r13 - popq %r14 - popq %r15 - - movq %rbp, %rsp - popq %rbp - addq $16, %rsp - cmpq $0, -32(%rsp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - jz DoReturn # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - cmpb $1, -40(%rsp) - jz ErrorCode - jmp *-32(%rsp) -ErrorCode: - subq $8, %rsp - jmp *-24(%rsp) - -DoReturn: - pushq %rax -# movabsq ASM_PFX(mDoFarReturnFlag), %rax - movq ASM_PFX(mDoFarReturnFlag)(%rip), %rax - cmpq $0, %rax # Check if need to do far return instead of IRET - popq %rax - jz DoIret - pushq %rax - movq %rsp, %rax # save old RSP to rax - movq 0x20(%rsp), %rsp - pushq 0x10(%rax) # save CS in new location - pushq 0x8(%rax) # save EIP in new location - pushq 0x18(%rax) # save EFLAGS in new location - movq (%rax), %rax # restore rax - popfq # restore EFLAGS -# .byte 0x48 # prefix to composite "retq" with next "retf" -# lretq #retf # far return - .byte 0x48 # prefix to composite "retq" with next "retf" -#ifdef __APPLE__ - .byte 0xCB -#else - retf # far return -#endif - -DoIret: - iretq - - -#------------------------------------------------------------------------------------- -# AsmGetTemplateAddressMap (&AddressMap); -#------------------------------------------------------------------------------------- -# comments here for definition of address map -ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap) -ASM_PFX(AsmGetTemplateAddressMap): - -# movabsq $Exception0Handle, %rax -# movq %rax, (%rcx) -# movq $(Exception1Handle - Exception0Handle), 0x08(%rcx) -# movabsq $HookAfterStubHeaderBegin, %rax -# movq %rax, 0x10(%rcx) -# ret - leaq Exception0Handle(%rip), %rax - movq %rax, (%rcx) - movq $(Exception1Handle - Exception0Handle), 0x08(%rcx) - leaq HookAfterStubHeaderBegin(%rip), %rax - movq %rax, 0x10(%rcx) - ret - - -#------------------------------------------------------------------------------------- -# VOID -# EFIAPI -# AsmVectorNumFixup ( -# IN VOID *VectorBase, // RCX -# IN UINT8 VectorNum, // RDX -# IN BOOLEAN HookStub // R8 -# ); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmVectorNumFixup) -ASM_PFX(AsmVectorNumFixup): -# movq %rdx, %rax -# movb %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx) -# ret - pushq %rbp - movq %rsp, %rbp - -# Patch vector # - movb %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx) - -# Patch Function address - leaq ASM_PFX(HookAfterStubHeaderEnd)(%rip), %rax - leaq ASM_PFX(CommonInterruptEntry)(%rip), %r10 - testb %r8b, %r8b - cmovneq %rax, %r10 - movq %r10, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx) - - popq %rbp - ret - -#END - - diff --git a/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.c deleted file mode 100644 index 50a108726..000000000 --- a/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ /dev/null @@ -1,1692 +0,0 @@ -/** @file - MTRR setting library - - Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include - -// -// This table defines the offset, base and length of the fixed MTRRs -// -CONST FIXED_MTRR mMtrrLibFixedMtrrTable[] = { - { - MTRR_LIB_IA32_MTRR_FIX64K_00000, - 0, - SIZE_64KB - }, - { - MTRR_LIB_IA32_MTRR_FIX16K_80000, - 0x80000, - SIZE_16KB - }, - { - MTRR_LIB_IA32_MTRR_FIX16K_A0000, - 0xA0000, - SIZE_16KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_C0000, - 0xC0000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_C8000, - 0xC8000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_D0000, - 0xD0000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_D8000, - 0xD8000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_E0000, - 0xE0000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_E8000, - 0xE8000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_F0000, - 0xF0000, - SIZE_4KB - }, - { - MTRR_LIB_IA32_MTRR_FIX4K_F8000, - 0xF8000, - SIZE_4KB - }, -}; - -// -// Lookup table used to print MTRRs -// -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = { - "UC", // CacheUncacheable - "WC", // CacheWriteCombining - "R*", // Invalid - "R*", // Invalid - "WT", // CacheWriteThrough - "WP", // CacheWriteProtected - "WB", // CacheWriteBack - "R*" // Invalid -}; - -/** - Returns the variable MTRR count for the CPU. - - @return Variable MTRR count - -**/ -UINT32 -EFIAPI -GetVariableMtrrCount ( - VOID - ) -{ - UINT32 VariableMtrrCount; - - if (!IsMtrrSupported ()) { - return 0; - } - - VariableMtrrCount = (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - - return VariableMtrrCount; -} - -/** - Returns the firmware usable variable MTRR count for the CPU. - - @return Firmware usable variable MTRR count - -**/ -UINT32 -EFIAPI -GetFirmwareVariableMtrrCount ( - VOID - ) -{ - UINT32 VariableMtrrCount; - - VariableMtrrCount = GetVariableMtrrCount (); - if (VariableMtrrCount < RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER) { - return 0; - } - - return VariableMtrrCount - RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER; -} - -/** - Returns the default MTRR cache type for the system. - - @return The default MTRR cache type. - -**/ -MTRR_MEMORY_CACHE_TYPE -EFIAPI -MtrrGetDefaultMemoryType ( - VOID -) -{ - if (!IsMtrrSupported ()) { - return CacheUncacheable; -} - - return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7); -} - -/** - Preparation before programming MTRR. - - This function will do some preparation for programming MTRRs: - disable cache, invalid cache and disable MTRR caching functionality - - @return CR4 value before changing. - -**/ -UINTN -PreMtrrChange ( - VOID - ) -{ - UINTN Value; - - // - // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29) - // - AsmDisableCache (); - - // - // Save original CR4 value and clear PGE flag (Bit 7) - // - Value = AsmReadCr4 (); - AsmWriteCr4 (Value & (~BIT7)); - - // - // Flush all TLBs - // - CpuFlushTlb (); - - // - // Disable Mtrrs - // - AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0); - - // - // Return original CR4 value - // - return Value; -} - - -/** - Cleaning up after programming MTRRs. - - This function will do some clean up after programming MTRRs: - enable MTRR caching functionality, and enable cache - - @param Cr4 CR4 value to restore - -**/ -VOID -PostMtrrChange ( - UINTN Cr4 - ) -{ - // - // Enable Cache MTRR - // - AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); - - // - // Flush all TLBs - // - CpuFlushTlb (); - - // - // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29) - // - AsmEnableCache (); - - // - // Restore original CR4 value - // - AsmWriteCr4 (Cr4); -} - - -/** - Programs fixed MTRRs registers. - - @param MemoryCacheType The memory type to set. - @param Base The base address of memory range. - @param Length The length of memory range. - - @retval RETURN_SUCCESS The cache type was updated successfully - @retval RETURN_UNSUPPORTED The requested range or cache type was invalid - for the fixed MTRRs. - -**/ -RETURN_STATUS -ProgramFixedMtrr ( - IN UINT64 MemoryCacheType, - IN OUT UINT64 *Base, - IN OUT UINT64 *Length - ) -{ - UINT32 MsrNum; - UINT32 ByteShift; - UINT64 TempQword; - UINT64 OrMask; - UINT64 ClearMask; - - TempQword = 0; - OrMask = 0; - ClearMask = 0; - - for (MsrNum = 0; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) { - if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) && - (*Base < - ( - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress + - (8 * mMtrrLibFixedMtrrTable[MsrNum].Length) - ) - ) - ) { - break; - } - } - - if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) { - return RETURN_UNSUPPORTED; - } - - // - // We found the fixed MTRR to be programmed - // - for (ByteShift = 0; ByteShift < 8; ByteShift++) { - if (*Base == - ( - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress + - (ByteShift * mMtrrLibFixedMtrrTable[MsrNum].Length) - ) - ) { - break; - } - } - - if (ByteShift == 8) { - return RETURN_UNSUPPORTED; - } - - for ( - ; - ((ByteShift < 8) && (*Length >= mMtrrLibFixedMtrrTable[MsrNum].Length)); - ByteShift++ - ) { - OrMask |= LShiftU64 ((UINT64) MemoryCacheType, (UINT32) (ByteShift * 8)); - ClearMask |= LShiftU64 ((UINT64) 0xFF, (UINT32) (ByteShift * 8)); - *Length -= mMtrrLibFixedMtrrTable[MsrNum].Length; - *Base += mMtrrLibFixedMtrrTable[MsrNum].Length; - } - - if (ByteShift < 8 && (*Length != 0)) { - return RETURN_UNSUPPORTED; - } - - TempQword = - (AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr) & ~ClearMask) | OrMask; - AsmWriteMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr, TempQword); - return RETURN_SUCCESS; -} - - -/** - Get the attribute of variable MTRRs. - - This function shadows the content of variable MTRRs into an - internal array: VariableMtrr. - - @param MtrrValidBitsMask The mask for the valid bit of the MTRR - @param MtrrValidAddressMask The valid address mask for MTRR - @param VariableMtrr The array to shadow variable MTRRs content - - @return The return value of this paramter indicates the - number of MTRRs which has been used. - -**/ -UINT32 -EFIAPI -MtrrGetMemoryAttributeInVariableMtrr ( - IN UINT64 MtrrValidBitsMask, - IN UINT64 MtrrValidAddressMask, - OUT VARIABLE_MTRR *VariableMtrr - ) -{ - UINTN Index; - UINT32 MsrNum; - UINT32 UsedMtrr; - UINT32 FirmwareVariableMtrrCount; - UINT32 VariableMtrrEnd; - - if (!IsMtrrSupported ()) { - return 0; - } - - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); - VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1; - - ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR); - UsedMtrr = 0; - - for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE, Index = 0; - ( - (MsrNum < VariableMtrrEnd) && - (Index < FirmwareVariableMtrrCount) - ); - MsrNum += 2 - ) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) { - VariableMtrr[Index].Msr = MsrNum; - VariableMtrr[Index].BaseAddress = (AsmReadMsr64 (MsrNum) & - MtrrValidAddressMask); - VariableMtrr[Index].Length = ((~(AsmReadMsr64 (MsrNum + 1) & - MtrrValidAddressMask) - ) & - MtrrValidBitsMask - ) + 1; - VariableMtrr[Index].Type = (AsmReadMsr64 (MsrNum) & 0x0ff); - VariableMtrr[Index].Valid = TRUE; - VariableMtrr[Index].Used = TRUE; - UsedMtrr = UsedMtrr + 1; - Index++; - } - } - return UsedMtrr; -} - - -/** - Checks overlap between given memory range and MTRRs. - - @param Start The start address of memory range. - @param End The end address of memory range. - @param VariableMtrr The array to shadow variable MTRRs content - - @retval TRUE Overlap exists. - @retval FALSE No overlap. - -**/ -BOOLEAN -CheckMemoryAttributeOverlap ( - IN PHYSICAL_ADDRESS Start, - IN PHYSICAL_ADDRESS End, - IN VARIABLE_MTRR *VariableMtrr - ) -{ - UINT32 Index; - - for (Index = 0; Index < 6; Index++) { - if ( - VariableMtrr[Index].Valid && - !( - (Start > (VariableMtrr[Index].BaseAddress + - VariableMtrr[Index].Length - 1) - ) || - (End < VariableMtrr[Index].BaseAddress) - ) - ) { - return TRUE; - } - } - - return FALSE; -} - - -/** - Marks a variable MTRR as non-valid. - - @param Index The index of the array VariableMtrr to be invalidated - @param VariableMtrr The array to shadow variable MTRRs content - @param UsedMtrr The number of MTRRs which has already been used - -**/ -VOID -InvalidateShadowMtrr ( - IN UINTN Index, - IN VARIABLE_MTRR *VariableMtrr, - OUT UINT32 *UsedMtrr - ) -{ - VariableMtrr[Index].Valid = FALSE; - *UsedMtrr = *UsedMtrr - 1; -} - - -/** - Combine memory attributes. - - If overlap exists between given memory range and MTRRs, try to combine them. - - @param Attributes The memory type to set. - @param Base The base address of memory range. - @param Length The length of memory range. - @param VariableMtrr The array to shadow variable MTRRs content - @param UsedMtrr The number of MTRRs which has already been used - @param OverwriteExistingMtrr Returns whether an existing MTRR was used - - @retval EFI_SUCCESS Memory region successfully combined. - @retval EFI_ACCESS_DENIED Memory region cannot be combined. - -**/ -RETURN_STATUS -CombineMemoryAttribute ( - IN UINT64 Attributes, - IN OUT UINT64 *Base, - IN OUT UINT64 *Length, - IN VARIABLE_MTRR *VariableMtrr, - IN OUT UINT32 *UsedMtrr, - OUT BOOLEAN *OverwriteExistingMtrr - ) -{ - UINT32 Index; - UINT64 CombineStart; - UINT64 CombineEnd; - UINT64 MtrrEnd; - UINT64 EndAddress; - UINT32 FirmwareVariableMtrrCount; - BOOLEAN CoveredByExistingMtrr; - - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); - - *OverwriteExistingMtrr = FALSE; - CoveredByExistingMtrr = FALSE; - EndAddress = *Base +*Length - 1; - - for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) { - - MtrrEnd = VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length - 1; - if ( - !VariableMtrr[Index].Valid || - ( - *Base > (MtrrEnd) || - (EndAddress < VariableMtrr[Index].BaseAddress) - ) - ) { - continue; - } - - // - // Combine same attribute MTRR range - // - if (Attributes == VariableMtrr[Index].Type) { - // - // if the Mtrr range contain the request range, set a flag, then continue to - // invalidate any MTRR of the same request range with higher priority cache type. - // - if (VariableMtrr[Index].BaseAddress <= *Base && MtrrEnd >= EndAddress) { - CoveredByExistingMtrr = TRUE; - continue; - } - // - // invalid this MTRR, and program the combine range - // - CombineStart = - (*Base) < VariableMtrr[Index].BaseAddress ? - (*Base) : - VariableMtrr[Index].BaseAddress; - CombineEnd = EndAddress > MtrrEnd ? EndAddress : MtrrEnd; - - // - // Record the MTRR usage status in VariableMtrr array. - // - InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr); - *Base = CombineStart; - *Length = CombineEnd - CombineStart + 1; - EndAddress = CombineEnd; - *OverwriteExistingMtrr = TRUE; - continue; - } else { - // - // The cache type is different, but the range is convered by one MTRR - // - if (VariableMtrr[Index].BaseAddress == *Base && MtrrEnd == EndAddress) { - InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr); - continue; - } - - } - - if ((Attributes== MTRR_CACHE_WRITE_THROUGH && - VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK) || - (Attributes == MTRR_CACHE_WRITE_BACK && - VariableMtrr[Index].Type == MTRR_CACHE_WRITE_THROUGH) || - (Attributes == MTRR_CACHE_UNCACHEABLE) || - (VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE) - ) { - *OverwriteExistingMtrr = TRUE; - continue; - } - // - // Other type memory overlap is invalid - // - return RETURN_ACCESS_DENIED; - } - - if (CoveredByExistingMtrr) { - *Length = 0; - } - - return RETURN_SUCCESS; -} - - -/** - Calculate the maximum value which is a power of 2, but less the MemoryLength. - - @param MemoryLength The number to pass in. - @return The maximum value which is align to power of 2 and less the MemoryLength - -**/ -UINT64 -Power2MaxMemory ( - IN UINT64 MemoryLength - ) -{ - UINT64 Result; - - if (RShiftU64 (MemoryLength, 32) != 0) { - Result = LShiftU64 ( - (UINT64) GetPowerOfTwo32 ( - (UINT32) RShiftU64 (MemoryLength, 32) - ), - 32 - ); - } else { - Result = (UINT64) GetPowerOfTwo32 ((UINT32) MemoryLength); - } - - return Result; -} - - -/** - Determine the MTRR numbers used to program a memory range. - - This function first checks the alignment of the base address. If the alignment of the base address <= Length, - cover the memory range (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and Length -= alignment. - Repeat the step until alignment > Length. - - Then this function determines which direction of programming the variable MTRRs for the remaining length - will use fewer MTRRs. - - @param BaseAddress Length of Memory to program MTRR - @param Length Length of Memory to program MTRR - @param MtrrNumber Pointer to the number of necessary MTRRs - - @retval TRUE Positive direction is better. - FALSE Negtive direction is better. - -**/ -BOOLEAN -GetMtrrNumberAndDirection ( - IN UINT64 BaseAddress, - IN UINT64 Length, - IN UINTN *MtrrNumber - ) -{ - UINT64 TempQword; - UINT64 Alignment; - UINT32 Positive; - UINT32 Subtractive; - - *MtrrNumber = 0; - - if (BaseAddress != 0) { - do { - // - // Calculate the alignment of the base address. - // - Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress)); - - if (Alignment > Length) { - break; - } - - (*MtrrNumber)++; - BaseAddress += Alignment; - Length -= Alignment; - } while (TRUE); - - if (Length == 0) { - return TRUE; - } - } - - TempQword = Length; - Positive = 0; - Subtractive = 0; - - do { - TempQword -= Power2MaxMemory (TempQword); - Positive++; - } while (TempQword != 0); - - TempQword = Power2MaxMemory (LShiftU64 (Length, 1)) - Length; - Subtractive++; - do { - TempQword -= Power2MaxMemory (TempQword); - Subtractive++; - } while (TempQword != 0); - - if (Positive <= Subtractive) { - *MtrrNumber += Positive; - return TRUE; - } else { - *MtrrNumber += Subtractive; - return FALSE; - } -} - -/** - Invalid variable MTRRs according to the value in the shadow array. - - This function programs MTRRs according to the values specified - in the shadow array. - - @param VariableMtrr The array to shadow variable MTRRs content - -**/ -VOID -InvalidateMtrr ( - IN VARIABLE_MTRR *VariableMtrr - ) -{ - UINTN Index; - UINTN Cr4; - UINTN VariableMtrrCount; - - Cr4 = PreMtrrChange (); - Index = 0; - VariableMtrrCount = GetVariableMtrrCount (); - while (Index < VariableMtrrCount) { - if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) { - AsmWriteMsr64 (VariableMtrr[Index].Msr, 0); - AsmWriteMsr64 (VariableMtrr[Index].Msr + 1, 0); - VariableMtrr[Index].Used = FALSE; - } - Index ++; - } - PostMtrrChange (Cr4); -} - - -/** - Programs variable MTRRs - - This function programs variable MTRRs - - @param MtrrNumber Index of MTRR to program. - @param BaseAddress Base address of memory region. - @param Length Length of memory region. - @param MemoryCacheType Memory type to set. - @param MtrrValidAddressMask The valid address mask for MTRR - -**/ -VOID -ProgramVariableMtrr ( - IN UINTN MtrrNumber, - IN PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 MemoryCacheType, - IN UINT64 MtrrValidAddressMask - ) -{ - UINT64 TempQword; - UINTN Cr4; - - Cr4 = PreMtrrChange (); - - // - // MTRR Physical Base - // - TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType; - AsmWriteMsr64 ((UINT32) MtrrNumber, TempQword); - - // - // MTRR Physical Mask - // - TempQword = ~(Length - 1); - AsmWriteMsr64 ( - (UINT32) (MtrrNumber + 1), - (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED - ); - - PostMtrrChange (Cr4); -} - - -/** - Convert the Memory attibute value to MTRR_MEMORY_CACHE_TYPE. - - @param MtrrType MTRR memory type - - @return The enum item in MTRR_MEMORY_CACHE_TYPE - -**/ -MTRR_MEMORY_CACHE_TYPE -GetMemoryCacheTypeFromMtrrType ( - IN UINT64 MtrrType - ) -{ - switch (MtrrType) { - case MTRR_CACHE_UNCACHEABLE: - return CacheUncacheable; - case MTRR_CACHE_WRITE_COMBINING: - return CacheWriteCombining; - case MTRR_CACHE_WRITE_THROUGH: - return CacheWriteThrough; - case MTRR_CACHE_WRITE_PROTECTED: - return CacheWriteProtected; - case MTRR_CACHE_WRITE_BACK: - return CacheWriteBack; - default: - // - // MtrrType is MTRR_CACHE_INVALID_TYPE, that means - // no mtrr covers the range - // - return CacheUncacheable; - } -} - -/** - Initializes the valid bits mask and valid address mask for MTRRs. - - This function initializes the valid bits mask and valid address mask for MTRRs. - - @param MtrrValidBitsMask The mask for the valid bit of the MTRR - @param MtrrValidAddressMask The valid address mask for the MTRR - -**/ -VOID -MtrrLibInitializeMtrrMask ( - OUT UINT64 *MtrrValidBitsMask, - OUT UINT64 *MtrrValidAddressMask - ) -{ - UINT32 RegEax; - UINT8 PhysicalAddressBits; - - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - - if (RegEax >= 0x80000008) { - AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - - PhysicalAddressBits = (UINT8) RegEax; - - *MtrrValidBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1; - *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL; - } else { - *MtrrValidBitsMask = MTRR_LIB_CACHE_VALID_ADDRESS; - *MtrrValidAddressMask = 0xFFFFFFFF; - } -} - - -/** - Determing the real attribute of a memory range. - - This function is to arbitrate the real attribute of the memory when - there are 2 MTRR covers the same memory range. For further details, - please refer the IA32 Software Developer's Manual, Volume 3, - Section 10.11.4.1. - - @param MtrrType1 the first kind of Memory type - @param MtrrType2 the second kind of memory type - -**/ -UINT64 -MtrrPrecedence ( - UINT64 MtrrType1, - UINT64 MtrrType2 - ) -{ - UINT64 MtrrType; - - MtrrType = MTRR_CACHE_INVALID_TYPE; - switch (MtrrType1) { - case MTRR_CACHE_UNCACHEABLE: - MtrrType = MTRR_CACHE_UNCACHEABLE; - break; - case MTRR_CACHE_WRITE_COMBINING: - if ( - MtrrType2==MTRR_CACHE_WRITE_COMBINING || - MtrrType2==MTRR_CACHE_UNCACHEABLE - ) { - MtrrType = MtrrType2; - } - break; - case MTRR_CACHE_WRITE_THROUGH: - if ( - MtrrType2==MTRR_CACHE_WRITE_THROUGH || - MtrrType2==MTRR_CACHE_WRITE_BACK - ) { - MtrrType = MTRR_CACHE_WRITE_THROUGH; - } else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) { - MtrrType = MTRR_CACHE_UNCACHEABLE; - } - break; - case MTRR_CACHE_WRITE_PROTECTED: - if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED || - MtrrType2 == MTRR_CACHE_UNCACHEABLE) { - MtrrType = MtrrType2; - } - break; - case MTRR_CACHE_WRITE_BACK: - if ( - MtrrType2== MTRR_CACHE_UNCACHEABLE || - MtrrType2==MTRR_CACHE_WRITE_THROUGH || - MtrrType2== MTRR_CACHE_WRITE_BACK - ) { - MtrrType = MtrrType2; - } - break; - case MTRR_CACHE_INVALID_TYPE: - MtrrType = MtrrType2; - break; - default: - break; - } - - if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) { - MtrrType = MtrrType1; - } - return MtrrType; -} - - -/** - This function attempts to set the attributes for a memory range. - - @param BaseAddress The physical address that is the start - address of a memory region. - @param Length The size in bytes of the memory region. - @param Attributes The bit mask of attributes to set for the - memory region. - - @retval RETURN_SUCCESS The attributes were set for the memory - region. - @retval RETURN_INVALID_PARAMETER Length is zero. - @retval RETURN_UNSUPPORTED The processor does not support one or - more bytes of the memory resource range - specified by BaseAddress and Length. - @retval RETURN_UNSUPPORTED The bit mask of attributes is not support - for the memory resource range specified - by BaseAddress and Length. - @retval RETURN_ACCESS_DENIED The attributes for the memory resource - range specified by BaseAddress and Length - cannot be modified. - @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to - modify the attributes of the memory - resource range. - -**/ -RETURN_STATUS -EFIAPI -MtrrSetMemoryAttribute ( - IN PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN MTRR_MEMORY_CACHE_TYPE Attribute - ) -{ - UINT64 TempQword; - RETURN_STATUS Status; - UINT64 MemoryType; - UINT64 Alignment; - BOOLEAN OverLap; - BOOLEAN Positive; - UINT32 MsrNum; - UINTN MtrrNumber; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT32 UsedMtrr; - UINT64 MtrrValidBitsMask; - UINT64 MtrrValidAddressMask; - UINTN Cr4; - BOOLEAN OverwriteExistingMtrr; - UINT32 FirmwareVariableMtrrCount; - UINT32 VariableMtrrEnd; - - DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length)); - - if (!IsMtrrSupported ()) { - Status = RETURN_UNSUPPORTED; - goto Done; - } - - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); - VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1; - - MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); - - TempQword = 0; - MemoryType = (UINT64)Attribute; - OverwriteExistingMtrr = FALSE; - - // - // Check for an invalid parameter - // - if (Length == 0) { - Status = RETURN_INVALID_PARAMETER; - goto Done; - } - - if ( - (BaseAddress & ~MtrrValidAddressMask) != 0 || - (Length & ~MtrrValidAddressMask) != 0 - ) { - Status = RETURN_UNSUPPORTED; - goto Done; - } - - // - // Check if Fixed MTRR - // - Status = RETURN_SUCCESS; - while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) { - Cr4 = PreMtrrChange (); - Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length); - PostMtrrChange (Cr4); - if (RETURN_ERROR (Status)) { - goto Done; - } - } - - if (Length == 0) { - // - // A Length of 0 can only make sense for fixed MTTR ranges. - // Since we just handled the fixed MTRRs, we can skip the - // variable MTRR section. - // - goto Done; - } - - // - // Since memory ranges below 1MB will be overridden by the fixed MTRRs, - // we can set the base to 0 to save variable MTRRs. - // - if (BaseAddress == BASE_1MB) { - BaseAddress = 0; - Length += SIZE_1MB; - } - - // - // Check for overlap - // - UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, MtrrValidAddressMask, VariableMtrr); - OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 1, VariableMtrr); - if (OverLap) { - Status = CombineMemoryAttribute (MemoryType, &BaseAddress, &Length, VariableMtrr, &UsedMtrr, &OverwriteExistingMtrr); - if (RETURN_ERROR (Status)) { - goto Done; - } - - if (Length == 0) { - // - // Combined successfully, invalidate the now-unused MTRRs - // - InvalidateMtrr(VariableMtrr); - Status = RETURN_SUCCESS; - goto Done; - } - } - - // - // The memory type is the same with the type specified by - // MTRR_LIB_IA32_MTRR_DEF_TYPE. - // - if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) { - // - // Invalidate the now-unused MTRRs - // - InvalidateMtrr(VariableMtrr); - goto Done; - } - - Positive = GetMtrrNumberAndDirection (BaseAddress, Length, &MtrrNumber); - - if ((UsedMtrr + MtrrNumber) > FirmwareVariableMtrrCount) { - Status = RETURN_OUT_OF_RESOURCES; - goto Done; - } - - // - // Invalidate the now-unused MTRRs - // - InvalidateMtrr(VariableMtrr); - - // - // Find first unused MTRR - // - for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE; - MsrNum < VariableMtrrEnd; - MsrNum += 2 - ) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - if (BaseAddress != 0) { - do { - // - // Calculate the alignment of the base address. - // - Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress)); - - if (Alignment > Length) { - break; - } - - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Alignment, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress += Alignment; - Length -= Alignment; - } while (TRUE); - - if (Length == 0) { - goto Done; - } - } - - TempQword = Length; - - if (!Positive) { - Length = Power2MaxMemory (LShiftU64 (TempQword, 1)); - - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress += Length; - TempQword = Length - TempQword; - MemoryType = MTRR_CACHE_UNCACHEABLE; - } - - do { - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - Length = Power2MaxMemory (TempQword); - if (!Positive) { - BaseAddress -= Length; - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - - if (Positive) { - BaseAddress += Length; - } - TempQword -= Length; - - } while (TempQword > 0); - -Done: - DEBUG((DEBUG_CACHE, " Status = %r\n", Status)); - if (!RETURN_ERROR (Status)) { - MtrrDebugPrintAllMtrrs (); - } - - return Status; -} - - -/** - This function will get the memory cache type of the specific address. - - This function is mainly for debug purpose. - - @param Address The specific address - - @return Memory cache type of the sepcific address - -**/ -MTRR_MEMORY_CACHE_TYPE -EFIAPI -MtrrGetMemoryAttribute ( - IN PHYSICAL_ADDRESS Address - ) -{ - UINT64 TempQword; - UINTN Index; - UINTN SubIndex; - UINT64 MtrrType; - UINT64 TempMtrrType; - MTRR_MEMORY_CACHE_TYPE CacheType; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT64 MtrrValidBitsMask; - UINT64 MtrrValidAddressMask; - UINTN VariableMtrrCount; - - if (!IsMtrrSupported ()) { - return CacheUncacheable; - } - - // - // Check if MTRR is enabled, if not, return UC as attribute - // - TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); - MtrrType = MTRR_CACHE_INVALID_TYPE; - - if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - return CacheUncacheable; - } - - // - // If address is less than 1M, then try to go through the fixed MTRR - // - if (Address < BASE_1MB) { - if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) { - // - // Go through the fixed MTRR - // - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress && - Address < ( - mMtrrLibFixedMtrrTable[Index].BaseAddress + - (mMtrrLibFixedMtrrTable[Index].Length * 8) - ) - ) { - SubIndex = - ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / - mMtrrLibFixedMtrrTable[Index].Length; - TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); - MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF; - return GetMemoryCacheTypeFromMtrrType (MtrrType); - } - } - } - } - MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); - MtrrGetMemoryAttributeInVariableMtrr( - MtrrValidBitsMask, - MtrrValidAddressMask, - VariableMtrr - ); - - // - // Go through the variable MTRR - // - VariableMtrrCount = GetVariableMtrrCount (); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - - for (Index = 0; Index < VariableMtrrCount; Index++) { - if (VariableMtrr[Index].Valid) { - if (Address >= VariableMtrr[Index].BaseAddress && - Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) { - TempMtrrType = VariableMtrr[Index].Type; - MtrrType = MtrrPrecedence (MtrrType, TempMtrrType); - } - } - } - CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType); - - return CacheType; -} - - -/** - This function will get the raw value in variable MTRRs - - @param VariableSettings A buffer to hold variable MTRRs content. - - @return The VariableSettings input pointer - -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrGetVariableMtrr ( - OUT MTRR_VARIABLE_SETTINGS *VariableSettings - ) -{ - UINT32 Index; - UINT32 VariableMtrrCount; - - if (!IsMtrrSupported ()) { - return VariableSettings; - } - - VariableMtrrCount = GetVariableMtrrCount (); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - - for (Index = 0; Index < VariableMtrrCount; Index++) { - VariableSettings->Mtrr[Index].Base = - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1)); - VariableSettings->Mtrr[Index].Mask = - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1); - } - - return VariableSettings; -} - - -/** - Worker function setting variable MTRRs - - @param VariableSettings A buffer to hold variable MTRRs content. - -**/ -VOID -MtrrSetVariableMtrrWorker ( - IN MTRR_VARIABLE_SETTINGS *VariableSettings - ) -{ - UINT32 Index; - UINT32 VariableMtrrCount; - - VariableMtrrCount = GetVariableMtrrCount (); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - - for (Index = 0; Index < VariableMtrrCount; Index++) { - AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1), - VariableSettings->Mtrr[Index].Base - ); - AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1, - VariableSettings->Mtrr[Index].Mask - ); - } -} - - -/** - This function sets variable MTRRs - - @param VariableSettings A buffer to hold variable MTRRs content. - - @return The pointer of VariableSettings - -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrSetVariableMtrr ( - IN MTRR_VARIABLE_SETTINGS *VariableSettings - ) -{ - UINTN Cr4; - - if (!IsMtrrSupported ()) { - return VariableSettings; - } - - Cr4 = PreMtrrChange (); - MtrrSetVariableMtrrWorker (VariableSettings); - PostMtrrChange (Cr4); - return VariableSettings; -} - - -/** - This function gets the content in fixed MTRRs - - @param FixedSettings A buffer to hold fixed Mtrrs content. - - @retval The pointer of FixedSettings - -**/ -MTRR_FIXED_SETTINGS* -EFIAPI -MtrrGetFixedMtrr ( - OUT MTRR_FIXED_SETTINGS *FixedSettings - ) -{ - UINT32 Index; - - if (!IsMtrrSupported ()) { - return FixedSettings; - } - - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - FixedSettings->Mtrr[Index] = - AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); - }; - - return FixedSettings; -} - -/** - Worker function setting fixed MTRRs - - @param FixedSettings A buffer to hold fixed Mtrrs content. - -**/ -VOID -MtrrSetFixedMtrrWorker ( - IN MTRR_FIXED_SETTINGS *FixedSettings - ) -{ - UINT32 Index; - - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - AsmWriteMsr64 ( - mMtrrLibFixedMtrrTable[Index].Msr, - FixedSettings->Mtrr[Index] - ); - } -} - - -/** - This function sets fixed MTRRs - - @param FixedSettings A buffer to hold fixed Mtrrs content. - - @retval The pointer of FixedSettings - -**/ -MTRR_FIXED_SETTINGS* -EFIAPI -MtrrSetFixedMtrr ( - IN MTRR_FIXED_SETTINGS *FixedSettings - ) -{ - UINTN Cr4; - - if (!IsMtrrSupported ()) { - return FixedSettings; - } - - Cr4 = PreMtrrChange (); - MtrrSetFixedMtrrWorker (FixedSettings); - PostMtrrChange (Cr4); - - return FixedSettings; -} - - -/** - This function gets the content in all MTRRs (variable and fixed) - - @param MtrrSetting A buffer to hold all Mtrrs content. - - @retval the pointer of MtrrSetting - -**/ -MTRR_SETTINGS * -EFIAPI -MtrrGetAllMtrrs ( - OUT MTRR_SETTINGS *MtrrSetting - ) -{ - if (!IsMtrrSupported ()) { - return MtrrSetting; - } - - // - // Get fixed MTRRs - // - MtrrGetFixedMtrr (&MtrrSetting->Fixed); - - // - // Get variable MTRRs - // - MtrrGetVariableMtrr (&MtrrSetting->Variables); - - // - // Get MTRR_DEF_TYPE value - // - MtrrSetting->MtrrDefType = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); - - return MtrrSetting; -} - - -/** - This function sets all MTRRs (variable and fixed) - - @param MtrrSetting A buffer holding all MTRRs content. - - @retval The pointer of MtrrSetting - -**/ -MTRR_SETTINGS * -EFIAPI -MtrrSetAllMtrrs ( - IN MTRR_SETTINGS *MtrrSetting - ) -{ - UINTN Cr4; - - if (!IsMtrrSupported ()) { - return MtrrSetting; - } - - Cr4 = PreMtrrChange (); - - // - // Set fixed MTRRs - // - MtrrSetFixedMtrrWorker (&MtrrSetting->Fixed); - - // - // Set variable MTRRs - // - MtrrSetVariableMtrrWorker (&MtrrSetting->Variables); - - // - // Set MTRR_DEF_TYPE value - // - AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); - - PostMtrrChange (Cr4); - - return MtrrSetting; -} - -/** - This function prints all MTRRs for debugging. -**/ -VOID -EFIAPI -MtrrDebugPrintAllMtrrs ( - VOID - ) -{ - DEBUG_CODE ( - MTRR_SETTINGS MtrrSettings; - UINTN Index; - UINTN Index1; - UINTN VariableMtrrCount; - UINT64 Base; - UINT64 Limit; - UINT64 MtrrBase; - UINT64 MtrrLimit; - UINT64 RangeBase; - UINT64 RangeLimit; - UINT64 NoRangeBase; - UINT64 NoRangeLimit; - UINT32 RegEax; - UINTN MemoryType; - UINTN PreviousMemoryType; - BOOLEAN Found; - - if (!IsMtrrSupported ()) { - return; - } - - DEBUG((DEBUG_CACHE, "MTRR Settings\n")); - DEBUG((DEBUG_CACHE, "=============\n")); - - MtrrGetAllMtrrs (&MtrrSettings); - DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType)); - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index])); - } - - VariableMtrrCount = GetVariableMtrrCount (); - for (Index = 0; Index < VariableMtrrCount; Index++) { - DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n", - Index, - MtrrSettings.Variables.Mtrr[Index].Base, - MtrrSettings.Variables.Mtrr[Index].Mask - )); - } - DEBUG((DEBUG_CACHE, "\n")); - DEBUG((DEBUG_CACHE, "MTRR Ranges\n")); - DEBUG((DEBUG_CACHE, "====================================\n")); - - Base = 0; - PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - Base = mMtrrLibFixedMtrrTable[Index].BaseAddress; - for (Index1 = 0; Index1 < 8; Index1++) { - MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff); - if (MemoryType > CacheWriteBack) { - MemoryType = MTRR_CACHE_INVALID_TYPE; - } - if (MemoryType != PreviousMemoryType) { - if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - } - PreviousMemoryType = MemoryType; - DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); - } - Base += mMtrrLibFixedMtrrTable[Index].Length; - } - } - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - - VariableMtrrCount = GetVariableMtrrCount (); - - Base = BASE_1MB; - PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; - do { - MemoryType = MtrrGetMemoryAttribute (Base); - if (MemoryType > CacheWriteBack) { - MemoryType = MTRR_CACHE_INVALID_TYPE; - } - - if (MemoryType != PreviousMemoryType) { - if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - } - PreviousMemoryType = MemoryType; - DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); - } - - RangeBase = BASE_1MB; - NoRangeBase = BASE_1MB; - Limit = BIT36 - 1; - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000008) { - AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - Limit = LShiftU64 (1, RegEax & 0xff) - 1; - } - RangeLimit = Limit; - NoRangeLimit = Limit; - - for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) { - if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) { - // - // If mask is not valid, then do not display range - // - continue; - } - MtrrBase = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1))); - MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit); - - if (Base >= MtrrBase && Base < MtrrLimit) { - Found = TRUE; - } - - if (Base >= MtrrBase && MtrrBase > RangeBase) { - RangeBase = MtrrBase; - } - if (Base > MtrrLimit && MtrrLimit > RangeBase) { - RangeBase = MtrrLimit + 1; - } - if (Base < MtrrBase && MtrrBase < RangeLimit) { - RangeLimit = MtrrBase - 1; - } - if (Base < MtrrLimit && MtrrLimit <= RangeLimit) { - RangeLimit = MtrrLimit; - } - - if (Base > MtrrLimit && NoRangeBase < MtrrLimit) { - NoRangeBase = MtrrLimit + 1; - } - if (Base < MtrrBase && NoRangeLimit > MtrrBase) { - NoRangeLimit = MtrrBase - 1; - } - } - - if (Found) { - Base = RangeLimit + 1; - } else { - Base = NoRangeLimit + 1; - } - } while (Found); - DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1)); - ); -} - -/** - Checks if MTRR is supported. - - @retval TRUE MTRR is supported. - @retval FALSE MTRR is not supported. - -**/ -BOOLEAN -EFIAPI -IsMtrrSupported ( - VOID - ) -{ - UINT32 RegEdx; - UINT64 MtrrCap; - - // - // Check CPUID(1).EDX[12] for MTRR capability - // - AsmCpuid (1, NULL, NULL, NULL, &RegEdx); - if (BitFieldRead32 (RegEdx, 12, 12) == 0) { - return FALSE; - } - - // - // Check IA32_MTRRCAP.[0..7] for number of variable MTRRs and IA32_MTRRCAP[8] for - // fixed MTRRs existence. If number of variable MTRRs is zero, or fixed MTRRs do not - // exist, return false. - // - MtrrCap = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP); - if ((BitFieldRead64 (MtrrCap, 0, 7) == 0) || (BitFieldRead64 (MtrrCap, 8, 8) == 0)) { - return FALSE; - } - - return TRUE; -} diff --git a/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf b/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf deleted file mode 100644 index ef4a59651..000000000 --- a/CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf +++ /dev/null @@ -1,41 +0,0 @@ -## @file -# MTRR library provides API for MTRR operation -# -# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MtrrLib - FILE_GUID = 6826b408-f4f3-47ee-917f-af7047f9d937 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = MtrrLib - - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - MtrrLib.c - -[Packages] - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseMemoryLib - BaseLib - CpuLib - diff --git a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c b/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c deleted file mode 100644 index 714b99eec..000000000 --- a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c +++ /dev/null @@ -1,216 +0,0 @@ -/** @file - Timer Library functions built upon ITC on IPF. - - Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include - - -/** - Performs a delay measured as number of ticks. - - An internal function to perform a delay measured as number of ticks. It's - invoked by MicroSecondDelay() and NanoSecondDelay(). - - @param Delay The number of ticks to delay. - -**/ -VOID -EFIAPI -InternalIpfDelay ( - IN INT64 Delay - ) -{ - INT64 Ticks; - - // - // The target timer count is calculated here - // - Ticks = (INT64)AsmReadItc () + Delay; - - // - // Wait until time out - // Delay > 2^63 could not be handled by this function - // Timer wrap-arounds are handled correctly by this function - // - while (Ticks - (INT64)AsmReadItc() >= 0); -} - -/** - Stalls the CPU for at least the given number of microseconds. - - Stalls the CPU for the number of microseconds specified by MicroSeconds. - - @param MicroSeconds The minimum number of microseconds to delay. - - @return The value of MicroSeconds inputted. - -**/ -UINTN -EFIAPI -MicroSecondDelay ( - IN UINTN MicroSeconds - ) -{ - InternalIpfDelay ( - GetPerformanceCounterProperties (NULL, NULL) * - MicroSeconds / - 1000000 - ); - return MicroSeconds; -} - -/** - Stalls the CPU for at least the given number of nanoseconds. - - Stalls the CPU for the number of nanoseconds specified by NanoSeconds. - - @param NanoSeconds The minimum number of nanoseconds to delay. - - @return The value of NanoSeconds inputted. - -**/ -UINTN -EFIAPI -NanoSecondDelay ( - IN UINTN NanoSeconds - ) -{ - InternalIpfDelay ( - GetPerformanceCounterProperties (NULL, NULL) * - NanoSeconds / - 1000000000 - ); - return NanoSeconds; -} - -/** - Retrieves the current value of a 64-bit free running performance counter. - - The counter can either count up by 1 or count down by 1. If the physical - performance counter counts by a larger increment, then the counter values - must be translated. The properties of the counter can be retrieved from - GetPerformanceCounterProperties(). - - @return The current value of the free running performance counter. - -**/ -UINT64 -EFIAPI -GetPerformanceCounter ( - VOID - ) -{ - return AsmReadItc (); -} - -/** - Retrieves the 64-bit frequency in Hz and the range of performance counter - values. - - If StartValue is not NULL, then the value that the performance counter starts - with immediately after is it rolls over is returned in StartValue. If - EndValue is not NULL, then the value that the performance counter end with - immediately before it rolls over is returned in EndValue. The 64-bit - frequency of the performance counter in Hz is always returned. If StartValue - is less than EndValue, then the performance counter counts up. If StartValue - is greater than EndValue, then the performance counter counts down. For - example, a 64-bit free running counter that counts up would have a StartValue - of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter - that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0. - - @param StartValue The value the performance counter starts with when it - rolls over. - @param EndValue The value that the performance counter ends with before - it rolls over. - - @return The frequency in Hz. - -**/ -UINT64 -EFIAPI -GetPerformanceCounterProperties ( - OUT UINT64 *StartValue, OPTIONAL - OUT UINT64 *EndValue OPTIONAL - ) -{ - PAL_CALL_RETURN PalRet; - UINT64 BaseFrequence; - - if (StartValue != NULL) { - *StartValue = 0; - } - - if (EndValue != NULL) { - *EndValue = (UINT64)(-1); - } - - PalRet = PalCall (PAL_FREQ_BASE, 0, 0, 0); - if (PalRet.Status != 0) { - return 1000000; - } - BaseFrequence = PalRet.r9; - - PalRet = PalCall (PAL_FREQ_RATIOS, 0, 0, 0); - if (PalRet.Status != 0) { - return 1000000; - } - - return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11; -} - -/** - Converts elapsed ticks of performance counter to time in nanoseconds. - - This function converts the elapsed ticks of running performance counter to - time value in unit of nanoseconds. - - @param Ticks The number of elapsed ticks of running performance counter. - - @return The elapsed time in nanoseconds. - -**/ -UINT64 -EFIAPI -GetTimeInNanoSecond ( - IN UINT64 Ticks - ) -{ - UINT64 Frequency; - UINT64 NanoSeconds; - UINT64 Remainder; - INTN Shift; - - Frequency = GetPerformanceCounterProperties (NULL, NULL); - - // - // Ticks - // Time = --------- x 1,000,000,000 - // Frequency - // - NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); - - // - // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. - // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, - // i.e. highest bit set in Remainder should <= 33. - // - Shift = MAX (0, HighBitSet64 (Remainder) - 33); - Remainder = RShiftU64 (Remainder, (UINTN) Shift); - Frequency = RShiftU64 (Frequency, (UINTN) Shift); - NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); - - return NanoSeconds; -} diff --git a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf b/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf deleted file mode 100644 index 91566c647..000000000 --- a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf +++ /dev/null @@ -1,63 +0,0 @@ -## @file -# Instance of Timer Library only using CPU resources. -# -# Timer Library that only uses CPU resources to provide calibrated delays -# on IA-32, x64, and IPF. -# Note: Because CPU Local APIC and ITC could be programmed by OS, it cannot be -# used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM -# drivers and runtime drivers. -# -# This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in -# that it uses the local APIC library so that it supports x2APIC mode. -# -# Copyright (c) 2010, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SecPeiDxeTimerLibUefiCpu - FILE_GUID = 4FFF2014-2086-4ee6-9B58-886D1967861C - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = TimerLib|BASE DXE_CORE DXE_DRIVER DXE_SAL_DRIVER PEIM PEI_CORE SEC UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = IA32 X64 IPF -# - -[Sources.Ia32, Sources.X64] - X86TimerLib.c - -[Sources.IPF] - IpfTimerLib.c - - -[Packages] - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - -[LibraryClasses.IA32, LibraryClasses.X64] - PcdLib - DebugLib - LocalApicLib - -[LibraryClasses.IPF] - PalLib - - -[Pcd.IA32, Pcd.X64] - gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES - diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw b/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw deleted file mode 100644 index ec6bcfd48..000000000 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw and /dev/null differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw b/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw deleted file mode 100644 index 02cb66c84..000000000 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw and /dev/null differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm b/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm deleted file mode 100644 index 883cef03e..000000000 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm +++ /dev/null @@ -1,26 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Debug disabled -; -; Copyright (c) 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -; -;------------------------------------------------------------------------------ - -BITS 16 - -%macro debugInitialize 0 - ; - ; No initialization is required - ; -%endmacro - -%macro debugShowPostCode 1 -%endmacro - diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py b/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py deleted file mode 100644 index 7833f4b76..000000000 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py +++ /dev/null @@ -1,110 +0,0 @@ -## @file -# Apply fixup to VTF binary image for FFS Raw section -# -# Copyright (c) 2008, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# - -import sys - -filename = sys.argv[1] - -if filename.lower().find('ia32') >= 0: - d = open(sys.argv[1], 'rb').read() - c = ((len(d) + 4 + 7) & ~7) - 4 - if c > len(d): - c -= len(d) - f = open(sys.argv[1], 'wb') - f.write('\x90' * c) - f.write(d) - f.close() -else: - from struct import pack - - PAGE_PRESENT = 0x01 - PAGE_READ_WRITE = 0x02 - PAGE_USER_SUPERVISOR = 0x04 - PAGE_WRITE_THROUGH = 0x08 - PAGE_CACHE_DISABLE = 0x010 - PAGE_ACCESSED = 0x020 - PAGE_DIRTY = 0x040 - PAGE_PAT = 0x080 - PAGE_GLOBAL = 0x0100 - PAGE_2M_MBO = 0x080 - PAGE_2M_PAT = 0x01000 - - def NopAlign4k(s): - c = ((len(s) + 0xfff) & ~0xfff) - len(s) - return ('\x90' * c) + s - - def PageDirectoryEntries4GbOf2MbPages(baseAddress): - - s = '' - for i in range(0x800): - i = ( - baseAddress + long(i << 21) + - PAGE_2M_MBO + - PAGE_CACHE_DISABLE + - PAGE_ACCESSED + - PAGE_DIRTY + - PAGE_READ_WRITE + - PAGE_PRESENT - ) - s += pack('Q', i) - return s - - def PageDirectoryPointerTable4GbOf2MbPages(pdeBase): - s = '' - for i in range(0x200): - i = ( - pdeBase + - (min(i, 3) << 12) + - PAGE_CACHE_DISABLE + - PAGE_ACCESSED + - PAGE_READ_WRITE + - PAGE_PRESENT - ) - s += pack('Q', i) - return s - - def PageMapLevel4Table4GbOf2MbPages(pdptBase): - s = '' - for i in range(0x200): - i = ( - pdptBase + - (min(i, 0) << 12) + - PAGE_CACHE_DISABLE + - PAGE_ACCESSED + - PAGE_READ_WRITE + - PAGE_PRESENT - ) - s += pack('Q', i) - return s - - def First4GbPageEntries(topAddress): - PDE = PageDirectoryEntries4GbOf2MbPages(0L) - pml4tBase = topAddress - 0x1000 - pdptBase = pml4tBase - 0x1000 - pdeBase = pdptBase - len(PDE) - PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase) - PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase) - return PDE + PDPT + PML4T - - def AlignAndAddPageTables(): - d = open(sys.argv[1], 'rb').read() - code = NopAlign4k(d) - topAddress = 0x100000000 - len(code) - d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code - f = open(sys.argv[1], 'wb') - f.write(d) - f.close() - - AlignAndAddPageTables() - diff --git a/CloverEFI/UefiCpuPkg/UefiCpuPkg.dec b/CloverEFI/UefiCpuPkg/UefiCpuPkg.dec deleted file mode 100644 index 31b7303e6..000000000 --- a/CloverEFI/UefiCpuPkg/UefiCpuPkg.dec +++ /dev/null @@ -1,46 +0,0 @@ -## @file UefiCpuPkg.dec -# -# This Package provides UEFI compatible CPU modules and libraries. -# -# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials are licensed and made available under -# the terms and conditions of the BSD License which accompanies this distribution. -# The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - DEC_SPECIFICATION = 0x00010005 - PACKAGE_NAME = UefiCpuPkg - PACKAGE_GUID = 2171df9b-0d39-45aa-ac37-2de190010d23 - PACKAGE_VERSION = 0.1 - -[Includes] - Include - -[LibraryClasses] - ## @libraryclass Defines some routines that are generic for IA32 family CPU - ## to be UEFI specification compliant. - ## - UefiCpuLib|Include/Library/UefiCpuLib.h - -[LibraryClasses.IA32, LibraryClasses.X64] - ## @libraryclass Provides functions to manage MTRR settings on IA32 and X64 CPUs. - ## - MtrrLib|Include/Library/MtrrLib.h - - ## @libraryclass Provides functions to manage the Local APIC on IA32 and X64 CPUs. - ## - LocalApicLib|Include/Library/LocalApicLib.h - -[Guids] - gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} - -[PcdsFixedAtBuild, PcdsPatchableInModule] - gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress|0xfee00000|UINT32|0x00000001 - diff --git a/CloverEFI/UefiCpuPkg/UefiCpuPkg.dsc b/CloverEFI/UefiCpuPkg/UefiCpuPkg.dsc deleted file mode 100644 index c4c4e3085..000000000 --- a/CloverEFI/UefiCpuPkg/UefiCpuPkg.dsc +++ /dev/null @@ -1,89 +0,0 @@ -## @file -# UefiCpuPkg Package -# -# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - PLATFORM_NAME = UefiCpu - PLATFORM_GUID = a1b7be22-78b3-4260-9569-8649e8c17d49 - PLATFORM_VERSION = 0.1 - DSC_SPECIFICATION = 0x00010005 - OUTPUT_DIRECTORY = Build/UefiCpu - SUPPORTED_ARCHITECTURES = IA32|IPF|X64 - BUILD_TARGETS = DEBUG|RELEASE - SKUID_IDENTIFIER = DEFAULT - -# -# External libraries to build package -# - -[LibraryClasses] - BaseLib|MdePkg/Library/BaseLib/BaseLib.inf - BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf - CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf - DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf - DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf - IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf - MtrrLib|CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf - PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf - UefiLib|MdePkg/Library/UefiLib/UefiLib.inf - UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf - UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf - DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf - PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf - PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf - DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf - LocalApicLib|CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf - ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf - -[LibraryClasses.common.PEIM] - MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf - HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf - -[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] - PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf - -[LibraryClasses.IPF.PEIM] - PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.inf - -[LibraryClasses.common.DXE_DRIVER] - MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf - -[LibraryClasses.common.DXE_SMM_DRIVER] - SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf - MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf - -# -# Drivers/Libraries within this package -# - -[Components] - CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.inf - CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf - -[Components.IA32, Components.X64] - CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.inf - CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf - CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf - CloverEFI/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf - CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf - CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf - CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf - diff --git a/CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf b/CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf deleted file mode 100644 index 1a38f518a..000000000 --- a/CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf +++ /dev/null @@ -1,79 +0,0 @@ -## @file -# S3 Resume Module: -# This module works with StandAloneBootScriptExecutor to S3 resume to OS. -# This module will excute the boot script saved during last boot and after that, -# control is passed to OS waking up handler. -# -# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials are -# licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = S3Resume2Pei - FILE_GUID = 89E549B0-7CFE-449d-9BA3-10D8B2312D71 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - ENTRY_POINT = PeimS3ResumeEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - S3Resume.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - PeiServicesTablePointerLib - PerformanceLib - HobLib - PeiServicesLib - PeimEntryPoint - TimerLib - BaseLib - DebugLib - PcdLib - IoLib - BaseMemoryLib - MemoryAllocationLib - DebugAgentLib - LocalApicLib - ReportStatusCodeLib - LockBoxLib - PrintLib - -[Guids] - gEfiBootScriptExecutorVariableGuid # SOMETIMES_CONSUMED - gEfiBootScriptExecutorContextGuid # SOMETIMES_CONSUMED - gPerformanceProtocolGuid # ALWAYS_CONSUMED L"PerfDataMemAddr" - gEfiAcpiVariableGuid # ALWAYS_CONSUMED Hob: GUID_EXTENSION - gEfiAcpiS3ContextGuid # ALWAYS_CONSUMED - -[Ppis] - gEfiPeiReadOnlyVariable2PpiGuid # PPI ALWAYS_CONSUMED - gEfiPeiS3Resume2PpiGuid # PPI ALWAYS_PRODUCED - gPeiSmmAccessPpiGuid # PPI ALWAYS_CONSUMED - gPeiPostScriptTablePpiGuid # PPI ALWAYS_PRODUCED - gEfiEndOfPeiSignalPpiGuid # PPI ALWAYS_PRODUCED - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode - gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport - -[Depex] - gEfiPeiReadOnlyVariable2PpiGuid diff --git a/CloverEFI/UefiCpuPkg/build.sh b/CloverEFI/UefiCpuPkg/build.sh deleted file mode 100644 index 0d479420e..000000000 --- a/CloverEFI/UefiCpuPkg/build.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-# Copyright (c) 2010, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# - -set -e -shopt -s nocasematch - - -# -# Setup workspace if it is not set -# -if [ -z "$WORKSPACE" ] -then - echo Initializing workspace - if [ ! -e `pwd`/edksetup.sh ] - then - cd .. - fi -# This version is for the tools in the BaseTools project. -# this assumes svn pulls have the same root dir -# export EDK_TOOLS_PATH=`pwd`/../BaseTools -# This version is for the tools source in edk2 - export EDK_TOOLS_PATH=`pwd`/BaseTools - echo $EDK_TOOLS_PATH - source edksetup.sh BaseTools -else - echo Building from: $WORKSPACE -fi - -# -# Pick a default tool type for a given OS -# -TARGET_TOOLS=MYTOOLS -NETWORK_SUPPORT= -case `uname` in - CYGWIN*) echo Cygwin not fully supported yet. ;; - Darwin*) - Major=$(uname -r | cut -f 1 -d '.') - if [[ $Major == 9 ]] - then - echo UnixPkg requires Snow Leopard or later OS - exit 1 - else - TARGET_TOOLS=XCODE32 - fi -# NETWORK_SUPPORT="-D NETWORK_SUPPORT" - ;; - Linux*) TARGET_TOOLS=ELFGCC ;; - -esac - -BUILD_ROOT_ARCH=$WORKSPACE/Build/Shell/DEBUG_"$TARGET_TOOLS"/IA32 - - -# -# Build the edk2 UnixPkg -# -echo $PATH -echo `which build` -#build -p $WORKSPACE/UnixPkg/UnixPkg.dsc -a IA32 -t $TARGET_TOOLS $NETWORK_SUPPORT -n 3 $1 $2 $3 $4 $5 $6 $7 $8 -build -p $WORKSPACE/CloverEFI/UefiCpuPkg/UefiCpuPkg.dsc -a IA32 -t $TARGET_TOOLS -n 3 $* -exit $? - diff --git a/CloverEFI/UefiCpuPkg/edk2.patch-idtgdt b/CloverEFI/UefiCpuPkg/edk2.patch-idtgdt deleted file mode 100644 index 34230487f..000000000 --- a/CloverEFI/UefiCpuPkg/edk2.patch-idtgdt +++ /dev/null @@ -1,283 +0,0 @@ -Index: UefiCpuPkg/CpuDxe/CpuDxe.inf -=================================================================== ---- UefiCpuPkg/CpuDxe/CpuDxe.inf (revision 9332) -+++ UefiCpuPkg/CpuDxe/CpuDxe.inf (working copy) -@@ -62,6 +62,9 @@ - [Protocols] - gEfiCpuArchProtocolGuid - -+[Guids] -+ gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID -+ - [Depex] - TRUE - -Index: UefiCpuPkg/CpuDxe/CpuGdt.c -=================================================================== ---- UefiCpuPkg/CpuDxe/CpuGdt.c (revision 9332) -+++ UefiCpuPkg/CpuDxe/CpuGdt.c (working copy) -@@ -67,6 +67,9 @@ - #error CPU type not supported for CPU GDT initialization! - #endif - -+VOID * Gdt; -+UINT32 GdtSize; -+ - // - // Global descriptor table (GDT) Template - // -@@ -161,6 +164,20 @@ - }, - }; - -+VOID EFIAPI -+LoadGdt(VOID* Gdt, UINT32 GdtSize) -+{ -+ IA32_DESCRIPTOR gdtPtr; -+ -+ // -+ // Write GDT register -+ // -+ gdtPtr.Base = (UINT32)(UINTN)Gdt; -+ gdtPtr.Limit = GdtSize - 1; -+ -+ AsmWriteGdtr (&gdtPtr); -+} -+ - /** - Initialize Global Descriptor Table - -@@ -169,27 +186,27 @@ - InitGlobalDescriptorTable ( - ) - { -- GDT_ENTRIES *gdt; -- IA32_DESCRIPTOR gdtPtr; -- - // - // Allocate Runtime Data for the GDT - // -- gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); -- ASSERT (gdt != NULL); -- gdt = ALIGN_POINTER (gdt, 8); -+ GdtSize = sizeof (GdtTemplate); -+#if 0 -+ Gdt = AllocateRuntimePool (GdtSize + 8); -+ ASSERT (Gdt != NULL); -+ Gdt = ALIGN_POINTER (Gdt, 8); -+#else -+ Gdt = (VOID*)(UINTN)HandyCpuPage; -+#endif - - // - // Initialize all GDT entries - // -- CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate)); -+ CopyMem (Gdt, &GdtTemplate, GdtSize); - - // - // Write GDT register - // -- gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; -- gdtPtr.Limit = sizeof (GdtTemplate) - 1; -- AsmWriteGdtr (&gdtPtr); -+ LoadGdt(Gdt, GdtSize); - - // - // Update selector (segment) registers base on new GDT -@@ -197,4 +214,3 @@ - SetCodeSelector ((UINT16)CPU_CODE_SEL); - SetDataSelectors ((UINT16)CPU_DATA_SEL); - } -- -Index: UefiCpuPkg/CpuDxe/CpuDxe.c -=================================================================== ---- UefiCpuPkg/CpuDxe/CpuDxe.c (revision 9332) -+++ UefiCpuPkg/CpuDxe/CpuDxe.c (working copy) -@@ -14,11 +14,14 @@ - - #include "CpuDxe.h" - -+EFI_EVENT mEfiVirtualNotifyEvent; -+EFI_PHYSICAL_ADDRESS HandyCpuPage; -+IA32_IDT_GATE_DESCRIPTOR* Idt; -+UINT32 IdtSize; -+ - // - // Global Variables - // --IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 }; -- - EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100]; - BOOLEAN InterruptState = FALSE; - EFI_HANDLE mCpuHandle = NULL; -@@ -1004,8 +1007,6 @@ - ) - { - EFI_STATUS Status; -- VOID *IdtPtrAlignmentBuffer; -- IA32_DESCRIPTOR *IdtPtr; - UINTN Index; - UINTN CurrentHandler; - -@@ -1015,27 +1016,33 @@ - // Initialize IDT - // - CurrentHandler = (UINTN)AsmIdtVector00; -+ -+ // -+ // Allocate Runtime Data for the IDT -+ // -+ IdtSize = INTERRUPT_VECTOR_NUMBER*sizeof(IA32_IDT_GATE_DESCRIPTOR); -+#if 0 -+ Idt = AllocateRuntimePool (IdtSize + 16); -+ ASSERT (Idt != NULL); -+ Idt = ALIGN_POINTER (Idt, 16); -+#else -+ Idt = (VOID*)(UINTN)HandyCpuPage + 0x500; -+#endif -+ - for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++, CurrentHandler += 0x08) { -- gIdtTable[Index].Bits.OffsetLow = (UINT16)CurrentHandler; -- gIdtTable[Index].Bits.Selector = AsmReadCs(); -- gIdtTable[Index].Bits.Reserved_0 = 0; -- gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; -- gIdtTable[Index].Bits.OffsetHigh = (UINT16)(CurrentHandler >> 16); -+ Idt[Index].Bits.OffsetLow = (UINT16)CurrentHandler; -+ Idt[Index].Bits.Selector = AsmReadCs(); -+ Idt[Index].Bits.Reserved_0 = 0; -+ Idt[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; -+ Idt[Index].Bits.OffsetHigh = (UINT16)(CurrentHandler >> 16); - #if defined (MDE_CPU_X64) -- gIdtTable[Index].Bits.OffsetUpper = (UINT32)(CurrentHandler >> 32); -- gIdtTable[Index].Bits.Reserved_1 = 0; -+ Idt[Index].Bits.OffsetUpper = (UINT32)(CurrentHandler >> 32); -+ Idt[Index].Bits.Reserved_1 = 0; - #endif - } - -- // -- // Load IDT Pointer -- // -- IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); -- IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); -- IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); -- IdtPtr->Limit = sizeof (gIdtTable) - 1; -- AsmWriteIdtr (IdtPtr); -- FreePool (IdtPtrAlignmentBuffer); -+ // Load IDT -+ LoadIdt(Idt, IdtSize); - - // - // Initialize Exception Handlers -@@ -1052,7 +1059,50 @@ - - } - -+VOID EFIAPI -+LoadIdt(VOID* Idt, UINT32 IdtSize) -+{ -+ IA32_DESCRIPTOR IdtPtr; - -+ IdtPtr.Base = (UINT32)(((UINTN) Idt) & (BASE_4GB-1)); -+ IdtPtr.Limit = IdtSize - 1; -+ AsmWriteIdtr (&IdtPtr); -+} -+ -+UINT32 -+EFIAPI -+IoWrite32 ( -+ IN UINTN Port, -+ IN UINT32 Value -+ ) -+{ -+ __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port)); -+ return Value; -+} -+ -+VOID -+EFIAPI -+CpuLibVirtualNotifyEvent ( -+ IN EFI_EVENT Event, -+ IN VOID *Context -+ ) -+{ -+ EFI_RUNTIME_SERVICES * rs = (EFI_RUNTIME_SERVICES *)Context; -+ -+ rs->ConvertPointer (0, (VOID **) &Gdt); -+ rs->ConvertPointer (0, (VOID **) &Idt); -+ -+ DisableInterrupts(); -+ -+ LoadIdt(Idt, IdtSize); -+ LoadGdt(Gdt, GdtSize); -+ -+ //IoWrite32(0xef11, 1); -+} -+ -+extern EFI_GUID gEfiEventVirtualAddressChangeGuid; -+ -+ - /** - Initialize the state information for the CPU Architectural Protocol. - -@@ -1073,6 +1123,17 @@ - { - EFI_STATUS Status; - -+ -+ // Allocate handy page -+ HandyCpuPage = 0xffffffff; -+ Status = gBS->AllocatePages ( -+ AllocateMaxAddress, -+ EfiReservedMemoryType, -+ 1, -+ &HandyCpuPage ); -+ ASSERT_EFI_ERROR (Status); -+ ASSERT (HandyCpuPage != 0xffffffff); -+ - // - // Make sure interrupts are disabled - // -@@ -1103,6 +1164,18 @@ - // - RefreshGcdMemoryAttributes (); - -+ -+ // Register virtual address change notifier -+#if 0 -+ gBS->CreateEventEx ( -+ EVT_NOTIFY_SIGNAL, -+ TPL_NOTIFY, -+ CpuLibVirtualNotifyEvent, -+ SystemTable->RuntimeServices, -+ &gEfiEventVirtualAddressChangeGuid, -+ &mEfiVirtualNotifyEvent -+ ); -+#endif -+ - return Status; - } -- -Index: UefiCpuPkg/CpuDxe/CpuDxe.h -=================================================================== ---- UefiCpuPkg/CpuDxe/CpuDxe.h (revision 9332) -+++ UefiCpuPkg/CpuDxe/CpuDxe.h (working copy) -@@ -136,5 +136,17 @@ - ); - - -+VOID EFIAPI -+LoadGdt(VOID* Gdt, UINT32 GdtSize); -+ -+VOID EFIAPI -+LoadIdt(VOID* Idt, UINT32 IdtSize); -+ -+extern EFI_PHYSICAL_ADDRESS HandyCpuPage; -+extern VOID* Gdt; -+extern UINT32 GdtSize; -+extern IA32_IDT_GATE_DESCRIPTOR* Idt; -+extern UINT32 IdtSize; -+ - #endif - diff --git a/CloverPkg.dec b/CloverPkg.dec index e1f13016e..7315ced43 100644 --- a/CloverPkg.dec +++ b/CloverPkg.dec @@ -133,7 +133,11 @@ ## Include/Microsoft/Guid/MicrosoftVariable.h gMicrosoftVariableGuid = {0x77FA9ABD, 0x0359, 0x4D32, {0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B}} +##OsxAptioFixDrv + gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}} +##Oc + gEfiMemorySubClassGuid = { 0x4E8F4EBB, 0x64B9, 0x4e05, { 0x9b, 0x18, 0x4c, 0xfe, 0x49, 0x23, 0x50, 0x97 }} [Protocols] diff --git a/Drivers/UsbKbDxe/KeyBoard.c b/Drivers/UsbKbDxe/KeyBoard.c index b58b82da1..8182cc71b 100644 --- a/Drivers/UsbKbDxe/KeyBoard.c +++ b/Drivers/UsbKbDxe/KeyBoard.c @@ -984,7 +984,7 @@ KeyboardHandler ( UINT32 UsbStatus; EFI_KEY_DESCRIPTOR *KeyDescriptor; UINTN NumberOfKeys; - APPLE_KEY Keys[8]; + APPLE_KEY_CODE Keys[8]; ASSERT (Context != NULL); @@ -1104,7 +1104,7 @@ KeyboardHandler ( UsbKeyboardDevice->KeyMapDbIndex, (APPLE_MODIFIER_MAP)CurModifierMap, NumberOfKeys, - &Keys[0] //APPLE_KEY + &Keys[0] //APPLE_KEY_CODE ); } diff --git a/FileSystems/GrubFS/grub/grub-core/fs/reiserfs.c b/FileSystems/GrubFS/grub/grub-core/fs/reiserfs.c index 7515d1bc9..b597333b6 100644 --- a/FileSystems/GrubFS/grub/grub-core/fs/reiserfs.c +++ b/FileSystems/GrubFS/grub/grub-core/fs/reiserfs.c @@ -65,7 +65,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; -#define assert(boolean) real_assert (boolean, GRUB_FILE, __LINE__) +#define assert(boolean) real_assert (boolean, GRUB_STRINGIFY(GRUB_FILE), __LINE__) static inline void real_assert (int boolean, const char *file, const int line) { diff --git a/FileSystems/GrubFS/grub/grub-core/kern/mm.c b/FileSystems/GrubFS/grub/grub-core/kern/mm.c index 1c3d02388..94efe9448 100644 --- a/FileSystems/GrubFS/grub/grub-core/kern/mm.c +++ b/FileSystems/GrubFS/grub/grub-core/kern/mm.c @@ -412,7 +412,7 @@ grub_free (void *ptr) do { grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n", - GRUB_FILE, __LINE__, q, q->size, q->magic); + GRUB_STRINGIFY(GRUB_FILE), __LINE__, q, q->size, q->magic); q = q->next; } while (q != r->first); diff --git a/FileSystems/GrubFS/grub/include/grub/list.h b/FileSystems/GrubFS/grub/include/grub/list.h index d170ff6da..874c38c86 100644 --- a/FileSystems/GrubFS/grub/include/grub/list.h +++ b/FileSystems/GrubFS/grub/include/grub/list.h @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_list { @@ -48,7 +49,7 @@ grub_bad_type_cast_real (int line, const char *file) file, line); } -#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, GRUB_FILE) +#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, GRUB_STRINGIFY(GRUB_FILE)) #define GRUB_FIELD_MATCH(ptr, type, field) \ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field) diff --git a/FileSystems/GrubFS/grub/include/grub/misc.h b/FileSystems/GrubFS/grub/include/grub/misc.h index 0e0d3a604..0a77f5540 100644 --- a/FileSystems/GrubFS/grub/include/grub/misc.h +++ b/FileSystems/GrubFS/grub/include/grub/misc.h @@ -62,7 +62,9 @@ //#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) //defined in edk2 #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } -#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) +#define _GRUB_STRINGIFY(x) #x +#define GRUB_STRINGIFY(x) _GRUB_STRINGIFY(x) +#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_STRINGIFY(GRUB_FILE), __LINE__, condition, __VA_ARGS__) #undef grub_memmove #define grub_memmove memmove @@ -550,7 +552,7 @@ extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); void EXPORT_FUNC(grub_real_boot_time) (const char *file, const int line, const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); -#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) +#define grub_boot_time(...) grub_real_boot_time(GRUB_STRINGIFY(GRUB_FILE), __LINE__, __VA_ARGS__) #else #define grub_boot_time(...) #endif diff --git a/FileSystems/GrubFS/grub/include/grub/mm.h b/FileSystems/GrubFS/grub/include/grub/mm.h index 28e2e53eb..9f392c2a0 100644 --- a/FileSystems/GrubFS/grub/include/grub/mm.h +++ b/FileSystems/GrubFS/grub/include/grub/mm.h @@ -38,7 +38,7 @@ void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); #endif void grub_mm_check_real (const char *file, int line); -#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); +#define grub_mm_check() grub_mm_check_real (GRUB_STRINGIFY(GRUB_FILE), __LINE__); /* For debugging. */ #if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) @@ -49,19 +49,19 @@ void grub_mm_dump_free (void); void grub_mm_dump (unsigned lineno); #define grub_malloc(size) \ - grub_debug_malloc (GRUB_FILE, __LINE__, size) + grub_debug_malloc (GRUB_STRINGIFY(GRUB_FILE), __LINE__, size) #define grub_zalloc(size) \ - grub_debug_zalloc (GRUB_FILE, __LINE__, size) + grub_debug_zalloc (GRUB_STRINGIFY(GRUB_FILE), __LINE__, size) #define grub_realloc(ptr,size) \ - grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size) + grub_debug_realloc (GRUB_STRINGIFY(GRUB_FILE), __LINE__, ptr, size) #define grub_memalign(align,size) \ - grub_debug_memalign (GRUB_FILE, __LINE__, align, size) + grub_debug_memalign (GRUB_STRINGIFY(GRUB_FILE), __LINE__, align, size) #define grub_free(ptr) \ - grub_debug_free (GRUB_FILE, __LINE__, ptr) + grub_debug_free (GRUB_STRINGIFY(GRUB_FILE), __LINE__, ptr) void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line, grub_size_t size); diff --git a/FileSystems/GrubFS/grub/include/grub/test.h b/FileSystems/GrubFS/grub/include/grub/test.h index b83bdb14e..8dc5ae141 100644 --- a/FileSystems/GrubFS/grub/include/grub/test.h +++ b/FileSystems/GrubFS/grub/include/grub/test.h @@ -67,7 +67,7 @@ void grub_test_assert_helper (int cond, const char *file, __attribute__ ((format (GNU_PRINTF, 6, 7))); #define grub_test_assert(cond, ...) \ - grub_test_assert_helper(cond, GRUB_FILE, __FUNCTION__, __LINE__, \ + grub_test_assert_helper(cond, GRUB_STRINGIFY(GRUB_FILE), __FUNCTION__, __LINE__, \ #cond, ## __VA_ARGS__); void grub_unit_test_init (void); diff --git a/FileSystems/GrubFS/src/AFFS.inf b/FileSystems/GrubFS/src/AFFS.inf index c7d9aea32..9a4076fc9 100644 --- a/FileSystems/GrubFS/src/AFFS.inf +++ b/FileSystems/GrubFS/src/AFFS.inf @@ -71,8 +71,8 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFFS.efi\" -DDRIVERNAME=affs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFFS.efi\" -DDRIVERNAME=affs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFFS.efi\" -DDRIVERNAME=affs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFFS.efi\" -DDRIVERNAME=affs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFFS.efi -DDRIVERNAME=affs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFFS.efi -DDRIVERNAME=affs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFFS.efi -DDRIVERNAME=affs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFFS.efi -DDRIVERNAME=affs -Os diff --git a/FileSystems/GrubFS/src/AFS.inf b/FileSystems/GrubFS/src/AFS.inf index ab5f4d3a4..021f3dee8 100644 --- a/FileSystems/GrubFS/src/AFS.inf +++ b/FileSystems/GrubFS/src/AFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFS.efi\" -DDRIVERNAME=afs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFS.efi\" -DDRIVERNAME=afs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFS.efi\" -DDRIVERNAME=afs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"AFS.efi\" -DDRIVERNAME=afs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFS.efi -DDRIVERNAME=afs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFS.efi -DDRIVERNAME=afs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFS.efi -DDRIVERNAME=afs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=AFS.efi -DDRIVERNAME=afs -Os diff --git a/FileSystems/GrubFS/src/BFS.inf b/FileSystems/GrubFS/src/BFS.inf index 516ac6b4d..888b3840a 100644 --- a/FileSystems/GrubFS/src/BFS.inf +++ b/FileSystems/GrubFS/src/BFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BFS.efi\" -DDRIVERNAME=bfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BFS.efi\" -DDRIVERNAME=bfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BFS.efi\" -DDRIVERNAME=bfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BFS.efi\" -DDRIVERNAME=bfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BFS.efi -DDRIVERNAME=bfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BFS.efi -DDRIVERNAME=bfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BFS.efi -DDRIVERNAME=bfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BFS.efi -DDRIVERNAME=bfs -Os diff --git a/FileSystems/GrubFS/src/BTRFS.inf b/FileSystems/GrubFS/src/BTRFS.inf index de89215af..9aa7e5618 100644 --- a/FileSystems/GrubFS/src/BTRFS.inf +++ b/FileSystems/GrubFS/src/BTRFS.inf @@ -75,7 +75,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BTRFS.efi\" -DDRIVERNAME=btrfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BTRFS.efi\" -DDRIVERNAME=btrfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BTRFS.efi\" -DDRIVERNAME=btrfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"BTRFS.efi\" -DDRIVERNAME=btrfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BTRFS.efi -DDRIVERNAME=btrfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BTRFS.efi -DDRIVERNAME=btrfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BTRFS.efi -DDRIVERNAME=btrfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=BTRFS.efi -DDRIVERNAME=btrfs -Os diff --git a/FileSystems/GrubFS/src/CBFS.inf b/FileSystems/GrubFS/src/CBFS.inf index 8b8501365..91f51ddfa 100644 --- a/FileSystems/GrubFS/src/CBFS.inf +++ b/FileSystems/GrubFS/src/CBFS.inf @@ -74,7 +74,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CBFS.efi\" -DDRIVERNAME=cbfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CBFS.efi\" -DDRIVERNAME=cbfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CBFS.efi\" -DDRIVERNAME=cbfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CBFS.efi\" -DDRIVERNAME=cbfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CBFS.efi -DDRIVERNAME=cbfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CBFS.efi -DDRIVERNAME=cbfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CBFS.efi -DDRIVERNAME=cbfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CBFS.efi -DDRIVERNAME=cbfs -Os diff --git a/FileSystems/GrubFS/src/CPIO.inf b/FileSystems/GrubFS/src/CPIO.inf index 8390bc3fa..a4ca8df6e 100644 --- a/FileSystems/GrubFS/src/CPIO.inf +++ b/FileSystems/GrubFS/src/CPIO.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO.efi\" -DDRIVERNAME=cpio -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO.efi\" -DDRIVERNAME=cpio -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO.efi\" -DDRIVERNAME=cpio -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO.efi\" -DDRIVERNAME=cpio -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO.efi -DDRIVERNAME=cpio -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO.efi -DDRIVERNAME=cpio -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO.efi -DDRIVERNAME=cpio -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO.efi -DDRIVERNAME=cpio -Os diff --git a/FileSystems/GrubFS/src/CPIO_BE.inf b/FileSystems/GrubFS/src/CPIO_BE.inf index b060a5482..de8f25dbe 100644 --- a/FileSystems/GrubFS/src/CPIO_BE.inf +++ b/FileSystems/GrubFS/src/CPIO_BE.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO_BE.efi\" -DDRIVERNAME=cpio_be -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO_BE.efi\" -DDRIVERNAME=cpio_be -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO_BE.efi\" -DDRIVERNAME=cpio_be -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"CPIO_BE.efi\" -DDRIVERNAME=cpio_be -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO_BE.efi -DDRIVERNAME=cpio_be -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO_BE.efi -DDRIVERNAME=cpio_be -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO_BE.efi -DDRIVERNAME=cpio_be -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=CPIO_BE.efi -DDRIVERNAME=cpio_be -Os diff --git a/FileSystems/GrubFS/src/EXFAT.inf b/FileSystems/GrubFS/src/EXFAT.inf index 66f832ed7..7c10182ff 100644 --- a/FileSystems/GrubFS/src/EXFAT.inf +++ b/FileSystems/GrubFS/src/EXFAT.inf @@ -72,9 +72,9 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 -DMODE_EXFAT *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 -DMODE_EXFAT - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXFAT.efi\" -DDRIVERNAME=exfat -O0 - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXFAT.efi\" -DDRIVERNAME=exfat -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXFAT.efi\" -DDRIVERNAME=exfat -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXFAT.efi\" -DDRIVERNAME=exfat -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXFAT.efi -DDRIVERNAME=exfat -O0 + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXFAT.efi -DDRIVERNAME=exfat -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXFAT.efi -DDRIVERNAME=exfat -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXFAT.efi -DDRIVERNAME=exfat -Os diff --git a/FileSystems/GrubFS/src/EXT2.inf b/FileSystems/GrubFS/src/EXT2.inf index 1ab7db289..92c476ae6 100644 --- a/FileSystems/GrubFS/src/EXT2.inf +++ b/FileSystems/GrubFS/src/EXT2.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXT2.efi\" -DDRIVERNAME=ext2 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXT2.efi\" -DDRIVERNAME=ext2 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXT2.efi\" -DDRIVERNAME=ext2 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"EXT2.efi\" -DDRIVERNAME=ext2 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXT2.efi -DDRIVERNAME=ext2 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXT2.efi -DDRIVERNAME=ext2 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXT2.efi -DDRIVERNAME=ext2 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=EXT2.efi -DDRIVERNAME=ext2 -Os diff --git a/FileSystems/GrubFS/src/FAT.inf b/FileSystems/GrubFS/src/FAT.inf index a1e10ed23..1efb7199a 100644 --- a/FileSystems/GrubFS/src/FAT.inf +++ b/FileSystems/GrubFS/src/FAT.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"FAT.efi\" -DDRIVERNAME=fat -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"FAT.efi\" -DDRIVERNAME=fat -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"FAT.efi\" -DDRIVERNAME=fat -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"FAT.efi\" -DDRIVERNAME=fat -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=FAT.efi -DDRIVERNAME=fat -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=FAT.efi -DDRIVERNAME=fat -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=FAT.efi -DDRIVERNAME=fat -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=FAT.efi -DDRIVERNAME=fat -Os diff --git a/FileSystems/GrubFS/src/HFS.inf b/FileSystems/GrubFS/src/HFS.inf index 2e7969176..86745c34d 100644 --- a/FileSystems/GrubFS/src/HFS.inf +++ b/FileSystems/GrubFS/src/HFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFS.efi\" -DDRIVERNAME=hfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFS.efi\" -DDRIVERNAME=hfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFS.efi\" -DDRIVERNAME=hfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFS.efi\" -DDRIVERNAME=hfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFS.efi -DDRIVERNAME=hfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFS.efi -DDRIVERNAME=hfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFS.efi -DDRIVERNAME=hfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFS.efi -DDRIVERNAME=hfs -Os diff --git a/FileSystems/GrubFS/src/HFSPLUS.inf b/FileSystems/GrubFS/src/HFSPLUS.inf index 6797c40e3..d952c6d8c 100644 --- a/FileSystems/GrubFS/src/HFSPLUS.inf +++ b/FileSystems/GrubFS/src/HFSPLUS.inf @@ -74,8 +74,8 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFSPLUS.efi\" -DDRIVERNAME=hfsplus -O0 - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFSPLUS.efi\" -DDRIVERNAME=hfsplus -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFSPLUS.efi\" -DDRIVERNAME=hfsplus -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"HFSPLUS.efi\" -DDRIVERNAME=hfsplus -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFSPLUS.efi -DDRIVERNAME=hfsplus -O0 + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFSPLUS.efi -DDRIVERNAME=hfsplus -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFSPLUS.efi -DDRIVERNAME=hfsplus -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=HFSPLUS.efi -DDRIVERNAME=hfsplus -Os diff --git a/FileSystems/GrubFS/src/ISO9660.inf b/FileSystems/GrubFS/src/ISO9660.inf index c76c4813b..1df8afa23 100644 --- a/FileSystems/GrubFS/src/ISO9660.inf +++ b/FileSystems/GrubFS/src/ISO9660.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ISO9660.efi\" -DDRIVERNAME=iso9660 -O0 - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ISO9660.efi\" -DDRIVERNAME=iso9660 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ISO9660.efi\" -DDRIVERNAME=iso9660 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ISO9660.efi\" -DDRIVERNAME=iso9660 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ISO9660.efi -DDRIVERNAME=iso9660 -O0 + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ISO9660.efi -DDRIVERNAME=iso9660 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ISO9660.efi -DDRIVERNAME=iso9660 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ISO9660.efi -DDRIVERNAME=iso9660 -Os diff --git a/FileSystems/GrubFS/src/JFS.inf b/FileSystems/GrubFS/src/JFS.inf index ce820cb91..8e9d090ac 100644 --- a/FileSystems/GrubFS/src/JFS.inf +++ b/FileSystems/GrubFS/src/JFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"JFS.efi\" -DDRIVERNAME=jfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"JFS.efi\" -DDRIVERNAME=jfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"JFS.efi\" -DDRIVERNAME=jfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"JFS.efi\" -DDRIVERNAME=jfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=JFS.efi -DDRIVERNAME=jfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=JFS.efi -DDRIVERNAME=jfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=JFS.efi -DDRIVERNAME=jfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=JFS.efi -DDRIVERNAME=jfs -Os diff --git a/FileSystems/GrubFS/src/MINIX.inf b/FileSystems/GrubFS/src/MINIX.inf index b4a6a1589..0aaa00cb9 100644 --- a/FileSystems/GrubFS/src/MINIX.inf +++ b/FileSystems/GrubFS/src/MINIX.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX.efi\" -DDRIVERNAME=minix -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX.efi\" -DDRIVERNAME=minix -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX.efi\" -DDRIVERNAME=minix -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX.efi\" -DDRIVERNAME=minix -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX.efi -DDRIVERNAME=minix -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX.efi -DDRIVERNAME=minix -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX.efi -DDRIVERNAME=minix -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX.efi -DDRIVERNAME=minix -Os diff --git a/FileSystems/GrubFS/src/MINIX2.inf b/FileSystems/GrubFS/src/MINIX2.inf index 315da5b7a..1615aebfa 100644 --- a/FileSystems/GrubFS/src/MINIX2.inf +++ b/FileSystems/GrubFS/src/MINIX2.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2.efi\" -DDRIVERNAME=minix2 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2.efi\" -DDRIVERNAME=minix2 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2.efi\" -DDRIVERNAME=minix2 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2.efi\" -DDRIVERNAME=minix2 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2.efi -DDRIVERNAME=minix2 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2.efi -DDRIVERNAME=minix2 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2.efi -DDRIVERNAME=minix2 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2.efi -DDRIVERNAME=minix2 -Os diff --git a/FileSystems/GrubFS/src/MINIX2_BE.inf b/FileSystems/GrubFS/src/MINIX2_BE.inf index 0f88f0ab5..939b42baa 100644 --- a/FileSystems/GrubFS/src/MINIX2_BE.inf +++ b/FileSystems/GrubFS/src/MINIX2_BE.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2_BE.efi\" -DDRIVERNAME=minix2_be -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2_BE.efi\" -DDRIVERNAME=minix2_be -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2_BE.efi\" -DDRIVERNAME=minix2_be -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX2_BE.efi\" -DDRIVERNAME=minix2_be -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2_BE.efi -DDRIVERNAME=minix2_be -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2_BE.efi -DDRIVERNAME=minix2_be -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2_BE.efi -DDRIVERNAME=minix2_be -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX2_BE.efi -DDRIVERNAME=minix2_be -Os diff --git a/FileSystems/GrubFS/src/MINIX3.inf b/FileSystems/GrubFS/src/MINIX3.inf index 4fb791072..9e28b9f30 100644 --- a/FileSystems/GrubFS/src/MINIX3.inf +++ b/FileSystems/GrubFS/src/MINIX3.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3.efi\" -DDRIVERNAME=minix3 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3.efi\" -DDRIVERNAME=minix3 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3.efi\" -DDRIVERNAME=minix3 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3.efi\" -DDRIVERNAME=minix3 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3.efi -DDRIVERNAME=minix3 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3.efi -DDRIVERNAME=minix3 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3.efi -DDRIVERNAME=minix3 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3.efi -DDRIVERNAME=minix3 -Os diff --git a/FileSystems/GrubFS/src/MINIX3_BE.inf b/FileSystems/GrubFS/src/MINIX3_BE.inf index 89062dcdf..dec5fe8ab 100644 --- a/FileSystems/GrubFS/src/MINIX3_BE.inf +++ b/FileSystems/GrubFS/src/MINIX3_BE.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3_BE.efi\" -DDRIVERNAME=minix3_be -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3_BE.efi\" -DDRIVERNAME=minix3_be -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3_BE.efi\" -DDRIVERNAME=minix3_be -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX3_BE.efi\" -DDRIVERNAME=minix3_be -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3_BE.efi -DDRIVERNAME=minix3_be -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3_BE.efi -DDRIVERNAME=minix3_be -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3_BE.efi -DDRIVERNAME=minix3_be -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX3_BE.efi -DDRIVERNAME=minix3_be -Os diff --git a/FileSystems/GrubFS/src/MINIX_BE.inf b/FileSystems/GrubFS/src/MINIX_BE.inf index f3b364130..0265c9ff9 100644 --- a/FileSystems/GrubFS/src/MINIX_BE.inf +++ b/FileSystems/GrubFS/src/MINIX_BE.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX_BE.efi\" -DDRIVERNAME=minix_be -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX_BE.efi\" -DDRIVERNAME=minix_be -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX_BE.efi\" -DDRIVERNAME=minix_be -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"MINIX_BE.efi\" -DDRIVERNAME=minix_be -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX_BE.efi -DDRIVERNAME=minix_be -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX_BE.efi -DDRIVERNAME=minix_be -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX_BE.efi -DDRIVERNAME=minix_be -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=MINIX_BE.efi -DDRIVERNAME=minix_be -Os diff --git a/FileSystems/GrubFS/src/NEWC.inf b/FileSystems/GrubFS/src/NEWC.inf index cde8042c2..32aae4652 100644 --- a/FileSystems/GrubFS/src/NEWC.inf +++ b/FileSystems/GrubFS/src/NEWC.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NEWC.efi\" -DDRIVERNAME=newc -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NEWC.efi\" -DDRIVERNAME=newc -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NEWC.efi\" -DDRIVERNAME=newc -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NEWC.efi\" -DDRIVERNAME=newc -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NEWC.efi -DDRIVERNAME=newc -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NEWC.efi -DDRIVERNAME=newc -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NEWC.efi -DDRIVERNAME=newc -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NEWC.efi -DDRIVERNAME=newc -Os diff --git a/FileSystems/GrubFS/src/NILFS2.inf b/FileSystems/GrubFS/src/NILFS2.inf index 9a5df4261..3bedc7c57 100644 --- a/FileSystems/GrubFS/src/NILFS2.inf +++ b/FileSystems/GrubFS/src/NILFS2.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NILFS2.efi\" -DDRIVERNAME=nilfs2 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NILFS2.efi\" -DDRIVERNAME=nilfs2 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NILFS2.efi\" -DDRIVERNAME=nilfs2 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NILFS2.efi\" -DDRIVERNAME=nilfs2 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NILFS2.efi -DDRIVERNAME=nilfs2 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NILFS2.efi -DDRIVERNAME=nilfs2 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NILFS2.efi -DDRIVERNAME=nilfs2 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NILFS2.efi -DDRIVERNAME=nilfs2 -Os diff --git a/FileSystems/GrubFS/src/NTFS.inf b/FileSystems/GrubFS/src/NTFS.inf index bc3add037..ba17ceda2 100644 --- a/FileSystems/GrubFS/src/NTFS.inf +++ b/FileSystems/GrubFS/src/NTFS.inf @@ -74,8 +74,8 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NTFS.efi\" -DDRIVERNAME=ntfs -O0 - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NTFS.efi\" -DDRIVERNAME=ntfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NTFS.efi\" -DDRIVERNAME=ntfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"NTFS.efi\" -DDRIVERNAME=ntfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NTFS.efi -DDRIVERNAME=ntfs -O0 + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NTFS.efi -DDRIVERNAME=ntfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NTFS.efi -DDRIVERNAME=ntfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=NTFS.efi -DDRIVERNAME=ntfs -Os diff --git a/FileSystems/GrubFS/src/ODC.inf b/FileSystems/GrubFS/src/ODC.inf index 7f5e88d76..84bf91b56 100644 --- a/FileSystems/GrubFS/src/ODC.inf +++ b/FileSystems/GrubFS/src/ODC.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ODC.efi\" -DDRIVERNAME=odc -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ODC.efi\" -DDRIVERNAME=odc -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ODC.efi\" -DDRIVERNAME=odc -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ODC.efi\" -DDRIVERNAME=odc -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ODC.efi -DDRIVERNAME=odc -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ODC.efi -DDRIVERNAME=odc -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ODC.efi -DDRIVERNAME=odc -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ODC.efi -DDRIVERNAME=odc -Os diff --git a/FileSystems/GrubFS/src/PROC.inf b/FileSystems/GrubFS/src/PROC.inf index b447342b9..58d6348b1 100644 --- a/FileSystems/GrubFS/src/PROC.inf +++ b/FileSystems/GrubFS/src/PROC.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"PROC.efi\" -DDRIVERNAME=procfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"PROC.efi\" -DDRIVERNAME=procfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"PROC.efi\" -DDRIVERNAME=procfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"PROC.efi\" -DDRIVERNAME=procfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=PROC.efi -DDRIVERNAME=procfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=PROC.efi -DDRIVERNAME=procfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=PROC.efi -DDRIVERNAME=procfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=PROC.efi -DDRIVERNAME=procfs -Os diff --git a/FileSystems/GrubFS/src/REISERFS.inf b/FileSystems/GrubFS/src/REISERFS.inf index 426155460..470eeecf0 100644 --- a/FileSystems/GrubFS/src/REISERFS.inf +++ b/FileSystems/GrubFS/src/REISERFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"REISERFS.efi\" -DDRIVERNAME=reiserfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"REISERFS.efi\" -DDRIVERNAME=reiserfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"REISERFS.efi\" -DDRIVERNAME=reiserfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"REISERFS.efi\" -DDRIVERNAME=reiserfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=REISERFS.efi -DDRIVERNAME=reiserfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=REISERFS.efi -DDRIVERNAME=reiserfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=REISERFS.efi -DDRIVERNAME=reiserfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=REISERFS.efi -DDRIVERNAME=reiserfs -Os diff --git a/FileSystems/GrubFS/src/ROMFS.inf b/FileSystems/GrubFS/src/ROMFS.inf index e902af50e..17e164502 100644 --- a/FileSystems/GrubFS/src/ROMFS.inf +++ b/FileSystems/GrubFS/src/ROMFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ROMFS.efi\" -DDRIVERNAME=romfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ROMFS.efi\" -DDRIVERNAME=romfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ROMFS.efi\" -DDRIVERNAME=romfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ROMFS.efi\" -DDRIVERNAME=romfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ROMFS.efi -DDRIVERNAME=romfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ROMFS.efi -DDRIVERNAME=romfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ROMFS.efi -DDRIVERNAME=romfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ROMFS.efi -DDRIVERNAME=romfs -Os diff --git a/FileSystems/GrubFS/src/SFS.inf b/FileSystems/GrubFS/src/SFS.inf index 145d3a28a..ab4eea9d5 100644 --- a/FileSystems/GrubFS/src/SFS.inf +++ b/FileSystems/GrubFS/src/SFS.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SFS.efi\" -DDRIVERNAME=sfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SFS.efi\" -DDRIVERNAME=sfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SFS.efi\" -DDRIVERNAME=sfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SFS.efi\" -DDRIVERNAME=sfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SFS.efi -DDRIVERNAME=sfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SFS.efi -DDRIVERNAME=sfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SFS.efi -DDRIVERNAME=sfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SFS.efi -DDRIVERNAME=sfs -Os diff --git a/FileSystems/GrubFS/src/SQUASH4.inf b/FileSystems/GrubFS/src/SQUASH4.inf index d51f47211..aef36850c 100644 --- a/FileSystems/GrubFS/src/SQUASH4.inf +++ b/FileSystems/GrubFS/src/SQUASH4.inf @@ -80,7 +80,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SQUASH4.efi\" -DDRIVERNAME=squash4 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SQUASH4.efi\" -DDRIVERNAME=squash4 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SQUASH4.efi\" -DDRIVERNAME=squash4 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"SQUASH4.efi\" -DDRIVERNAME=squash4 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SQUASH4.efi -DDRIVERNAME=squash4 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SQUASH4.efi -DDRIVERNAME=squash4 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SQUASH4.efi -DDRIVERNAME=squash4 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=SQUASH4.efi -DDRIVERNAME=squash4 -Os diff --git a/FileSystems/GrubFS/src/TAR.inf b/FileSystems/GrubFS/src/TAR.inf index 7339368fc..0d91fbdc4 100644 --- a/FileSystems/GrubFS/src/TAR.inf +++ b/FileSystems/GrubFS/src/TAR.inf @@ -73,7 +73,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"TAR.efi\" -DDRIVERNAME=tar -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"TAR.efi\" -DDRIVERNAME=tar -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"TAR.efi\" -DDRIVERNAME=tar -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"TAR.efi\" -DDRIVERNAME=tar -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=TAR.efi -DDRIVERNAME=tar -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=TAR.efi -DDRIVERNAME=tar -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=TAR.efi -DDRIVERNAME=tar -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=TAR.efi -DDRIVERNAME=tar -Os diff --git a/FileSystems/GrubFS/src/UDF.inf b/FileSystems/GrubFS/src/UDF.inf index 434d20e55..40091560c 100644 --- a/FileSystems/GrubFS/src/UDF.inf +++ b/FileSystems/GrubFS/src/UDF.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UDF.efi\" -DDRIVERNAME=udf -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UDF.efi\" -DDRIVERNAME=udf -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UDF.efi\" -DDRIVERNAME=udf -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UDF.efi\" -DDRIVERNAME=udf -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UDF.efi -DDRIVERNAME=udf -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UDF.efi -DDRIVERNAME=udf -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UDF.efi -DDRIVERNAME=udf -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UDF.efi -DDRIVERNAME=udf -Os diff --git a/FileSystems/GrubFS/src/UFS.inf b/FileSystems/GrubFS/src/UFS.inf index 53f5e3f61..eeccb5d7e 100644 --- a/FileSystems/GrubFS/src/UFS.inf +++ b/FileSystems/GrubFS/src/UFS.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS.efi\" -DDRIVERNAME=ufs1 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS.efi\" -DDRIVERNAME=ufs1 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS.efi\" -DDRIVERNAME=ufs1 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS.efi\" -DDRIVERNAME=ufs1 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS.efi -DDRIVERNAME=ufs1 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS.efi -DDRIVERNAME=ufs1 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS.efi -DDRIVERNAME=ufs1 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS.efi -DDRIVERNAME=ufs1 -Os diff --git a/FileSystems/GrubFS/src/UFS2.inf b/FileSystems/GrubFS/src/UFS2.inf index 8d1161f72..79db3b138 100644 --- a/FileSystems/GrubFS/src/UFS2.inf +++ b/FileSystems/GrubFS/src/UFS2.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS2.efi\" -DDRIVERNAME=ufs2 -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS2.efi\" -DDRIVERNAME=ufs2 -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS2.efi\" -DDRIVERNAME=ufs2 -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS2.efi\" -DDRIVERNAME=ufs2 -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS2.efi -DDRIVERNAME=ufs2 -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS2.efi -DDRIVERNAME=ufs2 -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS2.efi -DDRIVERNAME=ufs2 -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS2.efi -DDRIVERNAME=ufs2 -Os diff --git a/FileSystems/GrubFS/src/UFS_BE.inf b/FileSystems/GrubFS/src/UFS_BE.inf index d92de0158..d4d7f314d 100644 --- a/FileSystems/GrubFS/src/UFS_BE.inf +++ b/FileSystems/GrubFS/src/UFS_BE.inf @@ -71,7 +71,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS_BE.efi\" -DDRIVERNAME=ufs1_be -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS_BE.efi\" -DDRIVERNAME=ufs1_be -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS_BE.efi\" -DDRIVERNAME=ufs1_be -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"UFS_BE.efi\" -DDRIVERNAME=ufs1_be -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS_BE.efi -DDRIVERNAME=ufs1_be -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS_BE.efi -DDRIVERNAME=ufs1_be -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS_BE.efi -DDRIVERNAME=ufs1_be -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=UFS_BE.efi -DDRIVERNAME=ufs1_be -Os diff --git a/FileSystems/GrubFS/src/XFS.inf b/FileSystems/GrubFS/src/XFS.inf index 16b1ccb3d..ef21b3064 100644 --- a/FileSystems/GrubFS/src/XFS.inf +++ b/FileSystems/GrubFS/src/XFS.inf @@ -72,7 +72,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"XFS.efi\" -DDRIVERNAME=xfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"XFS.efi\" -DDRIVERNAME=xfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"XFS.efi\" -DDRIVERNAME=xfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"XFS.efi\" -DDRIVERNAME=xfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=XFS.efi -DDRIVERNAME=xfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=XFS.efi -DDRIVERNAME=xfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=XFS.efi -DDRIVERNAME=xfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=XFS.efi -DDRIVERNAME=xfs -Os diff --git a/FileSystems/GrubFS/src/ZFS.inf b/FileSystems/GrubFS/src/ZFS.inf index 5f23d7e03..b4dbba76b 100644 --- a/FileSystems/GrubFS/src/ZFS.inf +++ b/FileSystems/GrubFS/src/ZFS.inf @@ -85,7 +85,7 @@ [BuildOptions.common] *_*_IA32_CC_FLAGS = -DFORMAT=efi-app-ia32 *_*_X64_CC_FLAGS = -DFORMAT=efi-app-x64 - GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ZFS.efi\" -DDRIVERNAME=zfs -Os - XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ZFS.efi\" -DDRIVERNAME=zfs -Os - IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ZFS.efi\" -DDRIVERNAME=zfs -Os - MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=\"ZFS.efi\" -DDRIVERNAME=zfs -Os + GCC:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ZFS.efi -DDRIVERNAME=zfs -Os + XCODE:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ZFS.efi -DDRIVERNAME=zfs -Os + IBTEL:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ZFS.efi -DDRIVERNAME=zfs -Os + MSFT:*_*_*_CC_FLAGS = -DCPU_$(ARCH) -DMDEPKG_NDEBUG -DGRUB_MACHINE_EFI -DGRUB_KERNEL -DGRUB_UTIL -DGRUB_FILE=ZFS.efi -DDRIVERNAME=zfs -Os diff --git a/Include/Guid/AppleBless.h b/Include/Guid/AppleBless.h deleted file mode 100644 index 8ca15bcef..000000000 --- a/Include/Guid/AppleBless.h +++ /dev/null @@ -1,69 +0,0 @@ -/** @file -Copyright (C) 2014 - 2016, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_BLESS_H -#define APPLE_BLESS_H - -// -// These GUIDs allow to retrieve parsed finderInfo fields out of HFSPlusVolumeHeader -// via HFSPlus.efi driver. The fields are reads from the following structure in Big Endian: -// -// struct HFSPlusVolumeFinderInfo { -// uint32_t blessedSystemFolderID; // for OpenFirmware systems -// uint32_t blessedSystemFileID; // for EFI systems -// uint32_t openWindowFolderID; // deprecated, first link in linked list of folders to open at mount -// uint32_t blessedAlternateOSID; // currently used for FV2 recovery, inaccessible from UEFI -// uint32_t unused; // formerly PowerTalk Inbox -// uint32_t blessedOSXFolderID; // currently used for normal recovery -// uint64_t volumeID; -// }; -// -// References: -// https://opensource.apple.com/source/hfs/hfs-407.30.1/core/hfs_format.h.auto.html -// https://opensource.apple.com/source/bless/bless-166/handleInfo.c.auto.html -// https://opensource.apple.com/source/bless/bless-166/libbless/FinderInfo/BLGetVolumeFinderInfo.c.auto.html -// https://opensource.apple.com/source/bless/bless-166/libbless/HFS/BLLookupFileIDOnMount.c.auto.html -// -// TODO: Implement this in an opensource HFSPlus EFI driver. -// - -// APPLE_BLESSED_SYSTEM_FILE_INFO_GUID -/// InformationType GUID used to get the blessed file's path. -#define APPLE_BLESSED_SYSTEM_FILE_INFO_GUID \ - { 0xCA7E4814, 0x2ADC, 0x4ADD, \ - { 0xAB, 0xFF, 0x73, 0x4E, 0x3C, 0xFE, 0x13, 0xF3 } } - -// APPLE_BLESSED_SYSTEM_FOLDER_INFO_GUID -/// InformationType GUID exposed used to get the blessed folder's path. -#define APPLE_BLESSED_SYSTEM_FOLDER_INFO_GUID \ - { 0x7BD1F02D, 0x9C2F, 0x4581, \ - { 0xBF, 0x12, 0xD5, 0x4a, 0xBA, 0x0D, 0x98, 0xD6 } } - -// APPLE_BLESSED_OSX_FOLDER_INFO_GUID -/// InformationType GUID exposed used to get alternative blessed file or folder's path. -#define APPLE_BLESSED_OSX_FOLDER_INFO_GUID \ - { 0x893CA450, 0x5F5E, 0x48BA, \ - { 0x85, 0x8F, 0x08, 0xC4, 0x5D, 0x80, 0x23, 0x18 } } - -// gAppleBlessedSystemFileInfoGuid -/// A global variable storing the GUID of the APPLE_BLESSED_SYSTEM_FILE_INFO_GUID. -extern EFI_GUID gAppleBlessedSystemFileInfoGuid; - -// gAppleBlessedSystemFolderInfoGuid -/// A global variable storing the GUID of the APPLE_BLESSED_SYSTEM_FOLDER_INFO_GUID. -extern EFI_GUID gAppleBlessedSystemFolderInfoGuid; - -// gAppleBlessedOsxFolderInfoGuid -/// A global variable storing the GUID of the APPLE_BLESSED_OSX_FOLDER_INFO_GUID. -extern EFI_GUID gAppleBlessedOsxFolderInfoGuid; - -#endif // APPLE_BLESS_H diff --git a/Include/Guid/AppleFile.h b/Include/Guid/AppleFile.h deleted file mode 100644 index ed4787015..000000000 --- a/Include/Guid/AppleFile.h +++ /dev/null @@ -1,102 +0,0 @@ -/** @file -Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_FILE_H -#define APPLE_FILE_H - -// -// ASCII content stored in legacy firmwares. -// -#define APPLE_FIRMWARE_INFO_FILE_GUID \ - { 0x95C8C131, 0x4467, 0x4447, \ - { 0x8A, 0x71, 0xF0, 0x87, 0xAF, 0xCA, 0x07, 0xA5 } } - -// gAppleFirmwareInfoFileGuid -extern EFI_GUID gAppleFirmwareInfoFileGuid; - -#define APPLE_SLING_SHOT_FILE_GUID \ - { 0xD5B366C7, 0xDB85, 0x455F, \ - { 0xB5, 0x0B, 0x90, 0x0A, 0x69, 0x4E, 0x4C, 0x8C } } - -extern EFI_GUID gAppleSlingShotFileGuid; - -#define APPLE_BOOT_PICKER_FILE_GUID \ - { 0xE1628C66, 0x2A2D, 0x4DC5, \ - { 0xBD, 0x41, 0xB2, 0x0F, 0x35, 0x38, 0xAA, 0xF7 } } - -extern EFI_GUID gAppleBootPickerFileGuid; - -#define APPLE_PASSWORD_UI_FILE_GUID \ - { 0x9EBA2D25, 0xBBE3, 0x4AC2, \ - { 0xA2, 0xC6, 0xC8, 0x7F, 0x44, 0xA1, 0x27, 0x8C } } - -extern EFI_GUID gApplePasswordUIFileGuid; - -#define APPLE_UTDMUI_APP_FILE_GUID \ - { 0xD3231048, 0xB7D7, 0x46FC, \ - { 0x80, 0xF8, 0x2F, 0x7B, 0x22, 0x95, 0x86, 0xC5 } } - -extern EFI_GUID gAppleUTDMUIAppFileGuid; - -#define APPLE_LEGACY_LOAD_APP_FILE_GUID \ - { 0x2B0585EB, 0xD8B8, 0x49A9, \ - { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } } - -extern EFI_GUID gAppleLegacyLoadAppFileGuid; - -/// -/// 05984E1A-D8BB-5D8A-A8E6-90E6FB2AB7DA -/// -#define APPLE_ALERT_UI_FILE_GUID \ - { 0x05984E1A, 0xD8BB, 0x5D8A, \ - { 0xA8, 0xE6, 0x90, 0xE6, 0xFB, 0x2A, 0xB7, 0xDA } } - -extern EFI_GUID gAppleAlertUiFileGuid; - -/// -/// 4CF484CD-135F-4FDC-BAFB-1AA104B48D36 -/// -#define APPLE_HFS_PLUS_DXE_FILE_GUID \ - { 0x4CF484CD, 0x135F, 0x4FDC, \ - { 0xBA, 0xFB, 0x1A, 0xA1, 0x04, 0xB4, 0x8D, 0x36 } } - -extern EFI_GUID gAppleHfsPlusDxeFileGuid; - -/// -/// AE4C11C8-1D6C-F24E-A183-E1CA36D1A8A9 -/// -#define APPLE_HFS_PLUS_FILE_GUID \ - { 0xAE4C11C8, 0x1D6C, 0xF24E, \ - { 0xA1, 0x83, 0xE1, 0xCA, 0x36, 0xD1, 0xA8, 0xA9 } } - -extern EFI_GUID gAppleHfsPlusFileGuid; - -/// -/// 44883EC1-C77C-1749-B73D-30C7B468B556 -/// -#define APPLE_EX_FAT_DXE_FILE_GUID \ - { 0x44883EC1, 0xC77C, 0x1749, \ - { 0xB7, 0x3D, 0x30, 0xC7, 0xB4, 0x68, 0xB5, 0x56 } } - -extern EFI_GUID gAppleExFatDxeFileGuid; - -/// -/// 3730EC36-868D-4DF6-88CF-30B791272F5C -/// -#define APPLE_APFS_FILE_GUID \ - { 0x3730EC36, 0x868D, 0x4DF6, \ - { 0x88, 0xCF, 0x30, 0xB7, 0x91, 0x27, 0x2F, 0x5C } } - -extern EFI_GUID gAppleApfsFileGuid; - - -#endif // APPLE_FILE_H diff --git a/Include/Guid/AppleHfsInfo.h b/Include/Guid/AppleHfsInfo.h deleted file mode 100644 index f04f14ac4..000000000 --- a/Include/Guid/AppleHfsInfo.h +++ /dev/null @@ -1,53 +0,0 @@ -/** @file -Copyright (C) 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_HFS_INFO_H -#define APPLE_HFS_INFO_H - -/** - Normal HFS+ volume. -**/ -#define APPLE_HFS_PARTITION_TYPE_GUID \ - { 0x48465300, 0x0000, 0x11AA, \ - { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } } - -extern EFI_GUID gAppleHfsPartitionTypeGuid; - -/** - CoreStorage HFS+ volume. -**/ -#define APPLE_HFS_CS_PARTITION_TYPE_GUID \ - { 0x53746F72, 0x6167, 0x11AA, \ - { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } } - -extern EFI_GUID gAppleHfsCsPartitionTypeGuid; - -/** - Boot (Recovery) HFS+ volume. -**/ -#define APPLE_HFS_BOOT_PARTITION_TYPE_GUID \ - { 0x426F6F74, 0x0000, 0x11AA, \ - { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } } - -extern EFI_GUID gAppleHfsBootPartitionTypeGuid; - -/** - Accessible from EFI_FILE_PROTOCOL::GetInfo, this GUID - allows to quickly obtain volume UUID. -**/ -#define APPLE_HFS_UUID_INFO_GUID \ - { 0xFA99420C, 0x88F1, 0x11E7, \ - { 0x95, 0xF6, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } } - -extern EFI_GUID gAppleHfsUuidInfoGuid; - -#endif // APPLE_HFS_INFO_H diff --git a/Include/Guid/AppleOSLoaded.h b/Include/Guid/AppleOSLoaded.h deleted file mode 100644 index 2d14f420d..000000000 --- a/Include/Guid/AppleOSLoaded.h +++ /dev/null @@ -1,26 +0,0 @@ -/** @file -Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_OS_LOADED_H -#define APPLE_OS_LOADED_H - -#include - -// APPLE_OS_LOADED_EVENT_NAME -#define APPLE_OS_LOADED_NAMED_EVENT_GUID \ - { 0xC5C5DA95, 0x7D5C, 0x45E6, \ - { 0x83, 0x72, 0x89, 0xBD, 0x52, 0x6D, 0xE9, 0x56 } } - -// gAppleOSLoadedNamedEventGuid -extern EFI_GUID gAppleOSLoadedNamedEventGuid; - -#endif // APPLE_OS_LOADED_H diff --git a/Include/Guid/AppleVariable.h b/Include/Guid/AppleVariable.h deleted file mode 100644 index 2ab66224e..000000000 --- a/Include/Guid/AppleVariable.h +++ /dev/null @@ -1,303 +0,0 @@ -/** @file -Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_VARIABLE_H -#define APPLE_VARIABLE_H - -#include - -/// -/// The Apple Vendor Variable-vendor GUID. -/// -#define APPLE_VENDOR_VARIABLE_GUID \ - { 0x4D1EDE05, 0x38C7, 0x4A6A, \ - { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x8C, 0x14 } } - -/// -/// The Apple boot Variable-vendor GUID. -/// -#define APPLE_BOOT_VARIABLE_GUID \ - { 0x7C436110, 0xAB2A, 0x4BBB, \ - { 0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82 } } - -/// -/// The Apple Core Storage Variable-vendor GUID. -/// -#define APPLE_CORE_STORAGE_VARIABLE_GUID \ - { 0x8D63D4FE, 0xBD3C, 0x4AAD, \ - { 0x88, 0x1D, 0x86, 0xFD, 0x97, 0x4B, 0xC1, 0xDF } } - -/// -/// The Apple TRB Variable-vendor GUID. -/// -#define APPLE_TAMPER_RESISTANT_BOOT_VARIABLE_GUID \ - { 0x5D62B28D, 0x6ED2, 0x40B4, \ - { 0xA5, 0x60, 0x6C, 0xD7, 0x9B, 0x93, 0xD3, 0x66 } } - -/// -/// The Apple TRB EFI User GUID. -/// -#define APPLE_TAMPER_RESISTANT_BOOT_EFI_USER_GUID \ - { 0x4E8023FF, 0xA79A, 0x47D1, \ - { 0xA3, 0x42, 0x75, 0x24, 0xCF, 0xC9, 0x6D, 0xC4 } } - -/// -/// The Apple WiFi Network Variable-vendor GUID. -/// -#define APPLE_WIRELESS_NETWORK_VARIABLE_GUID \ - { 0x36C28AB5, 0x6566, 0x4C50, \ - { 0x9E, 0xBD, 0xCB, 0xB9, 0x20, 0xF8, 0x38, 0x43 } } - -/// -/// The Apple Personalization Variable-vendor GUID. -/// -#define APPLE_PERSONALIZATION_VARIABLE_GUID \ - { 0xFA4CE28D, 0xB62F, 0x4C99, \ - { 0x9C, 0xC3, 0x68, 0x15, 0x68, 0x6E, 0x30, 0xF9 } } - -/// -/// The Apple TRB Secure Variable-vendor GUID. -/// -#define APPLE_TAMPER_RESISTANT_BOOT_SECURE_VARIABLE_GUID \ - { 0xF68DA75E, 0x1B55, 0x4E70, \ - { 0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA } } - -/// -/// The Apple Netboot Variable-vendor GUID. -/// -#define APPLE_NETBOOT_VARIABLE_GUID \ - { 0x37BCBEC7, 0xA645, 0x4215, \ - { 0x97, 0x9E, 0xF5, 0xAE, 0x4D, 0x11, 0x5F, 0x13 } } - -/// -/// The Apple Security-vendor GUID. -/// -#define APPLE_SECURITY_VARIABLE_GUID \ - { 0x7870DBED, 0x151D, 0x63FE, \ - { 0xF5, 0x88, 0x7C, 0x69, 0x94, 0x1C, 0xD0, 0x7B } } - -/// -/// The Apple Secure Boot Variable-vendor GUID. -/// -#define APPLE_SECURE_BOOT_VARIABLE_GUID \ - { 0x94B73556, 0x2197, 0x4702, \ - { 0x82, 0xA8, 0x3E, 0x13, 0x37, 0xDA, 0xFB, 0xFB } } - -/// -/// The Apple Startup Manager Variable-vendor GUID. -/// -#define APPLE_STARTUP_MANAGER_VARIABLE_GUID \ - { 0x5EEB160F, 0x45FB, 0x4CE9, \ - { 0xB4, 0xE3, 0x61, 0x03, 0x59, 0xAB, 0xF6, 0xF8 } } - -/// -/// The Apple Boot Variable Backup-vendor GUID. -/// -#define APPLE_BACKUP_BOOT_VARIABLE_GUID \ - { 0xA5CE328C, 0x769D, 0x11E9, \ - { 0x94, 0xC7, 0x8C, 0x85, 0x90, 0x6B, 0xAC, 0x48 } } - -/// -/// User interface scale variable -/// UINT8: 1 or 2 -/// gEfiAppleNvramGuid -/// -#define APPLE_UI_SCALE_VARIABLE_NAME L"UIScale" - -/// -/// User interface scale variable. -/// UINT32: RGBA -/// gEfiAppleNvramGuid -/// -#define APPLE_DEFAULT_BACKGROUND_COLOR_VARIABLE_NAME L"DefaultBackgroundColor" - -typedef enum { - ApplePickerEntryReasonUnknown = 0, ///< Unknown - ApplePickerEntryReasonManufacturingMode = 1, ///< IR Remote - ApplePickerEntryReasonNvram = 2, ///< NVRAM - ApplePickerEntryReasonLeftOptKeyPress = 3, ///< Left Option - ApplePickerEntryReasonRightOptKeyPress = 4, ///< Right Option - ApplePickerEntryReasonBootDeviceTimeout = 5, ///< BDS Timeout -} APPLE_PICKER_ENTRY_REASON; - -/// -/// BootPicker startup mode. -/// UINT32: APPLE_PICKER_ENTRY_REASON. -/// gEfiAppleNvramGuid -/// -#define APPLE_PICKER_ENTRY_REASON_VARIABLE_NAME L"PickerEntryReason" - -#define APPLE_SYSTEM_AUDIO_VOLUME_MUTED BIT7 -#define APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK 0x7FU - -/// -/// System audio volume. -/// UINT8: APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK | APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK -/// gEfiAppleBootGuid -/// -#define APPLE_SYSTEM_AUDIO_VOLUME_VARIABLE_NAME L"SystemAudioVolume" - -/// -/// System audio volume backup, restored by AppleEFIRuntime.kext at next reboot. -/// UINT8: APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK | APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK -/// gEfiAppleBootGuid -/// -#define APPLE_SYSTEM_AUDIO_VOLUME_SAVED_VARIABLE_NAME L"SystemAudioVolumeSaved" - -/// -/// System audio volume in decibels, created by AppleHDA.kext. -/// UINT8: SystemAudioVolume' -/// gEfiAppleBootGuid -/// -#define APPLE_SYSTEM_AUDIO_VOLUME_SAVED_VARIABLE_DB_NAME L"SystemAudioVolumeDB" - -/// -/// System language. -/// String starting with language code (e.g. ru-RU:252). -/// gEfiAppleBootGuid -/// -#define APPLE_PREV_LANG_KBD_VARIABLE_NAME L"prev-lang:kbd" - -/// -/// Performance record data enable. -/// UINT8: Any value to enable performance gathering (one time). -/// gEfiAppleBootGuid -/// -#define APPLE_EFI_BOOT_PERF_VARIABLE_NAME L"efiboot-perf-record" - -/// -/// Performance record data address. -/// UINT32: Physical address to EfiACPIReclaimMemory containing perf data. -/// gEfiAppleBootGuid -/// -#define APPLE_EFI_BOOT_PERF_ADDRESS_VARIABLE_NAME L"efiboot-perf-record-data" - -/// -/// Performance record data size. -/// UINT32: Size of performance record data, usually 4096 bytes. -/// gEfiAppleBootGuid -/// -#define APPLE_EFI_BOOT_PERF_SIZE_VARIABLE_NAME L"efiboot-perf-record-data-size" - -/// -/// Hibernation wake log (mirror for APPLE_RTC_WAKE_LOG_ADDR). -/// UINT8[4]: Normally printed like 0x%02X 0x%02X % 3d 0x%02X. -/// gEfiAppleBootGuid -/// -#define APPLE_WAKE_FAILURE_VARIABLE_NAME L"wake-failure" - -/// -/// Force enable UEFI Windows support. -/// CHAR8: '1'. -/// gEfiAppleBootGuid -/// -#define APPLE_UEFI_WINDOWS_BOOT_CAPABLE_VARIABLE_NAME L"UEFIWindowsBootCapable" - -/// -/// Will install UEFI Windows on next reboot. -/// CHAR8: '1'. -/// gEfiAppleBootGuid -/// -#define APPLE_INSTALL_WINDOWS_UEFI_VARIABLE_NAME L"InstallWindowsUEFI" - -/// -/// 7-bit packed panic information. -/// Data blob from with indices in the range of [0000, 0400). -/// gEfiAppleBootGuid -/// -#define APPLE_PANIC_INFO_NO_VARIABLE_NAME L"AAPL,PanicInfo%04x" - -/// -/// BootCampt device path. -/// UEFI Device Path. -/// gEfiAppleBootGuid -/// -#define APPLE_BOOT_CAMP_HD_VARIABLE_NAME L"BootCampHD" - -/// -/// A global variable storing the GUID of the APPLE_VENDOR EFI variable scope. -/// -extern EFI_GUID gEfiAppleNvramGuid; - -/// -/// A global variable storing the GUID of the APPLE_BOOT EFI variable scope. -/// AKA gAppleEFINVRAMGuid -/// -extern EFI_GUID gEfiAppleBootGuid; - -/// -/// A global variable storing the GUID of the APPLE_CORE_STORAGE EFI variable -/// scope. -/// -extern EFI_GUID gAppleCoreStorageVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_TAMPER_RESISTANT_BOOT EFI -/// variable scope. -/// AKA gAppleEFINVRAMTRBStagingCommandGuid. -/// -extern EFI_GUID gAppleTamperResistantBootVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_WIRELESS_NETWORK EFI -/// variable scope. -/// -extern EFI_GUID gAppleWirelessNetworkVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_PERSONALIZATION EFI -/// variable scope. -/// -extern EFI_GUID gApplePersonalizationVariableGuid; - -/// -/// A global variable storing the GUID of -/// the APPLE_TAMPER_RESISTANT_BOOT_SECURE_VARIABLE_GUID EFI variable scope. -/// AKA gAppleEFINVRAMTRBSecureVariableGuid. -/// -extern EFI_GUID gAppleTamperResistantBootSecureVariableGuid; - -/// -/// A global variable storing the GUID of -/// the APPLE_TAMPER_RESISTANT_BOOT_EFI_USER_VARIABLE_GUID EFI variable scope. -/// -extern EFI_GUID gAppleTamperResistantBootEfiUserVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_NETBOOT EFI variable -/// scope. -/// -extern EFI_GUID gAppleNetbootVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_SECURITY EFI variable -/// scope. -/// -extern EFI_GUID gAppleSecurityVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_SECURE_BOOT_VARIABLE_GUID -/// EFI variable scope. -/// -extern EFI_GUID gAppleSecureBootVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_STARTUP_MANAGER variable scope. -/// -extern EFI_GUID gAppleStartupManagerVariableGuid; - -/// -/// A global variable storing the GUID of the APPLE_BACKUP_BOOT variable scope. -/// -extern EFI_GUID gAppleBackupBootVariableGuid; - -#endif // APPLE_VARIABLE_H diff --git a/Include/Guid/OcVariable.h b/Include/Guid/OcVariable.h deleted file mode 100644 index 142e67da6..000000000 --- a/Include/Guid/OcVariable.h +++ /dev/null @@ -1,121 +0,0 @@ -/** @file - Lilu & OpenCore specific GUIDs for UEFI Variable Storage, version 1.0. - -Copyright (c) 2019, vit9696. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_VARIABLE_H -#define OC_VARIABLE_H - -// -// Variable used for OpenCore log storage (if enabled). -// -#define OC_LOG_VARIABLE_NAME L"boot-log" - -// -// Variable used for OpenCore boot path (if enabled). -// -#define OC_LOG_VARIABLE_PATH L"boot-path" - -// -// Variable used for OpenCore request to redirect NVRAM Boot variable write. -// Boot Services only. -// See: https://github.com/acidanthera/bugtracker/issues/308. -// -#define OC_BOOT_REDIRECT_VARIABLE_NAME L"boot-redirect" - -// -// Variable used for exposing OpenCore Security -> LoadPolicy. -// Boot Services only. -// -#define OC_LOAD_POLICY_VARIABLE_NAME L"load-policy" - -// -// Variable used for exposing OpenCore Security -> ScanPolicy. -// Boot Services only. -// -#define OC_SCAN_POLICY_VARIABLE_NAME L"scan-policy" - -// -// Variable used to report boot protection. -// -#define OC_BOOT_PROTECT_VARIABLE_NAME L"boot-protect" - -// -// Boot protection guids. -// -#define OC_BOOT_PROTECT_VARIABLE_BOOTSTRAP BIT0 -#define OC_BOOT_PROTECT_VARIABLE_NAMESPACE BIT1 - -// -// Variable used to report OpenCore version in the following format: -// REL-001-2019-01-01. This follows versioning style of Lilu and plugins. -// -#define OC_VERSION_VARIABLE_NAME L"opencore-version" - -// -// Variable used to report OEM product from SMBIOS Type1 ProductName. -// -#define OC_OEM_PRODUCT_VARIABLE_NAME L"oem-product" - -// -// Variable used to report OEM board vendor from SMBIOS Type2 Manufacturer. -// -#define OC_OEM_VENDOR_VARIABLE_NAME L"oem-vendor" - -// -// Variable used to report OEM board vendor from SMBIOS Type2 ProductName. -// -#define OC_OEM_BOARD_VARIABLE_NAME L"oem-board" - -// -// Variable used to share CPU frequency calculated from ACPI between the drivers. -// -#define OC_ACPI_CPU_FREQUENCY_VARIABLE_NAME L"acpi-cpu-frequency" - -// -// Variable used to mark blacklisted RTC values. -// -#define OC_RTC_BLACKLIST_VARIABLE_NAME L"rtc-blacklist" - -// -// 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102 -// This GUID is specifically used for normal variable access by Lilu kernel extension and its plugins. -// -#define OC_VENDOR_VARIABLE_GUID \ - { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } } - -// -// E09B9297-7928-4440-9AAB-D1F8536FBF0A -// This GUID is specifically used for reading variables by Lilu kernel extension and its plugins. -// Any writes to this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES. -// The expected return code on variable write is EFI_SECURITY_VIOLATION. -// -#define OC_READ_ONLY_VARIABLE_GUID \ - { 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } } - -// -// F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1 -// This GUID is specifically used for reading variables by Lilu and plugins. -// Any reads from this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES. -// The expected return code on variable read is EFI_SECURITY_VIOLATION. -// -#define OC_WRITE_ONLY_VARIABLE_GUID \ - { 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } } - -// -// External global variables with GUID values. -// -extern EFI_GUID gOcVendorVariableGuid; -extern EFI_GUID gOcReadOnlyVariableGuid; -extern EFI_GUID gOcWriteOnlyVariableGuid; - -#endif // OC_VARIABLE_H diff --git a/Include/Guid/OcVariables.h b/Include/Guid/OcVariables.h deleted file mode 100644 index 43944fc87..000000000 --- a/Include/Guid/OcVariables.h +++ /dev/null @@ -1,85 +0,0 @@ -/** @file - Lilu & OpenCore specific GUIDs for UEFI Variable Storage, version 1.0. - -Copyright (c) 2019, vit9696. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_VARIABLES_H -#define OC_VARIABLES_H - -// -// Variable used for OpenCore log storage (if enabled). -// -#define OC_LOG_VARIABLE_NAME L"boot-log" - -// -// Variable used for OpenCore boot path (if enabled). -// -#define OC_LOG_VARIABLE_PATH L"boot-path" - -// -// Variable used for OpenCore request to redirect NVRAM Boot variable write. -// Boot Services only. -// See: https://github.com/acidanthera/bugtracker/issues/308. -// -#define OC_BOOT_REDIRECT_VARIABLE_NAME L"boot-redirect" - -// -// Variable used for exposing OpenCore Security -> LoadPolicy. -// Boot Services only. -// -#define OC_LOAD_POLICY_VARIABLE_NAME L"load-policy" - -// -// Variable used for exposing OpenCore Security -> ScanPolicy. -// Boot Services only. -// -#define OC_SCAN_POLICY_VARIABLE_NAME L"scan-policy" - -// -// Variable used to report OpenCore version in the following format: -// REL-001-2019-01-01. This follows versioning style of Lilu and plugins. -// -#define OC_VERSION_VARIABLE_NAME L"opencore-version" - -// -// 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102 -// This GUID is specifically used for normal variable access by Lilu kernel extension and its plugins. -// -#define OC_VENDOR_VARIABLE_GUID \ - { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } } - -// -// E09B9297-7928-4440-9AAB-D1F8536FBF0A -// This GUID is specifically used for reading variables by Lilu kernel extension and its plugins. -// Any writes to this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES. -// The expected return code on variable write is EFI_SECURITY_VIOLATION. -// -#define OC_READ_ONLY_VARIABLE_GUID \ - { 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } } - -// -// F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1 -// This GUID is specifically used for reading variables by Lilu and plugins. -// Any reads from this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES. -// The expected return code on variable read is EFI_SECURITY_VIOLATION. -// -#define OC_WRITE_ONLY_VARIABLE_GUID \ - { 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } } - -// -// External global variables with GUID values. -// -extern EFI_GUID gOcVendorVariableGuid; -extern EFI_GUID gOcReadOnlyVariableGuid; -extern EFI_GUID gOcWriteOnlyVariableGuid; - -#endif // OC_VARIABLES_H diff --git a/Include/IndustryStandard/AppleHid.h b/Include/IndustryStandard/AppleHid.h.disabled similarity index 99% rename from Include/IndustryStandard/AppleHid.h rename to Include/IndustryStandard/AppleHid.h.disabled index 3243e11bf..0d3814650 100644 --- a/Include/IndustryStandard/AppleHid.h +++ b/Include/IndustryStandard/AppleHid.h.disabled @@ -318,5 +318,7 @@ enum { // APPLE_KEY typedef APPLE_HID_USAGE APPLE_KEY; +typedef APPLE_HID_USAGE APPLE_KEY_CODE; + #endif // APPLE_HID_H_ diff --git a/Include/IndustryStandard/AppleMachoImage.h b/Include/IndustryStandard/AppleMachoImage.h.dis similarity index 100% rename from Include/IndustryStandard/AppleMachoImage.h rename to Include/IndustryStandard/AppleMachoImage.h.dis diff --git a/Include/Library/DeviceTreeLib.h b/Include/Library/DeviceTreeLib.h deleted file mode 100644 index 59869196f..000000000 --- a/Include/Library/DeviceTreeLib.h +++ /dev/null @@ -1,285 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_DEVICE_TREE_LIB_H -#define OC_DEVICE_TREE_LIB_H - -// -// Struct at the beginning of every loaded kext. -// Pointers to every loaded kext (to this struct) are -// properties Driver- in DevTree /chosen/memory-map. -// -typedef struct DTBooterKextFileInfo_ { - UINT32 InfoDictPhysAddr; - UINT32 InfoDictLength; - UINT32 ExecutablePhysAddr; - UINT32 ExecutableLength; - UINT32 BundlePathPhysAddr; - UINT32 BundlePathLength; -} DTBooterKextFileInfo; - -// -// DeviceTree MemoryMap entry structure. -// -typedef struct DTMemMapEntry_ { - UINT32 Address; - UINT32 Length; -} DTMemMapEntry; - -// -// Foundation Types. -// - -#define DT_PATH_NAME_SEPARATOR '/' //< 0x2F - -#define DT_MAX_PROPERTY_NAME_LENGTH 31 //< Max length of Property Name (terminator not included) -#define DT_MAX_ENTRY_NAME_LENGTH 31 //< Max length of a C-String Entry Name (terminator not included) -#define DT_PROPERTY_NAME_LENGTH 32 - -typedef CHAR8 DTEntryNameBuf[DT_PROPERTY_NAME_LENGTH]; //< Length of DTEntryNameBuf = DT_MAX_ENTRY_NAME_LENGTH + 1 - -typedef struct OpaqueDTEntry_ DeviceTreeNode; -typedef DeviceTreeNode *DTEntry; //< Entry - -typedef struct OpaqueDTProperty_ DTProperty; - -typedef struct DTSavedScope_ DTSavedScope; -typedef DTSavedScope *DTSavedScopePtr; - -typedef struct OpaqueDTEntryIterator_ OpaqueDTEntryIterator; -typedef OpaqueDTEntryIterator *DTEntryIterator; - -typedef struct OpaqueDTPropertyIterator_ OpaqueDTPropertyIterator; -typedef OpaqueDTPropertyIterator *DTPropertyIterator; - -//Old compatibility -typedef DTProperty DeviceTreeNodeProperty; - -// -// Structures for a Flattened Device Tree. -// - -struct OpaqueDTProperty_ { - CHAR8 Name[DT_PROPERTY_NAME_LENGTH]; //< NUL terminated property name - UINT32 Length; //< Length (bytes) of folloing prop value -}; - -struct OpaqueDTEntry_ { - UINT32 NumProperties; // Number of props[] elements (0 => end) - UINT32 NumChildren; // Number of children[] elements -}; - -// -// Entry. -// - -struct DTSavedScope_ { - DTSavedScopePtr NextScope; - DTEntry Scope; - DTEntry Entry; - UINT32 Index; -}; - -// -// Entry Iterator. -// -struct OpaqueDTEntryIterator_ { - DTEntry OuterScope; - DTEntry CurrentScope; - DTEntry CurrentEntry; - DTSavedScopePtr SavedScope; - UINT32 CurrentIndex; -}; - -// -// Property Iterator. -// -struct OpaqueDTPropertyIterator_ { - DTEntry Entry; - DTProperty *CurrentProperty; - UINT32 CurrentIndex; -}; - - -/** - Lookup Entry - Locates an entry given a specified subroot (searchPoint) and path name. If the - searchPoint pointer is NULL, the path name is assumed to be an absolute path - name rooted to the root of the device tree. -**/ -EFI_STATUS -DTLookupEntry ( - IN CONST DTEntry SearchPoint, - IN CONST CHAR8 *PathName, - IN DTEntry *FoundEntry - ); - -/** - An Entry Iterator maintains three variables that are of interest to clients. - First is an "OutermostScope" which defines the outer boundry of the iteration. - This is defined by the starting entry and includes that entry plus all of it's - embedded entries. Second is a "currentScope" which is the entry the iterator is - currently in. And third is a "currentPosition" which is the last entry returned - during an iteration. - - Create Entry Iterator - Create the iterator structure. The outermostScope and currentScope of the iterator - are set to "startEntry". If "startEntry" = NULL, the outermostScope and - currentScope are set to the root entry. The currentPosition for the iterator is - set to "nil". -**/ -EFI_STATUS -DTCreateEntryIterator ( - IN CONST DTEntry StartEntry, - IN DTEntryIterator *Iterator - ); - -/** - Dispose Entry Iterator -**/ -EFI_STATUS -DTDisposeEntryIterator ( - IN DTEntryIterator Iterator - ); - -/** - Enter Child Entry - Move an Entry Iterator into the scope of a specified child entry. The - currentScope of the iterator is set to the entry specified in "childEntry". If - "childEntry" is nil, the currentScope is set to the entry specified by the - currentPosition of the iterator. -**/ -EFI_STATUS -DTEnterEntry ( - IN DTEntryIterator Iterator, - IN DTEntry ChildEntry - ); - -/** - Exit to Parent Entry - Move an Entry Iterator out of the current entry back into the scope of it's parent - entry. The currentPosition of the iterator is reset to the current entry (the - previous currentScope), so the next iteration call will continue where it left off. - This position is returned in parameter "currentPosition". -**/ -EFI_STATUS -DTExitEntry ( - IN DTEntryIterator Iterator, - IN DTEntry *CurrentPosition - ); - -/** - Iterate Entries - Iterate and return entries contained within the entry defined by the current - scope of the iterator. Entries are returned one at a time. When - int == kIterationDone, all entries have been exhausted, and the - value of nextEntry will be Nil. -**/ -EFI_STATUS -DTIterateEntries ( - IN DTEntryIterator Iterator, - IN DTEntry *NextEntry - ); - -/** - Restart Entry Iteration - Restart an iteration within the current scope. The iterator is reset such that - iteration of the contents of the currentScope entry can be restarted. The - outermostScope and currentScope of the iterator are unchanged. The currentPosition - for the iterator is set to "nil". -**/ -EFI_STATUS -DTRestartEntryIteration ( - IN DTEntryIterator Iterator - ); - -/** - Get the value of the specified property for the specified entry. -**/ -EFI_STATUS -DTGetProperty( - IN CONST DTEntry Entry, - IN CHAR8 *PropertyName, - IN VOID **PropertyValue, - IN UINT32 *PropertySize - ); - -/** - Create Property Iterator - Create the property iterator structure. The target entry is defined by entry. -**/ -EFI_STATUS -DTCreatePropertyIterator ( - IN CONST DTEntry Entry, - IN DTPropertyIterator Iterator - ); - -/** - Iterate Properites - Iterate and return properties for given entry. - EFI_END_OF_MEDIA, all properties have been exhausted. -**/ - -EFI_STATUS -DTIterateProperties ( - IN DTPropertyIterator Iterator, - IN CHAR8 **FoundProperty - ); - -/** - Restart Property Iteration - Used to re-iterate over a list of properties. The Property Iterator is - reset to the beginning of the list of properties for an entry. -**/ -EFI_STATUS -DTRestartPropertyIteration ( - IN DTPropertyIterator Iterator - ); - -// -// Exported Functions -// - -/** - Used to initalize the device tree functions. - Base is the base address of the flatened device tree. -**/ -VOID -DTInit ( - IN VOID *Base, - IN UINT32 *Length - ); - -VOID -DumpDeviceTree ( - VOID - ); - -UINT32 -DTDeleteProperty ( - IN CHAR8 *NodeName, - IN CHAR8 *DeletePropertyName - ); - -VOID -DTInsertProperty ( - IN CHAR8 *NodeName, - IN CHAR8 *InsertPropertyName, - IN CHAR8 *AddPropertyName, - IN VOID *AddPropertyValue, - IN UINT32 ValueLength, - IN BOOLEAN InsertAfter OPTIONAL - ); - -#endif // OC_DEVICE_TREE_LIB_H diff --git a/Include/Library/OcAfterBootCompatLib.h b/Include/Library/OcAfterBootCompatLib.h deleted file mode 100644 index f288410f9..000000000 --- a/Include/Library/OcAfterBootCompatLib.h +++ /dev/null @@ -1,149 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_AFTER_BOOT_COMPAT_LIB_H -#define OC_AFTER_BOOT_COMPAT_LIB_H - -/** - Apple Boot Compatibility layer configuration. -**/ -typedef struct OC_ABC_SETTINGS_ { - /// - /// Protect from boot.efi from defragmenting runtime memory. This fixes UEFI runtime services - /// (date and time, NVRAM, power control, etc.) support on many firmwares. - /// Needed basically by everyone that uses SMM implementation of variable services. - /// - BOOLEAN AvoidRuntimeDefrag; //1 - /// - /// Setup virtual memory mapping after SetVirtualAddresses call. This fixes crashes in many - /// firmwares at early boot as they accidentally access virtual addresses after ExitBootServices. - /// - BOOLEAN SetupVirtualMap; //1 - /// - /// Provide custom Apple KASLR slide calculation for firmwares with polluted low memory ranges. - /// This also ensures that slide= argument is never passed to the operating system. - /// - BOOLEAN ProvideCustomSlide; //1 - /// - /// Provide max KASLR slide for firmwares with polluted higher memory ranges. - /// - UINT8 ProvideMaxSlide; //0 - /// - /// Remove runtime flag from MMIO areas and prevent virtual address assignment for known - /// MMIO regions. This may improve the amount of slides available, but may not work on - /// unknown configurations. - /// - BOOLEAN DevirtualiseMmio; //0 - /// - /// Disable passing -s to operating system through key presses, to simulate T2 Mac behaviour. - /// Ref: https://support.apple.com/HT201573 - /// - BOOLEAN DisableSingleUser; //0 - /// - /// Discard UEFI memory map after waking from hibernation and preserve the original mapping. - /// - BOOLEAN DiscardHibernateMap; //0 - /// - /// Try to patch Apple bootloader to have KASLR enabled even in SafeMode. - /// - BOOLEAN EnableSafeModeSlide; //1 - /// - /// Attempt to protect certain memory regions from being incorrectly mapped: - /// - CSM region could get used by the kernel due to being BS data, - /// which caused caused wake issues on older firmwares. - /// - MMIO regions can be marked as reserved memory and be thus unmapped, - /// which caused boot failures when accessing NVRAM. - /// - BOOLEAN ProtectMemoryRegions; //0 - /// - /// Rebuild memory map to be compatible with Apple kernel. - /// - Apply memory attributes and split RT entries into code and data. - /// - Reduce memory map entries through grouping to fit into 4KB. - /// - BOOLEAN RebuildAppleMemoryMap; //0 - /// - /// Ensure that ExitBootServices call succeeds even with outdated MemoryMap key. - /// - BOOLEAN ForceExitBootServices; //0 - /// - /// Disable NVRAM variable write support to protect from malware or to prevent - /// buggy NVRAM implementations cause system issues. - /// - BOOLEAN DisableVariableWrite; //0 - /// - /// Protect secure boot variables. - /// - BOOLEAN ProtectSecureBoot; //0 - /// - /// Permit writing to executable memory in UEFI runtime services. Fixes crashes - /// on many APTIO V firmwares. - /// - BOOLEAN EnableWriteUnprotector; //1 - /// - /// Signal OSInfo protocol that every loaded non-macOS OS is macOS. - /// Works around disabled IGPU in Windows and Linux on Apple laptops. - /// - BOOLEAN SignalAppleOS; //0 - /// - /// CoreImage may update and restore GetMemoryMap during loading (see InsertImageRecord) - /// as it needs this for segment splitting. Unfortunately it assumes nobody else - /// changes GetMemoryMap, and thus restores to its own CoreGetMemoryMap instead of - /// the previous value. Fix it here. - /// To make it worse VMware also replaces GetMemoryMap pointer in MacMisc, which CoreDxe - /// effectively trashes when we load drivers. As a result without this hack VMware Fusion - /// may show "Your Mac OS guest might run unreliably with more than one virtual core." - /// message when running OpenCore. - /// - BOOLEAN ProtectUefiServices; //0 - /// - /// Fix OpenRuntime permissions in the memory map and memory attributes. - /// - BOOLEAN SyncRuntimePermissions; //1 - /// - /// List of physical addresses to not be devirtualised by DevirtualiseMmio. - /// - EFI_PHYSICAL_ADDRESS *MmioWhitelist; //null - /// - /// Size of list of physical addresses to not be devirtualised by DevirtualiseMmio. - /// - UINTN MmioWhitelistSize; //0 - /// - /// List of NULL-terminated handlers for TPL_APPLICATION execution within ExitBootServices. - /// - EFI_EVENT_NOTIFY *ExitBootServicesHandlers; //null - /// - /// List of handler contexts for ExitBootServicesHandlers. - /// - VOID **ExitBootServicesHandlerContexts; //null - // - // labels for GUI for future - // - CHAR8 **MmioWhitelistLabels; //null - BOOLEAN *MmioWhitelistEnabled; //null -} OC_ABC_SETTINGS; - -/** - Initialize Apple Boot Compatibility layer. This layer is needed on partially - incompatible firmwares to prevent boot failure and UEFI services breakage. - - @param[in] Settings Compatibility layer configuration. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcAbcInitialize ( - IN OC_ABC_SETTINGS *Settings - ); - -#endif // OC_AFTER_BOOT_COMPAT_LIB_H diff --git a/Include/Library/OcAfterBootCompatLib4Clover.h b/Include/Library/OcAfterBootCompatLib4Clover.h new file mode 100644 index 000000000..fce1ce235 --- /dev/null +++ b/Include/Library/OcAfterBootCompatLib4Clover.h @@ -0,0 +1,43 @@ +/** @file + Copyright (C) 2019, vit9696. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#ifndef OC_AFTER_BOOT_COMPAT_LIB_4CLOVER_H +#define OC_AFTER_BOOT_COMPAT_LIB_4CLOVER_H + +#include +/** + Apple Boot Compatibility layer configuration. +**/ +typedef struct OC_ABC_SETTINGS_4CLOVER +{ + OC_ABC_SETTINGS OcAbcSettings; + + CHAR8 **MmioWhitelistLabels; //null + BOOLEAN *MmioWhitelistEnabled; //null +} OC_ABC_SETTINGS_4CLOVER; + +/** + Initialize Apple Boot Compatibility layer. This layer is needed on partially + incompatible firmwares to prevent boot failure and UEFI services breakage. + + @param[in] Settings Compatibility layer configuration. + + @retval EFI_SUCCESS on success. +**/ +//EFI_STATUS +//OcAbcInitialize ( +// IN OC_ABC_SETTINGS_4CLOVER *Settings +// ); + +#endif // OC_AFTER_BOOT_COMPAT_LIB_H diff --git a/Include/Library/OcAppleBootPolicyLib.h b/Include/Library/OcAppleBootPolicyLib.h deleted file mode 100755 index 2b4ad5f1a..000000000 --- a/Include/Library/OcAppleBootPolicyLib.h +++ /dev/null @@ -1,188 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_APPLE_BOOT_POLICY_LIB_H -#define OC_APPLE_BOOT_POLICY_LIB_H - -#include - -/** - Install and initialise Apple Boot policy protocol. - - @param[in] Reinstall Overwrite installed protocol. - - @retval installed or located protocol or NULL. -**/ -APPLE_BOOT_POLICY_PROTOCOL * -OcAppleBootPolicyInstallProtocol ( - IN BOOLEAN Reinstall - ); - -EFI_STATUS -OcGetBooterFromPredefinedPathList ( - IN EFI_HANDLE Device, - IN EFI_FILE_PROTOCOL *Root, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - IN CHAR16 *Prefix OPTIONAL - ); - -/** - Locates the bootable file of the given volume. Prefered are the values - blessed, though if unavailable, hard-coded names are being verified and used - if existing. - - The blessed paths are to be determined by the HFS Driver via - EFI_FILE_PROTOCOL.GetInfo(). The related identifier definitions are to be - found in AppleBless.h. - - @param[in] Device Thed device's Handle to perform the search on. - @param[in] PredefinedPaths An array of file paths to scan for if no file - was blessed. - @param[in] NumPredefinedPaths The number of paths in PredefinedPaths. - @param[out] FilePath A pointer to the device path pointer to set to - the file path of the boot file. - - @retval EFI_NOT_FOUND A bootable file could not be found on the given - volume. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval EFI_SUCCESS The operation completed successfully and the - BootFilePath Buffer has been filled. - @retval other The status of an operation used to complete - this operation is returned. -**/ -EFI_STATUS -OcBootPolicyGetBootFile ( - IN EFI_HANDLE Device, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -/** - Please refer to OcBootPolicyGetBootFile. This function extends the - functionality by supporting the APFS Preboot scheme. - - @param[in] Device Thed device's Handle to perform the search on. - @param[in] PredefinedPaths An array of file paths to scan for if no file - was blessed. - @param[in] NumPredefinedPaths The number of paths in PredefinedPaths. - @param[out] FilePath A pointer to the device path pointer to set to - the file path of the boot file. - - @retval EFI_NOT_FOUND A bootable file could not be found on the given - volume. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval EFI_SUCCESS The operation completed successfully and the - BootFilePath Buffer has been filled. - @retval other The status of an operation used to complete - this operation is returned. -**/ -EFI_STATUS -OcBootPolicyGetBootFileEx ( - IN EFI_HANDLE Device, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -/** - Retrieves information about DevicePath. - - @param[in] DevicePath The device path to describe. - @param[out] BootPathName A pointer into which the folder portion of - DevicePath is returned. - @param[out] Device A pointer into which the device handle of - DevicePath is returned. - - @retval EFI_SUCCESS The operation has been completed successfully. - @retval other DevicePath is not a valid file path. -**/ -EFI_STATUS -OcBootPolicyDevicePathToDirPath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device - ); - -/** - Retrieves path info for the APFS Recovery volume associated with the APFS - volume given by DevicePath. - - @param[in] DevicePath The device path to the APFS recovery volume. - @param[in] PathName The file path to open. - @param[in] PredefinedPaths An array of file paths to scan for if no file - was blessed. - @param[in] NumPredefinedPaths The number of paths in PredefinedPaths. - @param[out] FullPathName A pointer into which the full file path for - DevicePath and PathName is returned. - @param[out] Root A pointer into which the opened Recovery - volume root protocol is returned. - @param[out] DeviceHandle A pointer into which the device handle of - DevicePath is returned. - - @retval EFI_SUCCESS The operation has been completed successfully. - @retval EFI_NOT_FOUND The file path could not be found. - @retval other An unexpected error has occured. -**/ -EFI_STATUS -OcBootPolicyGetApfsRecoveryFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *PathName, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT CHAR16 **FullPathName, - OUT EFI_FILE_PROTOCOL **Root, - OUT EFI_HANDLE *DeviceHandle - ); - -/* - Retrieves all valid APFS Recovery instances on the system. - The APFS Recovery instance associated with the APFS volume referenced by - Handle is moved to index 0, if present. - - @param[in] Handle If given, the Recovery instance associated with - this handle is added first. - @param[out] Volumes A pointer the APFS Recovery instances info is - returned into. - @param[out] NumberOfEntries A pointer into which the number of entries in - Volumes is returned. - - @retval EFI_SUCCESS The operation has been completed successfully. - @retval EFI_NOT_FOUND No valid APFS Recovery instance could be found. - @retval other An unexpected error has occured. -*/ -EFI_STATUS -OcBootPolicyGetAllApfsRecoveryFilePath ( - IN EFI_HANDLE Handle OPTIONAL, - OUT VOID **Volumes, - OUT UINTN *NumberOfEntries - ); - -extern CONST CHAR16 *gAppleBootPolicyPredefinedPaths[]; - -/// -/// All Apple Boot Policy predefined booter paths. -/// -extern CONST UINTN gAppleBootPolicyNumPredefinedPaths; - -/// -/// Core Apple Boot Policy predefined booter paths. -/// -extern CONST UINTN gAppleBootPolicyCoreNumPredefinedPaths; - -#endif // OC_APPLE_BOOT_POLICY_LIB_H diff --git a/Include/Library/OcAppleChunklistLib.h b/Include/Library/OcAppleChunklistLib.h deleted file mode 100644 index 5b2b64103..000000000 --- a/Include/Library/OcAppleChunklistLib.h +++ /dev/null @@ -1,77 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef APPLE_CHUNKLIST_LIB_H -#define APPLE_CHUNKLIST_LIB_H - -#include - -#include -#include - -// -// Chunklist context. -// -typedef struct OC_APPLE_CHUNKLIST_CONTEXT_ { - UINTN ChunkCount; - CONST APPLE_CHUNKLIST_CHUNK *Chunks; - APPLE_CHUNKLIST_SIG *Signature; - UINT8 Hash[SHA256_DIGEST_SIZE]; -} OC_APPLE_CHUNKLIST_CONTEXT; - -// -// Chunklist functions. -// - -/** - Initializes a chunklist context. - - @param[out] Context The Context to initialize. - @param[in] Buffer A pointer to a buffer containing the chunklist data. - @param[in] BufferSize The size of the buffer specified in Buffer. - - @retval EFI_SUCCESS The Context was intialized successfully. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED The chunklist is unsupported. -**/ -BOOLEAN -OcAppleChunklistInitializeContext ( - OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN OUT VOID *Buffer, - IN UINT32 BufferSize - ); - -BOOLEAN -OcAppleChunklistVerifySignature ( - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN CONST OC_RSA_PUBLIC_KEY *PublicKey - ); - -/** - Verifies the specified data against a chunklist context. - - @param[in] Context The Context to verify against. - @param[in] ExtentTable A pointer to the RAM disk extent table to be - verified. - - @retval EFI_SUCCESS The data was verified successfully. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_END_OF_FILE The end of Buffer was reached. - @retval EFI_COMPROMISED_DATA The data failed verification. -**/ -BOOLEAN -OcAppleChunklistVerifyData ( - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable - ); - -#endif // APPLE_CHUNKLIST_LIB_H diff --git a/Include/Library/OcAppleDiskImageLib.h b/Include/Library/OcAppleDiskImageLib.h deleted file mode 100644 index bc5f0aa4c..000000000 --- a/Include/Library/OcAppleDiskImageLib.h +++ /dev/null @@ -1,85 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef APPLE_DISK_IMAGE_LIB_H_ -#define APPLE_DISK_IMAGE_LIB_H_ - -#include - -#include - -#include -#include - -// -// Disk image context. -// -typedef struct { - CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable; - - UINTN SectorCount; - - UINT32 BlockCount; - APPLE_DISK_IMAGE_BLOCK_DATA **Blocks; -} OC_APPLE_DISK_IMAGE_CONTEXT; - -BOOLEAN -OcAppleDiskImageInitializeContext ( - OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN FileSize - ); - -BOOLEAN -OcAppleDiskImageInitializeFromFile ( - OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN EFI_FILE_PROTOCOL *File - ); - -VOID -OcAppleDiskImageFreeContext ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context - ); -VOID -OcAppleDiskImageFreeFile ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context - ); - -BOOLEAN -OcAppleDiskImageVerifyData ( - IN OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *ChunklistContext - ); - -BOOLEAN -OcAppleDiskImageRead ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -EFI_HANDLE -OcAppleDiskImageInstallBlockIo ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN FileSize, - OUT CONST EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - OUT UINTN *DevicePathSize OPTIONAL - ); - -VOID -OcAppleDiskImageUninstallBlockIo ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN VOID *BlockIoHandle - ); - -#endif diff --git a/Include/Library/OcAppleKeyMapLib.h b/Include/Library/OcAppleKeyMapLib.h deleted file mode 100644 index 23d501e8a..000000000 --- a/Include/Library/OcAppleKeyMapLib.h +++ /dev/null @@ -1,100 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_APPLE_KEY_MAP_LIB_H -#define OC_APPLE_KEY_MAP_LIB_H - -#include -#include - -/** - Default buffer size for key map. -**/ -#define OC_KEY_MAP_DEFAULT_SIZE 8 -#define APPLE_KEY_CODE APPLE_KEY - -/** - Returns the previously install Apple Key Map Database protocol. - - @retval installed or located protocol or NULL -**/ -APPLE_KEY_MAP_DATABASE_PROTOCOL * -OcAppleKeyMapGetDatabase ( - VOID - ); - -/** - Install and initialise Apple Key Map protocols. - - @param[in] Reinstall Overwrite installed protocols. - - @retval installed or located protocol or NULL -**/ -APPLE_KEY_MAP_AGGREGATOR_PROTOCOL * -OcAppleKeyMapInstallProtocols ( - IN BOOLEAN Reinstall - ); - -/** - Checks whether or not a list of keys is contained within another. - - @param[in] Keys The reference keys. - @param[in] NumKeys The number of keys in Keys. - @param[in] CheckKeys The keys to locate in Keys. - @param[in] NumCheckKeys The number of keys in CheckKeys. - @param[in] ExactMatch Specifies whether matches must be exact. - - @returns Whether the reference keys contain the checked keys. - -**/ -BOOLEAN -OcKeyMapHasKeys ( - IN CONST APPLE_KEY_CODE *Keys, - IN UINTN NumKeys, - IN CONST APPLE_KEY_CODE *CheckKeys, - IN UINTN NumCheckKeys, - IN BOOLEAN ExactMatch - ); - -/** - Checks whether or not a KeyCode is contained within Keys. - - @param[in] Keys The reference keys. - @param[in] NumKeys The number of keys in Keys. - @param[in] KeyCode The key to locate in Keys. - - @returns Whether the reference keys contain the checked key. - -**/ -BOOLEAN -OcKeyMapHasKey ( - IN CONST APPLE_KEY_CODE *Keys, - IN UINTN NumKeys, - IN CONST APPLE_KEY_CODE KeyCode - ); - -/** - Performs keyboard input flush. - - @param[in] KeyMap Apple Key Map Aggregator protocol. - @param[in] Key Key to wait for removal or 0. - @param[in] FlushConsole Also flush console input. -**/ -VOID -OcKeyMapFlush ( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - IN APPLE_KEY_CODE Key, - IN BOOLEAN FlushConsole - ); - -#endif // OC_APPLE_KEY_MAP_LIB_H diff --git a/Include/Library/OcAppleKeysLib.h b/Include/Library/OcAppleKeysLib.h deleted file mode 100644 index a824f5745..000000000 --- a/Include/Library/OcAppleKeysLib.h +++ /dev/null @@ -1,33 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_APPLE_KEYS_LIB_H -#define OC_APPLE_KEYS_LIB_H - -#include -#include - -#define NUM_OF_PK 2 - -typedef struct APPLE_PK_ENTRY_ { - UINT8 Hash[SHA256_DIGEST_SIZE]; - CONST OC_RSA_PUBLIC_KEY *PublicKey; -} APPLE_PK_ENTRY; - -extern CONST APPLE_PK_ENTRY PkDataBase[NUM_OF_PK]; - -extern CONST UINT8 gAppleX86SecureBootRootCaCert[]; -extern CONST UINTN gAppleX86SecureBootRootCaCertSize; - -#endif // OC_APPLE_KEYS_LIB_H diff --git a/Include/Library/OcAppleRamDiskLib.h b/Include/Library/OcAppleRamDiskLib.h deleted file mode 100644 index 62dbbff42..000000000 --- a/Include/Library/OcAppleRamDiskLib.h +++ /dev/null @@ -1,97 +0,0 @@ -/** @file - Apple RAM Disk library. - -Copyright (C) 2019, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_APPLE_RAM_DISK_LIB_H -#define OC_APPLE_RAM_DISK_LIB_H - -#include -#include - -/** - Request allocation of Size bytes in extents table. - - @param[in] Size Requested memory size. - @param[in] MemoryType Requested memory type. - - @retval Allocated extent table. -**/ -CONST APPLE_RAM_DISK_EXTENT_TABLE * -OcAppleRamDiskAllocate ( - IN UINTN Size, - IN EFI_MEMORY_TYPE MemoryType - ); - -/** - Read RAM disk data. - - @param[in] ExtentTable Allocated extent table. - @param[in] Offset Offset in RAM disk. - @param[in] Size Amount of data to read. - @param[out] Buffer Resulting data. - - @retval TRUE on success. -**/ -BOOLEAN -OcAppleRamDiskRead ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN Offset, - IN UINTN Size, - OUT VOID *Buffer - ); - -/** - Write RAM disk data. - - @param[in] ExtentTable Allocated extent table. - @param[in] Offset Offset in RAM disk. - @param[in] Size Amount of data to write. - @param[in] Buffer Source data. - - @retval TRUE on success. -**/ -BOOLEAN -OcAppleRamDiskWrite ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN Offset, - IN UINTN Size, - IN CONST VOID *Buffer - ); - -/** - Load file into RAM disk as it is. - - @param[in] ExtentTable Allocated extent table. - @param[in] File File protocol open for reading. - @param[in] FileSize Amount of data to write. - - @retval TRUE on success. -**/ -BOOLEAN -OcAppleRamDiskLoadFile ( - IN OUT CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN EFI_FILE_PROTOCOL *File, - IN UINTN FileSize - ); - -/** - Free RAM disk. - - @param[in] ExtentTable Allocated extent table. -**/ -VOID -OcAppleRamDiskFree ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable - ); - -#endif // OC_APPLE_RAM_DISK_LIB_H diff --git a/Include/Library/OcBootManagementLib.h b/Include/Library/OcBootManagementLib.h deleted file mode 100755 index 4b2c3e7b3..000000000 --- a/Include/Library/OcBootManagementLib.h +++ /dev/null @@ -1,1240 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_BOOT_MANAGEMENT_LIB_H -#define OC_BOOT_MANAGEMENT_LIB_H - -#include -#include -#include -#include -#include -#include -//TODO this is AppleKeyState protocol -#include -#include -#include -#include - -/** - Primary picker context. -**/ -typedef struct OC_PICKER_CONTEXT_ OC_PICKER_CONTEXT; - -/** - Default strings for use in the interfaces. -**/ -#define OC_MENU_BOOT_MENU L"OpenCore Boot Menu" -#define OC_MENU_RESET_NVRAM_ENTRY L"Reset NVRAM" -#define OC_MENU_UEFI_SHELL_ENTRY L"UEFI Shell" -#define OC_MENU_PASSWORD_REQUEST L"Password: " -#define OC_MENU_PASSWORD_RETRY_LIMIT L"Password retry limit exceeded." -#define OC_MENU_CHOOSE_OS L"Choose the Operating System: " -#define OC_MENU_SHOW_AUXILIARY L"Show Auxiliary" -#define OC_MENU_RELOADING L"Reloading" -#define OC_MENU_TIMEOUT L"Timeout" -#define OC_MENU_OK L"OK" -#define OC_MENU_DISK_IMAGE L" (dmg)" -#define OC_MENU_EXTERNAL L" (external)" - -/** - Paths allowed to be accessible by the interfaces. -**/ -#define OPEN_CORE_IMAGE_PATH L"Resources\\Image\\" -#define OPEN_CORE_LABEL_PATH L"Resources\\Label\\" -#define OPEN_CORE_AUDIO_PATH L"Resources\\Audio\\" -#define OPEN_CORE_FONT_PATH L"Resources\\Font\\" - -/** - Attributes supported by the interfaces. -**/ -#define OC_ATTR_USE_VOLUME_ICON BIT0 -#define OC_ATTR_USE_DISK_LABEL_FILE BIT1 -#define OC_ATTR_USE_GENERIC_LABEL_IMAGE BIT2 -#define OC_ATTR_USE_ALTERNATE_ICONS BIT3 - -/** - Default timeout for IDLE timeout during menu picker navigation - before VoiceOver toggle. -**/ -#define OC_VOICE_OVER_IDLE_TIMEOUT_MS 700 ///< Experimental, less is problematic. - -/** - Default VoiceOver BeepGen protocol values. -**/ -#define OC_VOICE_OVER_SIGNAL_NORMAL_MS 200 ///< From boot.efi, constant. -#define OC_VOICE_OVER_SILENCE_NORMAL_MS 150 ///< From boot.efi, constant. -#define OC_VOICE_OVER_SIGNALS_NORMAL 1 ///< Username prompt or any input for boot.efi -#define OC_VOICE_OVER_SIGNALS_PASSWORD 2 ///< Password prompt for boot.efi -#define OC_VOICE_OVER_SIGNALS_PASSWORD_OK 3 ///< Password correct for boot.efi - -#define OC_VOICE_OVER_SIGNAL_ERROR_MS 1000 -#define OC_VOICE_OVER_SILENCE_ERROR_MS 150 -#define OC_VOICE_OVER_SIGNALS_ERROR 1 ///< Password verification error or boot failure. -#define OC_VOICE_OVER_SIGNALS_HWERROR 3 ///< Hardware error - -/** - Operating system boot type. - WARNING: This is only for debug purposes. -**/ -typedef UINT32 OC_BOOT_ENTRY_TYPE; - -#define OC_BOOT_UNKNOWN BIT0 -#define OC_BOOT_APPLE_OS BIT1 -#define OC_BOOT_APPLE_RECOVERY BIT2 -#define OC_BOOT_APPLE_TIME_MACHINE BIT3 -#define OC_BOOT_APPLE_FW_UPDATE BIT4 -#define OC_BOOT_APPLE_ANY (OC_BOOT_APPLE_OS | OC_BOOT_APPLE_RECOVERY | OC_BOOT_APPLE_TIME_MACHINE | OC_BOOT_APPLE_FW_UPDATE) -#define OC_BOOT_WINDOWS BIT5 -#define OC_BOOT_EXTERNAL_OS BIT6 -#define OC_BOOT_EXTERNAL_TOOL BIT7 -#define OC_BOOT_RESET_NVRAM BIT8 -#define OC_BOOT_SYSTEM (OC_BOOT_RESET_NVRAM) - -/** - Default boot option numbers. -**/ -#define OC_BOOT_OPTION 0x9696 -#define OC_BOOT_OPTION_VARIABLE_NAME L"Boot9696" - -/** - Picker mode. -**/ -typedef enum OC_PICKER_MODE_ { - OcPickerModeBuiltin, - OcPickerModeExternal, - OcPickerModeApple, -} OC_PICKER_MODE; - -/** - Action to perform as part of executing a system boot entry. -**/ -typedef -EFI_STATUS -(*OC_BOOT_SYSTEM_ACTION)( - VOID - ); - -/** - Discovered boot entry. - Note, inner resources must be freed with OcResetBootEntry. -**/ -typedef struct OC_BOOT_ENTRY_ { - // - // Link in entry list in OC_BOOT_FILESYSTEM. - // - LIST_ENTRY Link; - // - // Device path to booter or its directory. - // Can be NULL, for example, for custom or system entries. - // - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - // - // Action to perform on execution. Only valid for system entries. - // - OC_BOOT_SYSTEM_ACTION SystemAction; - // - // Obtained human visible name. - // - CHAR16 *Name; - // - // Obtained boot path directory. - // For custom entries this contains tool path. - // - CHAR16 *PathName; - // - // Heuristical value signalising about booted os. - // WARNING: This is only for debug purposes. - // - OC_BOOT_ENTRY_TYPE Type; - // - // Entry index number, assigned by picker. - // - UINT32 EntryIndex; - // - // Set when this entry is an externally available entry (e.g. USB). - // - BOOLEAN IsExternal; - // - // Should try booting from first dmg found in DevicePath. - // - BOOLEAN IsFolder; - // - // Set when this entry refers to a generic booter (e.g. BOOTx64.EFI). - // - BOOLEAN IsGeneric; - // - // Should make this option default boot option. - // - BOOLEAN SetDefault; - // - // Load option data (usually "boot args") size. - // - UINT32 LoadOptionsSize; - // - // Load option data (usually "boot args"). - // - VOID *LoadOptions; -} OC_BOOT_ENTRY; - -/** - Boot filesystem containing boot entries. -**/ -typedef struct OC_BOOT_FILESYSTEM_ OC_BOOT_FILESYSTEM; -struct OC_BOOT_FILESYSTEM_ { - // - // Link in filesystem list in OC_BOOT_CONTEXT. - // - LIST_ENTRY Link; - // - // Filesystem handle. - // - EFI_HANDLE Handle; - // - // List of boot entries (OC_BOOT_ENTRY). - // - LIST_ENTRY BootEntries; - // - // Pointer to APFS Recovery partition (if any). - // - OC_BOOT_FILESYSTEM *RecoveryFs; - // - // External filesystem. - // - BOOLEAN External; - // - // Loader filesystem. - // - BOOLEAN LoaderFs; - // - // Contains recovery on the filesystem. - // - BOOLEAN HasSelfRecovery; -}; - -/** - Boot context containing boot filesystems. -**/ -typedef struct OC_BOOT_CONTEXT_ { - // - // Total boot entry count. - // - UINTN BootEntryCount; - // - // Total filesystem count. - // - UINTN FileSystemCount; - // - // List of filesystems containing boot entries (OC_BOOT_FILESYSTEM). - // - LIST_ENTRY FileSystems; - // - // GUID namespace for boot entries. - // - EFI_GUID *BootVariableGuid; - // - // Default entry to be booted. - // - OC_BOOT_ENTRY *DefaultEntry; - // - // Picker context for externally configured parameters. - // - OC_PICKER_CONTEXT *PickerContext; -} OC_BOOT_CONTEXT; - -/** - Perform filtering based on file system basis. - Ignores all filesystems by default. - Remove this bit to allow any file system. -**/ -#define OC_SCAN_FILE_SYSTEM_LOCK BIT0 - -/** - Perform filtering based on device basis. - Ignores all devices by default. - Remove this bit to allow any device type. -**/ -#define OC_SCAN_DEVICE_LOCK BIT1 - -/** - Allow scanning APFS filesystems. -**/ -#define OC_SCAN_ALLOW_FS_APFS BIT8 - -/** - Allow scanning HFS filesystems. -**/ -#define OC_SCAN_ALLOW_FS_HFS BIT9 - -/** - Allow scanning ESP filesystems. -**/ -#define OC_SCAN_ALLOW_FS_ESP BIT10 - -/** - Allow scanning NTFS filesystems. -**/ -#define OC_SCAN_ALLOW_FS_NTFS BIT11 - -/** - Allow scanning EXT filesystems (e.g. EXT4). -**/ -#define OC_SCAN_ALLOW_FS_EXT BIT12 - -/** - Allow scanning SATA devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_SATA BIT16 - -/** - Allow scanning SAS and Mac NVMe devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_SASEX BIT17 - -/** - Allow scanning SCSI devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_SCSI BIT18 - -/** - Allow scanning NVMe devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_NVME BIT19 - -/** - Allow scanning ATAPI devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_ATAPI BIT20 - -/** - Allow scanning USB devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_USB BIT21 - -/** - Allow scanning FireWire devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_FIREWIRE BIT22 - -/** - Allow scanning SD card devices. -**/ -#define OC_SCAN_ALLOW_DEVICE_SDCARD BIT23 - -/** - Allow scanning PCI devices (e.g. virtio). -**/ -#define OC_SCAN_ALLOW_DEVICE_PCI BIT24 - -/** - All device bits used by OC_SCAN_DEVICE_LOCK. -**/ -#define OC_SCAN_DEVICE_BITS ( \ - OC_SCAN_ALLOW_DEVICE_SATA | OC_SCAN_ALLOW_DEVICE_SASEX | \ - OC_SCAN_ALLOW_DEVICE_SCSI | OC_SCAN_ALLOW_DEVICE_NVME | \ - OC_SCAN_ALLOW_DEVICE_ATAPI | OC_SCAN_ALLOW_DEVICE_USB | \ - OC_SCAN_ALLOW_DEVICE_FIREWIRE | OC_SCAN_ALLOW_DEVICE_SDCARD | \ - OC_SCAN_ALLOW_DEVICE_PCI) - -/** - All device bits used by OC_SCAN_DEVICE_LOCK. -**/ -#define OC_SCAN_FILE_SYSTEM_BITS ( \ - OC_SCAN_ALLOW_FS_APFS | OC_SCAN_ALLOW_FS_HFS | OC_SCAN_ALLOW_FS_ESP | \ - OC_SCAN_ALLOW_FS_NTFS | OC_SCAN_ALLOW_FS_EXT) - -/** - By default allow booting from APFS from internal drives. -**/ -#define OC_SCAN_DEFAULT_POLICY ( \ - OC_SCAN_FILE_SYSTEM_LOCK | OC_SCAN_DEVICE_LOCK | \ - OC_SCAN_ALLOW_FS_APFS | \ - OC_SCAN_ALLOW_DEVICE_SATA | OC_SCAN_ALLOW_DEVICE_SASEX | \ - OC_SCAN_ALLOW_DEVICE_SCSI | OC_SCAN_ALLOW_DEVICE_NVME | \ - OC_SCAN_ALLOW_DEVICE_PCI) - -/** - OcLoadBootEntry Mode policy bits allow to configure OcLoadBootEntry behaviour. -**/ - -/** - Thin EFI image loading (normal PE) is allowed. -**/ -#define OC_LOAD_ALLOW_EFI_THIN_BOOT BIT0 -/** - FAT EFI image loading (Apple FAT PE) is allowed. - These can be found on macOS 10.8 and below. -**/ -#define OC_LOAD_ALLOW_EFI_FAT_BOOT BIT1 -/** - One level recursion into dmg file is allowed. - It is assumed that dmg contains a single volume and a single blessed entry. - Loading dmg from dmg is not allowed in any case. -**/ -#define OC_LOAD_ALLOW_DMG_BOOT BIT2 -/** - Abort loading on invalid Apple-like signature. - If file is signed with Apple-like signature, and it is mismatched, then abort. - @warn Unsigned files or UEFI-signed files will skip this check. - @warn It is ignored what certificate was used for signing. -**/ -#define OC_LOAD_VERIFY_APPLE_SIGN BIT8 -/** - Abort loading on missing Apple-like signature. - If file is not signed with Apple-like signature (valid or not) then abort. - @warn Unsigned files or UEFI-signed files will not load with this check. - @warn Without OC_LOAD_VERIFY_APPLE_SIGN corrupted binaries may still load. -**/ -#define OC_LOAD_REQUIRE_APPLE_SIGN BIT9 -/** - Abort loading on untrusted key (otherwise may warn). - @warn Unsigned files or UEFI-signed files will skip this check. -**/ -#define OC_LOAD_REQUIRE_TRUSTED_KEY BIT10 -/** - Trust specified (as OcLoadBootEntry argument) custom keys. -**/ -#define OC_LOAD_TRUST_CUSTOM_KEY BIT16 -/** - Trust Apple CFFD3E6B public key. - TODO: Move certificates from ApplePublicKeyDb.h to EfiPkg? -**/ -#define OC_LOAD_TRUST_APPLE_V1_KEY BIT17 -/** - Trust Apple E50AC288 public key. - TODO: Move certificates from ApplePublicKeyDb.h to EfiPkg? -**/ -#define OC_LOAD_TRUST_APPLE_V2_KEY BIT18 -/** - Default moderate policy meant to augment secure boot facilities. - Loads almost everything and bypasses secure boot for Apple and Custom signed binaries. -**/ -#define OC_LOAD_DEFAULT_POLICY ( \ - OC_LOAD_ALLOW_EFI_THIN_BOOT | OC_LOAD_ALLOW_DMG_BOOT | OC_LOAD_REQUIRE_APPLE_SIGN | \ - OC_LOAD_VERIFY_APPLE_SIGN | OC_LOAD_REQUIRE_TRUSTED_KEY | \ - OC_LOAD_TRUST_CUSTOM_KEY | OC_LOAD_TRUST_APPLE_V1_KEY | OC_LOAD_TRUST_APPLE_V2_KEY) - -/** - Exposed start interface with chosen boot entry but otherwise equivalent - to EFI_BOOT_SERVICES StartImage. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_IMAGE_START) ( - IN OC_BOOT_ENTRY *ChosenEntry, - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ); - -/** - Exposed custom entry load interface. - Returns allocated file buffer from pool on success. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_CUSTOM_READ) ( - IN VOID *Context, - IN OC_BOOT_ENTRY *ChosenEntry, - OUT VOID **Data, - OUT UINT32 *DataSize, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - OUT EFI_HANDLE *ParentDeviceHandle OPTIONAL, - OUT EFI_DEVICE_PATH_PROTOCOL **ParentFilePath OPTIONAL - ); - -/** - Exposed custom entry describe interface. - Return allocated file buffers from pool on success. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_CUSTOM_DESCRIBE) ( - IN VOID *Context, - IN OC_BOOT_ENTRY *ChosenEntry, - IN UINT8 LabelScale OPTIONAL, - OUT VOID **IconData OPTIONAL, - OUT UINT32 *IconDataSize OPTIONAL, - OUT VOID **LabelData OPTIONAL, - OUT UINT32 *LabelDataSize OPTIONAL - ); - -/** - Custom picker entry. -**/ -typedef struct { - // - // Entry name. - // - CONST CHAR8 *Name; - // - // Entry path. - // - CONST CHAR8 *Path; - // - // Entry boot arguments. - // - CONST CHAR8 *Arguments; - // - // Whether this entry is auxiliary. - // - BOOLEAN Auxiliary; - // - // Whether this entry is a tool. - // - BOOLEAN Tool; -} OC_PICKER_ENTRY; - -/** - Privilege levels to escalate to -**/ -typedef enum { - OcPrivilegeUnauthorized = 0, - OcPrivilegeAuthorized = 1 -} OC_PRIVILEGE_LEVEL; - -/** - Request a privilege escalation, for example by prompting for a password. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_REQ_PRIVILEGE)( - IN OC_PICKER_CONTEXT *Context, - IN OC_PRIVILEGE_LEVEL Level - ); - -/** - Display entries onscreen. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_SHOW_MENU) ( - IN OC_BOOT_CONTEXT *BootContext, - IN OC_BOOT_ENTRY **BootEntries, - OUT OC_BOOT_ENTRY **ChosenBootEntry - ); - -/** - Picker behaviour action. -**/ -typedef enum { - OcPickerDefault = 0, - OcPickerShowPicker = 1, - OcPickerResetNvram = 2, - OcPickerBootApple = 3, - OcPickerBootAppleRecovery = 4, -} OC_PICKER_CMD; - -/** - Boot picker context describing picker behaviour. -**/ -struct OC_PICKER_CONTEXT_ { - // - // Scan policy (e.g. OC_SCAN_DEFAULT_POLICY). - // - UINT32 ScanPolicy; - // - // Load policy (e.g. OC_LOAD_DEFAULT_POLICY). - // - UINT32 LoadPolicy; - // - // Default entry selection timeout (pass 0 to ignore). - // - UINT32 TimeoutSeconds; - // - // Default delay prior to handling hotkeys (pass 0 to ignore). - // - UINT32 TakeoffDelay; - // - // Define picker behaviour. - // For example, show boot menu or just boot the default option. - // - OC_PICKER_CMD PickerCommand; - // - // Use custom (gOcVendorVariableGuid) for Boot#### variables. - // - BOOLEAN CustomBootGuid; - // - // Custom entry reading routine, optional for no custom entries. - // - OC_CUSTOM_READ CustomRead; - // - // Custom entry describing routine, optional for no custom entries. - // - OC_CUSTOM_DESCRIBE CustomDescribe; - // - // Context to pass to CustomRead and CustomDescribe, optional. - // - VOID *CustomEntryContext; - // - // Image starting routine used, required. - // - OC_IMAGE_START StartImage; - // - // Handle to perform loader detection, optional. - // - EFI_HANDLE LoaderHandle; - // - // Entry display routine. - // - OC_SHOW_MENU ShowMenu; - // - // Privilege escalation requesting routine. - // - OC_REQ_PRIVILEGE RequestPrivilege; - // - // Context to pass to RequestPrivilege, optional. - // - VOID *PrivilegeContext; - // - // Additional suffix to include by the interface. - // - CONST CHAR8 *TitleSuffix; - // - // Used picker mode. - // - OC_PICKER_MODE PickerMode; - // - // Console attributes. 0 is reserved as disabled. - // - UINT32 ConsoleAttributes; - // - // Picker attribues: - // - BIT0~BIT15 are OpenCore reserved. - // - BIT16~BIT31 are OEM-specific. - // - UINT32 PickerAttributes; - // - // Enable polling boot arguments. - // - BOOLEAN PollAppleHotKeys; - // - // Append the "Reset NVRAM" option to the boot entry list. - // - BOOLEAN ShowNvramReset; - // - // Allow setting default boot option from boot menu. - // - BOOLEAN AllowSetDefault; - // - // Hide and do not scan auxiliary entries. - // - BOOLEAN HideAuxiliary; - // - // Enable audio assistant during picker playback. - // - BOOLEAN PickerAudioAssist; - // - // Set when Apple picker cannot be used on this system. - // - BOOLEAN ApplePickerUnsupported; - // - // Recommended audio protocol, optional. - // - OC_AUDIO_PROTOCOL *OcAudio; - // - // Recommended beeper protocol, optional. - // - APPLE_BEEP_GEN_PROTOCOL *BeepGen; - // - // Custom boot order updated during scanning allocated from pool. - // Preserved here to avoid situations with losing BootNext on rescan. - // - UINT16 *BootOrder; - // - // Number of entries in boot order. - // - UINTN BootOrderCount; - // - // Additional boot arguments for Apple loaders. - // - CHAR8 AppleBootArgs[BOOT_LINE_LENGTH]; - // - // Number of custom boot paths (bless override). - // - UINTN NumCustomBootPaths; - // - // Custom boot paths (bless override). Must start with '\'. - // - CHAR16 **CustomBootPaths; - // - // Number of absolute custom entries. - // - UINT32 AbsoluteEntryCount; - // - // Number of total custom entries (absolute and tools). - // - UINT32 AllCustomEntryCount; - // - // Custom picker entries. Absolute entries come first. - // - OC_PICKER_ENTRY CustomEntries[]; -}; - -/** - Hibernate detection bit mask for hibernate source usage. -**/ -#define HIBERNATE_MODE_NONE 0U -#define HIBERNATE_MODE_RTC 1U -#define HIBERNATE_MODE_NVRAM 2U - -/** - Get '.disk_label' or '.disk_label_2x' file contents, if exists. - - @param[in] BootEntry Located boot entry. - @param[in] Scale User interface scale. - @param[out] ImageData File contents. - @param[out] DataLength File length. - - @retval EFI_SUCCESS The file was read successfully. -**/ -EFI_STATUS -OcGetBootEntryLabelImage ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN UINT8 Scale, - OUT VOID **ImageData, - OUT UINT32 *DataLength - ); - -/** - Get '.VolumeIcon.icns' file contents, if exists. - - @param[in] BootEntry Located boot entry. - @param[out] ImageData File contents. - @param[out] DataLength File length. - - @retval EFI_SUCCESS The file was read successfully. -**/ -EFI_STATUS -OcGetBootEntryIcon ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - OUT VOID **ImageData, - OUT UINT32 *DataLength - ); - -/** - Scan system for boot entries. - - @param[in] Context Picker context. - - @retval boot context allocated from pool. -**/ -OC_BOOT_CONTEXT * -OcScanForBootEntries ( - IN OC_PICKER_CONTEXT *Context - ); - -/** - Scan system for first entry to boot. - This is likely to return an incomplete list and can even give NULL, - when only tools and system entries are present. - - @param[in] Context Picker context. - - @retval boot context allocated from pool. -**/ -OC_BOOT_CONTEXT * -OcScanForDefaultBootEntry ( - IN OC_PICKER_CONTEXT *Context - ); - -/** - Perform boot entry enumeration. - - @param[in] BootContext Boot context. - - @retval enumerated boot entry list allocated from pool. -**/ -OC_BOOT_ENTRY ** -OcEnumerateEntries ( - IN OC_BOOT_CONTEXT *BootContext - ); - -/** - Free boot context. - - @param[in,out] Context Boot context to free. -**/ -VOID -OcFreeBootContext ( - IN OUT OC_BOOT_CONTEXT *Context - ); - -/** - Obtain default entry from picker context. - - @param[in] Context Picker context. - @param[in,out] BootEntries Described list of entries, may get updated. - @param[in] NumBootEntries Positive number of boot entries. - - @retval boot entry or 0. -**/ -UINT32 -OcGetDefaultBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OUT OC_BOOT_ENTRY *BootEntries, - IN UINTN NumBootEntries - ); - -/** - Set default entry to passed entry. - - @param[in] Context Picker context. - @param[in,out] Entry Entry to make default. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcSetDefaultBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *Entry - ); - -typedef struct { - OC_PRIVILEGE_LEVEL CurrentLevel; - CONST UINT8 *Salt; - UINT32 SaltSize; - CONST UINT8 *Hash; -} OC_PRIVILEGE_CONTEXT; - -/** - Show simple password prompt and return verification status. - - @param[in] Context Picker context. - @param[in] Level The privilege level to request escalating to. - - @retval EFI_SUCCESS The privilege level has been escalated successfully. - @retval EFI_ABORTED The privilege escalation has been aborted. - @retval other The system must be considered compromised. - -**/ -EFI_STATUS -EFIAPI -OcShowSimplePasswordRequest ( - IN OC_PICKER_CONTEXT *Context, - IN OC_PRIVILEGE_LEVEL Level - ); - -/** - Show simple boot entry selection menu and return chosen entry. - - @param[in] BootContext Boot context. - @param[in] BootEntries Enumerated entries. - @param[in] ChosenBootEntry Chosen boot entry from BootEntries on success. - - @retval EFI_SUCCESS Executed successfully and picked up an entry. - @retval EFI_ABORTED When the user chose to by pressing Esc or 0. -**/ -EFI_STATUS -EFIAPI -OcShowSimpleBootMenu ( - IN OC_BOOT_CONTEXT *BootContext, - IN OC_BOOT_ENTRY **BootEntries, - OUT OC_BOOT_ENTRY **ChosenBootEntry - ); - -/** - Load & start boot entry loader image with given options. - - @param[in] Context Picker context. - @param[in] BootEntry Located boot entry. - @param[in] ParentHandle Parent image handle. - - @retval EFI_SUCCESS The image was found, started, and ended succesfully. -**/ -EFI_STATUS -OcLoadBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN EFI_HANDLE ParentHandle - ); - -/** - Handle hibernation detection for later loading. - - @param[in] HibernateMask Hibernate detection mask. - - @retval EFI_SUCCESS Hibernation mode was found and activated. -**/ -EFI_STATUS -OcActivateHibernateWake ( - IN UINT32 HibernateMask - ); - -/** - Read and expand Apple panic log if present. - - @param[out] PanicSize Size of the panic log on success. - - @retval panic buffer on success. - @retval NULL on failure. -**/ -VOID * -OcReadApplePanicLog ( - OUT UINT32 *PanicSize - ); - -/** - Check if active hibernation is happening. - - @retval TRUE on waking from hibernation. -**/ -BOOLEAN -OcIsAppleHibernateWake ( - VOID - ); - -/** - Check pressed hotkeys and update booter context based on this. - - @param[in,out] Context Picker context. -**/ -VOID -OcLoadPickerHotKeys ( - IN OUT OC_PICKER_CONTEXT *Context - ); - -/** - Default index mapping macros. -**/ -#define OC_INPUT_STR "123456789ABCDEFGHIJKLMNOPQRSTUVXWZ" -#define OC_INPUT_MAX L_STR_LEN (OC_INPUT_STR) -#define OC_INPUT_ABORTED -1 ///< Esc or 0 -#define OC_INPUT_INVALID -2 ///< Some other key -#define OC_INPUT_TIMEOUT -3 ///< Timeout -#define OC_INPUT_CONTINUE -4 ///< Continue (press enter) -#define OC_INPUT_UP -5 ///< Move up -#define OC_INPUT_DOWN -6 ///< Move down -#define OC_INPUT_LEFT -7 ///< Move left -#define OC_INPUT_RIGHT -8 ///< Move right -#define OC_INPUT_TOP -9 ///< Move to top -#define OC_INPUT_BOTTOM -10 ///< Move to bottom -#define OC_INPUT_MORE -11 ///< Show more entries (press space) -#define OC_INPUT_VOICE_OVER -12 ///< Toggle VoiceOver (press CMD+F5) -#define OC_INPUT_INTERNAL -13 ///< Accepted internal hotkey (e.g. Apple) -#define OC_INPUT_FUNCTIONAL(x) (-20 - (x)) ///< Functional hotkeys - -/** - Obtains key index from user input. - - @param[in,out] Context Picker context. - @param[in] KeyMap Apple Key Map Aggregator protocol. - @param[out] SetDefault Set boot option as default, optional. - - @returns key index [0, OC_INPUT_MAX) or OC_INPUT_* value. - @returns OC_INPUT_TIMEOUT when no key is pressed. - @returns OC_INPUT_INVALID when unknown key is pressed. -**/ -INTN -OcGetAppleKeyIndex ( - IN OUT OC_PICKER_CONTEXT *Context, - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - OUT BOOLEAN *SetDefault OPTIONAL - ); - -/** - Waits for key index from user input. - - @param[in,out] Context Picker context. - @param[in] KeyMap Apple Key Map Aggregator protocol. - @param[in] Timeout Timeout to wait for in milliseconds. - @param[out] SetDefault Set boot option as default, optional. - - @returns key index [0, OC_INPUT_MAX) or OC_INPUT_* value. -**/ -INTN -OcWaitForAppleKeyIndex ( - IN OUT OC_PICKER_CONTEXT *Context, - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - IN UINTN Timeout, - OUT BOOLEAN *SetDefault OPTIONAL - ); - -/** - Install missing boot policy, scan, and show simple boot menu. - - @param[in] Context Picker context. - - @retval does not return unless a fatal error happened. -**/ -EFI_STATUS -OcRunBootPicker ( - IN OC_PICKER_CONTEXT *Context - ); - -/** - Get device scan policy type. - - @param[in] Handle Device/partition handle. - @param[out] External Check whether device is external. - - @retval required policy or 0 on mismatch. -**/ -UINT32 -OcGetDevicePolicyType ( - IN EFI_HANDLE Handle, - OUT BOOLEAN *External OPTIONAL - ); - -/** - Get file system scan policy type. - - @param[in] Handle Partition handle. - - @retval required policy or 0 on mismatch. -**/ -UINT32 -OcGetFileSystemPolicyType ( - IN EFI_HANDLE Handle - ); - -/** - Check if supplied device path contains known names (e.g. Apple bootloader). - - @param[in] DevicePath Device path. - @param[out] IsFolder Device path represents directory, optional. - @param[out] IsGeneric Device path represents generic booter, optional. - - @retval entry type for potentially known bootloaders. - @retval OC_BOOT_UNKNOWN for unknown bootloaders. -**/ -OC_BOOT_ENTRY_TYPE -OcGetBootDevicePathType ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT BOOLEAN *IsFolder OPTIONAL, - OUT BOOLEAN *IsGeneric OPTIONAL - ); - -/** - Get loaded image protocol for Apple bootloader. - - @param[in] ImageHandle Image handle. - - @retval loaded image protocol or NULL for non Apple images. -**/ -EFI_LOADED_IMAGE_PROTOCOL * -OcGetAppleBootLoadedImage ( - IN EFI_HANDLE ImageHandle - ); - -/** - Unified structure to hold macOS kernel boot arguments to make the code - independent of their format version. Several values need changing - by other libraries, so values are often pointers to original fields. -**/ -typedef struct OC_BOOT_ARGUMENTS_ { - UINT32 *MemoryMap; - UINT32 *MemoryMapSize; - UINT32 *MemoryMapDescriptorSize; - UINT32 *MemoryMapDescriptorVersion; - CHAR8 *CommandLine; - UINT32 *DeviceTreeP; - UINT32 *DeviceTreeLength; - UINT32 *CsrActiveConfig; - EFI_SYSTEM_TABLE *SystemTable; -} OC_BOOT_ARGUMENTS; - -/** - Parse macOS kernel into unified boot arguments structure. - - @param[out] Arguments Unified boot arguments structure. - @param[in] BootArgs Kernel boot arguments strucutre. -**/ -VOID -OcParseBootArgs ( - OUT OC_BOOT_ARGUMENTS *Arguments, - IN VOID *BootArgs - ); - -/** - Check if boot argument is currently passed (via image options or NVRAM). - - @param[in] LoadedImage UEFI loaded image protocol instance, optional. - @param[in] GetVariable Preferred UEFI NVRAM reader, optional. - @param[in] Argument Argument, e.g. -v, slide=, debug=, etc. - @param[in] ArgumentLength Argument length, e.g. L_STR_LEN ("-v"). - - @retval TRUE if argument is present. -**/ -BOOLEAN -OcCheckArgumentFromEnv ( - IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL, - IN EFI_GET_VARIABLE GetVariable OPTIONAL, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ); - -/** - Get argument value from command line. - - @param[in] CommandLine Argument command line, e.g. for boot.efi. - @param[in] Argument Argument, e.g. -v, slide=, debug=, etc. - @param[in] ArgumentLength Argument length, e.g. L_STR_LEN ("-v"). - - @retval pointer to argument value or NULL. -**/ -CONST CHAR8 * -OcGetArgumentFromCmd ( - IN CONST CHAR8 *CommandLine, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ); - -/** - Remove argument from command line if present. - - @param[in,out] CommandLine Argument command line, e.g. for boot.efi. - @param[in] Argument Argument, e.g. -v, slide=, debug=, etc. -**/ -VOID -OcRemoveArgumentFromCmd ( - IN OUT CHAR8 *CommandLine, - IN CONST CHAR8 *Argument - ); - -/** - Append argument to command line without deduplication. - - @param[in,out] Context Picker context. NULL, if a privilege escalation is not required. - @param[in,out] CommandLine Argument command line of BOOT_LINE_LENGTH bytes. - @param[in] Argument Argument, e.g. -v, slide=0, debug=0x100, etc. - @param[in] ArgumentLength Argument length, e.g. L_STR_LEN ("-v"). - - @retval TRUE on success. -**/ -BOOLEAN -OcAppendArgumentToCmd ( - IN OUT OC_PICKER_CONTEXT *Context OPTIONAL, - IN OUT CHAR8 *CommandLine, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ); - -/** - Perform NVRAM UEFI variable deletion. -**/ -VOID -OcDeleteVariables ( - VOID - ); - -/** - Launch Apple BootPicker. - - @retval error code, should not return. -**/ -EFI_STATUS -OcRunAppleBootPicker ( - VOID - ); - -/** - Play audio file for context. - - @param[in] Context Picker context. - @param[in] File File to play. - @param[in] Fallback Try to fallback to beeps on failure. - - @retval EFI_SUCCESS on success or when unnecessary. -**/ -EFI_STATUS -OcPlayAudioFile ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 File, - IN BOOLEAN Fallback - ); - -/** - Generate cycles of beep signals for context with silence afterwards, blocking. - - @param[in] Context Picker context. - @param[in] ToneCount Number of signals to produce. - @param[in] ToneLength Signal length in milliseconds. - @param[in] SilenceLength Silence length in milliseconds. - - @retval EFI_SUCCESS on success or when unnecessary. -**/ -EFI_STATUS -OcPlayAudioBeep ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 ToneCount, - IN UINT32 ToneLength, - IN UINT32 SilenceLength - ); - -/** - Play audio file for context. - - @param[in] Context Picker context. - @param[in] Entry Entry to play. - - @retval EFI_SUCCESS on success or when unnecessary. -**/ -EFI_STATUS -OcPlayAudioEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *Entry - ); - -/** - Toggle VoiceOver support. - - @param[in] Context Picker context. - @param[in] File File to play after enabling VoiceOver. -**/ -VOID -OcToggleVoiceOver ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 File OPTIONAL - ); - -/** - Obtain BootOrder entry list. - - @param[in] BootVariableGuid GUID namespace for boot entries. - @param[in] WithBootNext Add BootNext as the first option if available. - @param[out] BootOrderCount Number of entries in boot order. - @param[out] Deduplicated Whether the list was changed during deduplication, optional. - @param[out] HasBootNext Whether the list starts with BootNext, optional - - @retval boot order entry list allocated from pool or NULL. -**/ -UINT16 * -OcGetBootOrder ( - IN EFI_GUID *BootVariableGuid, - IN BOOLEAN WithBootNext, - OUT UINTN *BootOrderCount, - OUT BOOLEAN *Deduplicated OPTIONAL, - OUT BOOLEAN *HasBootNext OPTIONAL - ); - -/** - Register top-most priority boot option. - - @param[in] OptionName Option name to create. - @param[in] DeviceHandle Device handle of the file system. - @param[in] FilePath Bootloader path. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcRegisterBootOption ( - IN CONST CHAR16 *OptionName, - IN EFI_HANDLE DeviceHandle, - IN CONST CHAR16 *FilePath - ); - -#endif // OC_BOOT_MANAGEMENT_LIB_H diff --git a/Include/Library/OcCompressionLib.h b/Include/Library/OcCompressionLib.h deleted file mode 100644 index 8cf475942..000000000 --- a/Include/Library/OcCompressionLib.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_COMPRESSION_LIB_H -#define OC_COMPRESSION_LIB_H - -/** - Maximumum compression and decompression buffer size may vary from - 0 to OC_COMPRESSION_MAX_LENGTH inclusive. -**/ -#define OC_COMPRESSION_MAX_LENGTH BASE_1GB - -/** - Allow the use of extra adler32 validation. - Not very useful as dmg has own checks. -**/ -// #define OC_INFLATE_VERIFY_DATA - -/** - Compress buffer with LZSS algorithm. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - - @return Dst + CompressedLen on success otherwise NULL. -**/ -UINT8 * -CompressLZSS ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN UINT8 *Src, - IN UINT32 SrcLen - ); - -/** - Decompress buffer with LZSS algorithm. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - - @return DecompressedLen on success otherwise 0. -**/ -UINT32 -DecompressLZSS ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN UINT8 *Src, - IN UINT32 SrcLen - ); - -/** - Decompress buffer with LZVN algorithm. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - - @return DecompressedLen on success otherwise 0. -**/ -UINTN -DecompressLZVN ( - OUT UINT8 *Dst, - IN UINTN DstLen, - IN CONST UINT8 *Src, - IN UINTN SrcLen - ); - -/** - Compress buffer with ZLIB algorithm. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - - @return Dst + CompressedLen on success otherwise NULL. -**/ -UINT8 * -CompressZLIB ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN CONST UINT8 *Src, - IN UINT32 SrcLen - ); - -/** - Decompress buffer with ZLIB algorithm. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - - @return DecompressedLen on success otherwise 0. -**/ -UINTN -DecompressZLIB ( - OUT UINT8 *Dst, - IN UINTN DstLen, - IN CONST UINT8 *Src, - IN UINTN SrcLen - ); - -/** - Decompress buffer with RLE24 algorithm and 8-bit alpha. - This algorithm is used for encoding IT32/T8MK images in ICNS. - - @param[out] Dst Destination buffer. - @param[in] DstLen Destination buffer size. - @param[in] Src Source buffer. - @param[in] SrcLen Source buffer size. - @param[in] Mask Source buffer. - @param[in] MaskLen Source buffer size. - @param[in] Premultiply Multiply source channels by alpha. - - @return DecompressedLen on success otherwise 0. -**/ -UINT32 -DecompressMaskedRLE24 ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN UINT8 *Src, - IN UINT32 SrcLen, - IN UINT8 *Mask, - IN UINT32 MaskLen, - IN BOOLEAN Premultiply - ); - -#endif // OC_COMPRESSION_LIB_H diff --git a/Include/Library/OcConsoleLib.h b/Include/Library/OcConsoleLib.h deleted file mode 100644 index c7b17e899..000000000 --- a/Include/Library/OcConsoleLib.h +++ /dev/null @@ -1,196 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_CONSOLE_LIB_H -#define OC_CONSOLE_LIB_H - -#include -#include - -/** - Console renderer to use. -**/ -typedef enum { - OcConsoleRendererBuiltinGraphics, - OcConsoleRendererSystemGraphics, - OcConsoleRendererSystemText, - OcConsoleRendererSystemGeneric -} OC_CONSOLE_RENDERER; - -/** - Special commands sent to Builtin text renderer through TestString. -**/ -#define OC_CONSOLE_MARK_CONTROLLED L"MarkControlled" -#define OC_CONSOLE_MARK_UNCONTROLLED L"MarkUncontrolled" - -/** - Configure console control protocol with given options. - - @param[in] Renderer Renderer to use. - @param[in] IgnoreTextOutput Skip console output in text mode. - @param[in] SanitiseClearScreen Workaround ClearScreen breaking resolution. - @param[in] ClearScreenOnModeSwitch Clear graphic screen when switching to text mode. - @param[in] ReplaceTabWithSpace Replace invisible tab characters with spaces in OutputString. -**/ -VOID -OcSetupConsole ( - IN OC_CONSOLE_RENDERER Renderer, - IN BOOLEAN IgnoreTextOutput, - IN BOOLEAN SanitiseClearScreen, - IN BOOLEAN ClearScreenOnModeSwitch, - IN BOOLEAN ReplaceTabWithSpace - ); - -/** - Update console control screen mode. - - @param[in] Mode Desired mode. - - @retval previous console control mode. -**/ -EFI_CONSOLE_CONTROL_SCREEN_MODE -OcConsoleControlSetMode ( - IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - ); - -/** - Parse screen resolution from string. - - @param[in] String Resolution in WxH@B or WxH format. - @param[out] Width Parsed resolution width or 0. - @param[out] Height Parsed resolution height or 0. - @param[out] Bpp Parsed resolution bpp or 0. - @param[out] Max Set to TRUE when String equals to Max. -**/ -VOID -OcParseScreenResolution ( - IN CONST CHAR8 *String, - OUT UINT32 *Width, - OUT UINT32 *Height, - OUT UINT32 *Bpp, - OUT BOOLEAN *Max - ); - -/** - Parse console mode from string. - - @param[in] String Resolution in WxH format. - @param[out] Width Parsed mode width or 0. - @param[out] Height Parsed mode height or 0. - @param[out] Max Set to TRUE when String equals to Max. -**/ -VOID -OcParseConsoleMode ( - IN CONST CHAR8 *String, - OUT UINT32 *Width, - OUT UINT32 *Height, - OUT BOOLEAN *Max - ); - -/** - Set screen resolution on console handle. - - @param[in] Width Resolution width or 0 for Max. - @param[in] Height Resolution height or 0 for Max. - @param[in] Bpp Resolution bpp or 0 for automatic. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcSetConsoleResolution ( - IN UINT32 Width, - IN UINT32 Height, - IN UINT32 Bpp OPTIONAL - ); - -/** - Set console mode. - - @param[in] Width Resolution width or 0 for Max. - @param[in] Height Resolution height or 0 for Max. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcSetConsoleMode ( - IN UINT32 Width, - IN UINT32 Height - ); - -/** - Ensure installed GOP protocol on ConOut handle. -**/ -VOID -OcProvideConsoleGop( - IN BOOLEAN Route - ); - -/** - Perform console reconnection. -**/ -VOID -OcReconnectConsole ( - VOID - ); - -/** - Use direct GOP renderer for console. - - @param[in] CacheType Caching type, e.g. CacheWriteCombining or -1 to disable. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcUseDirectGop ( - IN INT32 CacheType - ); - -/** - Allocate new System Table with disabled text output. - - @param[in] SystemTable Base System Table. - - @retval non NULL The System Table table was allocated successfully. -**/ -EFI_SYSTEM_TABLE * -AllocateNullTextOutSystemTable ( - IN EFI_SYSTEM_TABLE *SystemTable - ); - -/** - Provide UGA protocol instances on top of existing GOP instances. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcProvideUgaPassThrough ( - VOID - ); - -/** - Install and initialise Apple Framebuffer Info protocol - on top of GOP protocol. For EfiBoot 10.4, which can only - use UGA, this is the only way to obtain framebuffer base - for XNU kernel PE Boot_args. - - @param[in] Reinstall Overwrite installed protocol. - - @retval installed or located protocol or NULL. -**/ -APPLE_FRAMEBUFFER_INFO_PROTOCOL * -OcAppleFbInfoInstallProtocol ( - IN BOOLEAN Reinstall - ); - -#endif // OC_CONSOLE_LIB_H diff --git a/Include/Library/OcCpuLib.h b/Include/Library/OcCpuLib.h deleted file mode 100755 index 701e20569..000000000 --- a/Include/Library/OcCpuLib.h +++ /dev/null @@ -1,223 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_CPU_LIB_H -#define OC_CPU_LIB_H - -#include -#include - -/** - Assumed CPU frequency when it cannot be detected. - Can be overridden by e.g. emulator. -**/ -#ifndef OC_FALLBACK_CPU_FREQUENCY -#define OC_FALLBACK_CPU_FREQUENCY 1000000000 -#endif - -typedef struct { - // - // Note, Vendor and BrandString are reordered for proper alignment. - // - UINT32 Vendor[4]; - CHAR8 BrandString[48]; - - CPUID_VERSION_INFO_EAX CpuidVerEax; - CPUID_VERSION_INFO_EBX CpuidVerEbx; - CPUID_VERSION_INFO_ECX CpuidVerEcx; - CPUID_VERSION_INFO_EDX CpuidVerEdx; - - UINT32 MicrocodeRevision; - BOOLEAN Hypervisor; ///< indicate whether we are under virtualization - - UINT8 Type; - UINT8 Family; - UINT8 Model; - UINT8 ExtModel; - UINT8 ExtFamily; - UINT8 Stepping; - UINT64 Features; - UINT64 ExtFeatures; - UINT32 Signature; - UINT8 Brand; - UINT16 AppleProcessorType; - BOOLEAN CstConfigLock; - - UINT32 MaxId; - UINT32 MaxExtId; - - UINT8 MaxDiv; - UINT8 CurBusRatio; ///< Current Multiplier - UINT8 MinBusRatio; ///< Min Bus Ratio - UINT8 MaxBusRatio; ///< Max Bus Ratio - - UINT8 TurboBusRatio1; - UINT8 TurboBusRatio2; - UINT8 TurboBusRatio3; - UINT8 TurboBusRatio4; - - UINT16 PackageCount; - UINT16 CoreCount; - UINT16 ThreadCount; - - // - // External clock for SMBIOS Type4 table. - // - UINT16 ExternalClock; - - // - // Platform-dependent frequency for the Always Running Timer (ART), normally - // 24Mhz. Firmwares may choose to override this. Some CPUs like Xeon Scalable - // use a different frequency. CPUs report the frequency through CPUID.15H.ECX. - // If unreported, the frequency is looked up based on the model and family. - // - // Nominal Core Crystal Clock Frequency for known processor families: - // Intel Xeon Scalable with CPUID signature 0x0655: 25 Mhz (server segment) - // 6th and 7th generation Intel Core & Xeon W: 24 Mhz (client segment) - // Nex Generation Intel Atom with CPUID 0x065C: 19.2 Mhz (atom segment) - // - UINT64 ARTFrequency; - - // - // The CPU frequency derived from either CPUFrequencyFromTSC (legacy) or - // CPUFrequencyFromART (preferred for Skylake and presumably newer processors - // that have an Always Running Timer). - // - // CPUFrequencyFromTSC should approximate equal CPUFrequencyFromART. If not, - // there is likely a bug or miscalculation. - // - UINT64 CPUFrequency; - - // - // The CPU frequency as reported by the Time Stamp Counter (TSC). - // - UINT64 CPUFrequencyFromTSC; - - // - // The CPU frequency derived from the Always Running Timer (ART) frequency: - // TSC Freq = (ART Freq * CPUID.15H:EBX[31:0]) / CPUID.15H:EAX[31:0] - // - // 0 if ART is not present. - // - UINT64 CPUFrequencyFromART; - - // - // TSC adjustment value read from MSR_IA32_TSC_ADJUST if present. - // - UINT64 TscAdjust; - - // - // The CPU frequency derived from the CPUID VMWare Timing leaf. - // 0 if VMWare Timing leaf is not present. - // - UINT64 CPUFrequencyFromVMT; - - // - // The Front Side Bus (FSB) frequency calculated from dividing the CPU - // frequency by the Max Ratio. - // - UINT64 FSBFrequency; -} OC_CPU_INFO; - -typedef enum { - OcCpuGenerationUnknown, - OcCpuGenerationPenryn, - OcCpuGenerationNehalem, - OcCpuGenerationWestmere, - OcCpuGenerationSandyBridge, - OcCpuGenerationIvyBridge, - OcCpuGenerationHaswell, - OcCpuGenerationBroadwell, - OcCpuGenerationSkylake, - OcCpuGenerationKabyLake, - OcCpuGenerationCoffeeLake, - OcCpuGenerationCannonLake, - OcCpuGenerationMaxGeneration -} OC_CPU_GENERATION; - -/** - Scan the processor and fill the cpu info structure with results. - - @param[in] Cpu A pointer to the cpu info structure to fill with results. -**/ -VOID -OcCpuScanProcessor ( - IN OUT OC_CPU_INFO *Cpu - ); - -/** - Disable flex ratio if it has invalid value. - Commonly fixes early reboot on APTIO IV (Ivy/Haswell). - - @param[in] Cpu A pointer to the cpu info. -**/ -VOID -OcCpuCorrectFlexRatio ( - IN OC_CPU_INFO *Cpu - ); - -/** - Synchronise TSC on all cores (needed on server chipsets and some laptops). - This does not fully replace VoodooTscSync or TSCAdjustReset due to - the need to sync on S3 as well and may also work far less reliably - due to the limitation of UEFI firmwares not letting us run MSR updates in - parallel with BSP and AP cores. However, it lets debug kernels work - most of the time till the time TSC kexts start. - - @param[in] Cpu A pointer to the cpu info. - @param[in] Timeout Amount of time to wait for CPU core rendezvous. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcCpuCorrectTscSync ( - IN OC_CPU_INFO *Cpu, - IN UINTN Timeout - ); - -/** - Converts CPUID Family and Model extracted from EAX - CPUID (1) call to AppleFamily value. This implements - cpuid_set_cpufamily functionality as it is in XNU. - - @param[in] VersionEax CPUID (1) EAX value. - - @retval Apple Family (e.g. CPUFAMILY_UNKNOWN) -**/ -UINT32 -OcCpuModelToAppleFamily ( - IN CPUID_VERSION_INFO_EAX VersionEax - ); - -/** - Obtain CPU's generation. - - @retval CPU's generation (e.g. OcCpuGenerationUnknown). - */ -OC_CPU_GENERATION -OcCpuGetGeneration ( - VOID - ); - -/** - Obtain CPU's invariant TSC frequency. - - @retval CPU's TSC frequency or OC_FALLBACK_CPU_FREQUENCY. -**/ -UINT64 -OcGetTSCFrequency ( - VOID - ); - -#endif // OC_CPU_LIB_H_ diff --git a/Include/Library/OcCryptoLib.h b/Include/Library/OcCryptoLib.h deleted file mode 100644 index 5b0fc3a19..000000000 --- a/Include/Library/OcCryptoLib.h +++ /dev/null @@ -1,541 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2018, savvas - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_CRYPTO_LIB_H -#define OC_CRYPTO_LIB_H - -#include - -// -// Default to 128-bit key length for AES. -// -#ifndef CONFIG_AES_KEY_SIZE -#define CONFIG_AES_KEY_SIZE 16 -#endif - -// -// Digest sizes. -// -#define MD5_DIGEST_SIZE 16 -#define SHA1_DIGEST_SIZE 20 -#define SHA256_DIGEST_SIZE 32 -#define SHA384_DIGEST_SIZE 48 -#define SHA512_DIGEST_SIZE 64 - -#define OC_MAX_SHA_DIGEST_SIZE SHA512_DIGEST_SIZE - -// -// Block sizes. -// -#define SHA256_BLOCK_SIZE 64 -#define SHA512_BLOCK_SIZE 128 -#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE - -// -// Derived parameters. -// -#define AES_BLOCK_SIZE 16 - -// -// Support all AES key sizes. -// -#if CONFIG_AES_KEY_SIZE == 32 -#define AES_KEY_EXP_SIZE 240 -#elif CONFIG_AES_KEY_SIZE == 24 -#define AES_KEY_EXP_SIZE 208 -#elif CONFIG_AES_KEY_SIZE == 16 -#define AES_KEY_EXP_SIZE 176 -#else -#error "Only AES-128, AES-192, and AES-256 are supported!" -#endif - -// -// ChaCha key size. -// -#define CHACHA_KEY_SIZE 32 - -// -// ChaCha IV size. -// -#define CHACHA_IV_SIZE 12 - -// -// Possible RSA algorithm types supported by OcCryptoLib -// for RSA digital signature verification -// PcdOcCryptoAllowedSigHashTypes MUST be kept in sync with changes! -// -typedef enum OC_SIG_HASH_TYPE_ { - OcSigHashTypeSha256, - OcSigHashTypeSha384, - OcSigHashTypeSha512, - OcSigHashTypeMax -} OC_SIG_HASH_TYPE; - -typedef struct AES_CONTEXT_ { - UINT8 RoundKey[AES_KEY_EXP_SIZE]; - UINT8 Iv[AES_BLOCK_SIZE]; -} AES_CONTEXT; - -typedef struct CHACHA_CONTEXT_ { - UINT32 Input[16]; -} CHACHA_CONTEXT; - -typedef struct MD5_CONTEXT_ { - UINT8 Data[64]; - UINT32 DataLen; - UINT64 BitLen; - UINT32 State[4]; -} MD5_CONTEXT; - -typedef struct SHA1_CONTEXT_ { - UINT8 Data[64]; - UINT32 DataLen; - UINT64 BitLen; - UINT32 State[5]; - UINT32 K[4]; -} SHA1_CONTEXT; - -typedef struct SHA256_CONTEXT_ { - UINT8 Data[64]; - UINT32 DataLen; - UINT64 BitLen; - UINT32 State[8]; -} SHA256_CONTEXT; - -typedef struct SHA512_CONTEXT_ { - UINT64 TotalLength; - UINTN Length; - UINT8 Block[2 * SHA512_BLOCK_SIZE]; - UINT64 State[8]; -} SHA512_CONTEXT; - -typedef SHA512_CONTEXT SHA384_CONTEXT; - -#pragma pack(push, 1) - -/// -/// The structure describing the RSA Public Key format. -/// The exponent is always 65537. -/// -typedef PACKED struct { - /// - /// The number of 64-bit values of N and RSqrMod each. - /// - UINT16 NumQwords; - /// - /// Padding for 64-bit alignment. Must be 0 to allow future extensions. - /// - UINT8 Reserved[6]; - /// - /// The Montgomery Inverse in 64-bit space: -1 / N[0] mod 2^64. - /// - UINT64 N0Inv; -} OC_RSA_PUBLIC_KEY_HDR; - -typedef PACKED struct { - /// - /// The RSA Public Key header structure. - /// - OC_RSA_PUBLIC_KEY_HDR Hdr; - /// - /// The Modulus and Montgomery's R^2 mod N in little endian byte order. - /// - UINT64 Data[]; -} OC_RSA_PUBLIC_KEY; - -#pragma pack(pop) - -// -// Functions prototypes -// - -VOID -AesInitCtxIv ( - OUT AES_CONTEXT *Context, - IN CONST UINT8 *Key, - IN CONST UINT8 *Iv - ); - -VOID -AesSetCtxIv ( - OUT AES_CONTEXT *Context, - IN CONST UINT8 *Iv - ); - -// -// Data size MUST be mutiple of AES_BLOCK_SIZE; -// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for Padding scheme -// NOTES: you need to set Iv in Context via AesInitCtxIv() or AesSetCtxIv() -// no Iv should ever be reused with the same key -// -VOID -AesCbcEncryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ); - -VOID -AesCbcDecryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ); - -// -// Same function for encrypting as for decrypting. -// Iv is incremented for every block, and used after encryption as XOR-compliment for output -// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for Padding scheme -// NOTES: you need to set Iv in Context via AesInitCtxIv() or AesSetCtxIv() -// no Iv should ever be reused with the same key -// -VOID -AesCtrXcryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ); - -/** - Setup ChaCha context (IETF variant). - - @param[out] Context ChaCha context. - @param[in] Key ChaCha 256-bit key. - @param[in] Iv ChaCha 96-bit initialisation vector. - @param[in] Counter ChaCha 32-bit counter. -**/ -VOID -ChaChaInitCtx ( - OUT CHACHA_CONTEXT *Context, - IN CONST UINT8 *Key, - IN CONST UINT8 *Iv, - IN UINT32 Counter - ); - -/** - Perform ChaCha encryption/decryption. - Source may match Destination. - - @param[in,out] Context ChaCha context. - @param[in] Source Data for transformation. - @param[out] Destination Resulting data. - @param[in] Length Data and ciphertext lengths. -**/ -VOID -ChaChaCryptBuffer ( - IN OUT CHACHA_CONTEXT *Context, - IN CONST UINT8 *Source, - OUT UINT8 *Destination, - IN UINT32 Length - ); - -VOID -Md5Init ( - MD5_CONTEXT *Context - ); - -VOID -Md5Update ( - MD5_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Md5Final ( - MD5_CONTEXT *Context, - UINT8 *Hash - ); - -VOID -Md5 ( - UINT8 *Hash, - UINT8 *Data, - UINTN Len - ); - -VOID -Sha1Init ( - SHA1_CONTEXT *Context - ); - -VOID -Sha1Update ( - SHA1_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha1Final ( - SHA1_CONTEXT *Context, - UINT8 *Hash - ); - -VOID -Sha1 ( - UINT8 *Hash, - UINT8 *Data, - UINTN Len - ); - -VOID -Sha256Init ( - SHA256_CONTEXT *Context - ); - -VOID -Sha256Update ( - SHA256_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha256Final ( - SHA256_CONTEXT *Context, - UINT8 *HashDigest - ); - -VOID -Sha256 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha512Init ( - SHA512_CONTEXT *Context - ); - -VOID -Sha512Update ( - SHA512_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha512Final ( - SHA512_CONTEXT *Context, - UINT8 *HashDigest - ); - -VOID -Sha512 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha384Init ( - SHA384_CONTEXT *Context - ); - -VOID -Sha384Update ( - SHA384_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ); - -VOID -Sha384Final ( - SHA384_CONTEXT *Context, - UINT8 *HashDigest - ); - -VOID -Sha384 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ); - -/** - Verifies Data against Hash with the appropiate SHA2 algorithm for HashSize. - - @param[in] Data The data to verify the hash of. - @param[in] DataSize The, in bytes, of Data. - @param[in] Hash The reference hash to verify against. - @param[in] HashSize The size, in bytes, of Hash. - - @return 0 All HashSize bytes of the two buffers are identical. - @retval Non-zero If HashSize is not a valid SHA2 digest size, -1. Otherwise, - the first mismatched byte in Data's hash subtracted from - the first mismatched byte in Hash. - -**/ -INTN -SigVerifyShaHashBySize ( - IN CONST VOID *Data, - IN UINTN DataSize, - IN CONST UINT8 *Hash, - IN UINTN HashSize - ); - -/** - Verify a RSA PKCS1.5 signature against an expected hash. - The exponent is always 65537 as per the format specification. - - @param[in] Key The RSA Public Key. - @param[in] Signature The RSA signature to be verified. - @param[in] SignatureSize Size, in bytes, of Signature. - @param[in] Hash The Hash digest of the signed data. - @param[in] HashSize Size, in bytes, of Hash. - @param[in] Algorithm The RSA algorithm used. - - @returns Whether the signature has been successfully verified as valid. - -**/ -BOOLEAN -RsaVerifySigHashFromKey ( - IN CONST OC_RSA_PUBLIC_KEY *Key, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Hash, - IN UINTN HashSize, - IN OC_SIG_HASH_TYPE Algorithm - ); - -/** - Verify RSA PKCS1.5 signed data against its signature. - The modulus' size must be a multiple of the configured BIGNUM word size. - This will be true for any conventional RSA, which use two's potencies. - - @param[in] Modulus The RSA modulus byte array. - @param[in] ModulusSize The size, in bytes, of Modulus. - @param[in] Exponent The RSA exponent. - @param[in] Signature The RSA signature to be verified. - @param[in] SignatureSize Size, in bytes, of Signature. - @param[in] Data The signed data to verify. - @param[in] DataSize Size, in bytes, of Data. - @param[in] Algorithm The RSA algorithm used. - - @returns Whether the signature has been successfully verified as valid. - -**/ -BOOLEAN -RsaVerifySigDataFromData ( - IN CONST UINT8 *Modulus, - IN UINTN ModulusSize, - IN UINT32 Exponent, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Data, - IN UINTN DataSize, - IN OC_SIG_HASH_TYPE Algorithm - ); - -/** - Verify RSA PKCS1.5 signed data against its signature. - The modulus' size must be a multiple of the configured BIGNUM word size. - This will be true for any conventional RSA, which use two's potencies. - The exponent is always 65537 as per the format specification. - - @param[in] Key The RSA Public Key. - @param[in] Signature The RSA signature to be verified. - @param[in] SignatureSize Size, in bytes, of Signature. - @param[in] Data The signed data to verify. - @param[in] DataSize Size, in bytes, of Data. - @param[in] Algorithm The RSA algorithm used. - - @returns Whether the signature has been successfully verified as valid. - -**/ -BOOLEAN -RsaVerifySigDataFromKey ( - IN CONST OC_RSA_PUBLIC_KEY *Key, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Data, - IN UINTN DataSize, - IN OC_SIG_HASH_TYPE Algorithm - ); - -/** - Performs a cryptographically secure comparison of the contents of two - buffers. - - This function compares Length bytes of SourceBuffer to Length bytes of - DestinationBuffer in a cryptographically secure fashion. This especially - implies that different lengths of the longest shared prefix do not change - execution time in a way relevant to security. - - If Length > 0 and DestinationBuffer is NULL, then ASSERT(). - If Length > 0 and SourceBuffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT(). - If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT(). - - @param DestinationBuffer The pointer to the destination buffer to compare. - @param SourceBuffer The pointer to the source buffer to compare. - @param Length The number of bytes to compare. - - @return 0 All Length bytes of the two buffers are identical. - @retval -1 The two buffers are not identical within Length - bytes. -**/ -INTN -SecureCompareMem ( - IN CONST VOID *DestinationBuffer, - IN CONST VOID *SourceBuffer, - IN UINTN Length - ); - -/** - Performs a cryptographically secure memory zeroing. - - If Length > 0 and Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param[out] Buffer The pointer to the destination buffer to zero. - @param[in] Length The number of bytes to zero. - - @return Buffer. -**/ -VOID * -SecureZeroMem ( - OUT VOID *Buffer, - IN UINTN Length - ); - -/** - Verify Password and Salt against RefHash. The used hash function is SHA-512, - thus the caller must ensure RefHash is at least 64 bytes in size. - - @param[in] Password The entered password to verify. - @param[in] PasswordSize The size, in bytes, of Password. - @param[in] Salt The cryptographic salt appended to Password on hash. - @param[in] SaltSize The size, in bytes, of Salt. - @param[in] RefHash The SHA-512 hash of the reference password and Salt. - - @returns Whether Password and Salt cryptographically match RefHash. - -**/ -BOOLEAN -OcVerifyPasswordSha512 ( - IN CONST UINT8 *Password, - IN UINT32 PasswordSize, - IN CONST UINT8 *Salt, - IN UINT32 SaltSize, - IN CONST UINT8 *RefHash - ); - -#endif // OC_CRYPTO_LIB_H diff --git a/Include/Library/OcDebugLogLib.h b/Include/Library/OcDebugLogLib.h deleted file mode 100644 index f6b3ae9dd..000000000 --- a/Include/Library/OcDebugLogLib.h +++ /dev/null @@ -1,176 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_DEBUG_LOG_LIB_H -#define OC_DEBUG_LOG_LIB_H - -#include -#include -#include - -#define OC_HEX_LOWER(x) "0123456789ABCDEF"[((UINT32) (x) & 0x0FU)] -#define OC_HEX_UPPER(x) "0123456789ABCDEF"[((UINT32) (x) & 0xF0U) >> 4U] - -#ifndef OC_TARGET_RELEASE -#define OC_TARGET_RELEASE RELEASE -#endif -/** - Expand device path to human readable string. -**/ -#define OC_HUMAN_STRING(TextDevicePath) \ - ((TextDevicePath) == NULL ? L"" : (TextDevicePath)[0] == '\0' ? L"" : (TextDevicePath)) - -/** - Debug information that is not logged when NVRAM logging is on. -**/ -#ifndef DEBUG_BULK_INFO - #define DEBUG_BULK_INFO (DEBUG_VERBOSE|DEBUG_INFO) -#endif - -/** - This is a place print debug messages when they happen after ExitBootServices. -**/ -#define RUNTIME_DEBUG(x) do { } while (0) - -/** - Pointer debug kit. -**/ -#if defined(OC_TARGET_DEBUG) || defined(OC_TARGET_NOOPT) -#define DEBUG_POINTER(x) x -#elif defined(OC_TARGET_RELEASE) -#define DEBUG_POINTER(x) NULL -#else -#error "Define target macro: OC_TARGET_!" -#endif - -/** - Install or update the OcLog protocol with specified options. - - @param[in] Options Logging options. - @param[in] DisplayDelay Delay in microseconds after each log entry. - @param[in] DisplayLevel Console visible error level. - @param[in] HaltLevel Error level causing CPU halt. - @param[in] LogPrefixPath Log path (without timestamp). - @param[in] LogFileSystem Log filesystem, optional. - - @retval EFI_SUCCESS The entry point is executed successfully. -**/ -EFI_STATUS -OcConfigureLogProtocol ( - IN OC_LOG_OPTIONS Options, - IN UINT32 DisplayDelay, - IN UINTN DisplayLevel, - IN UINTN HaltLevel, - IN CONST CHAR16 *LogPrefixPath OPTIONAL, - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *LogFileSystem OPTIONAL - ); - -/** - Install and initialise the Apple Debug Log protocol. - - @param[in] Reinstall Replace any installed protocol. - - @returns Installed or located protocol. - @retval NULL There was an error locating or installing the protocol. -**/ -APPLE_DEBUG_LOG_PROTOCOL * -OcAppleDebugLogInstallProtocol ( - IN BOOLEAN Reinstall - ); - -/** - Configure Apple Debug Log protocol. - - @param[in] Enable Enable logging to OcLog. -**/ -VOID -OcAppleDebugLogConfigure ( - IN BOOLEAN Enable - ); - -/** - Configure Apple performance log location. - - @param[in,out] PerfBuffer Performance buffer location. - @param[in] PerfBufferSize Performance buffer size. -**/ -VOID -OcAppleDebugLogPerfAllocated ( - IN OUT VOID *PerfBuffer, - IN UINTN PerfBufferSize - ); - -/** - Prints via gST->ConOut without any pool allocations. - Otherwise equivalent to Print. - Note: EFIAPI must be present for VA_ARGS forwarding (causes bugs with gcc). - - @param[in] Format Formatted string. -**/ -VOID -EFIAPI -OcPrintScreen ( - IN CONST CHAR16 *Format, - ... - ); - -/** - Dummy function that debuggers may break on. -**/ -VOID -DebugBreak ( - VOID - ); - -/** - Wait for user input after printing message. - - @param[in] Message Message to print. -**/ -VOID -WaitForKeyPress ( - CONST CHAR16 *Message - ); - -/** - Print Device Path to log. - - @param[in] ErrorLevel Debug error level. - @param[in] Message Prefixed message. - @param[in] DevicePath Device path to print. -**/ -VOID -DebugPrintDevicePath ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Message, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Print hex dump to log. - - @param[in] ErrorLevel Debug error level. - @param[in] Message Prefixed message. - @param[in] Bytes Byte sequence. - @param[in] Size Byte sequence size. -**/ -VOID -DebugPrintHexDump ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Message, - IN UINT8 *Bytes, - IN UINTN Size - ); - -#endif // OC_DEBUG_LOG_LIB_H diff --git a/Include/Library/OcDevicePathLib.h b/Include/Library/OcDevicePathLib.h deleted file mode 100755 index a15a2ed57..000000000 --- a/Include/Library/OcDevicePathLib.h +++ /dev/null @@ -1,305 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_DEVICE_PATH_LIB_H -#define OC_DEVICE_PATH_LIB_H - -/** - Append file name to device path. - - @param[in] DevicePath The device path which to append the file path. - @param[in] FileName The file name to append to the device path. - - @retval EFI_SUCCESS The defaults were initialized successfully. - @retval EFI_INVALID_PARAMETER The parameters passed were invalid. - @retval EFI_OUT_OF_RESOURCES The system ran out of memory. -**/ -EFI_DEVICE_PATH_PROTOCOL * -AppendFileNameDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CHAR16 *FileName - ); - -/** - Locate the node inside the device path specified by Type an SubType values. - - @param[in] DevicePath The device path used in the search. - @param[in] Type The Type field of the device path node specified by Node. - @param[in] SubType The SubType field of the device path node specified by Node. - - @return Returned is the first Device Path Node with the given type. -**/ -EFI_DEVICE_PATH_PROTOCOL * -FindDevicePathNodeWithType ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT8 Type, - IN UINT8 SubType OPTIONAL - ); - -/** - Check whether device paths are equal. - - @param[in] DevicePath1 The first device path protocol to compare. - @param[in] DevicePath2 The second device path protocol to compare. - - @retval TRUE The device paths matched - @retval FALSE The device paths were different -**/ -BOOLEAN -EFIAPI -IsDevicePathEqual ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ); - -/** - Check whether File Device Paths are equal. - - @param[in] FilePath1 The first device path protocol to compare. - @param[in] FilePath2 The second device path protocol to compare. - - @retval TRUE The device paths matched - @retval FALSE The device paths were different -**/ -BOOLEAN -FileDevicePathsEqual ( - IN FILEPATH_DEVICE_PATH *FilePath1, - IN FILEPATH_DEVICE_PATH *FilePath2 - ); - -/** - Check whether one device path exists in the other. - - @param[in] ParentPath The parent device path protocol to check against. - @param[in] ChildPath The device path protocol of the child device to compare. - - @retval TRUE The child device path contains the parent device path. - @retval FALSE The device paths were different -**/ -BOOLEAN -EFIAPI -IsDevicePathChild ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentPath, - IN EFI_DEVICE_PATH_PROTOCOL *ChildPath - ); - -/** - Get absolute device path. - - @param[in] Handle Device handle. - @param[in] RelativePath Relative device path to handle, optional. - - @retval New device path or NULL. -**/ -EFI_DEVICE_PATH_PROTOCOL * -AbsoluteDevicePath ( - IN EFI_HANDLE Handle, - IN EFI_DEVICE_PATH_PROTOCOL *RelativePath OPTIONAL - ); - -/** - Get trailed (slash-appended) device path for booter paths. - This way \\smth.efi gets NULL and \\smth gives \\smth\\. - - @param[in] DevicePath Device path. - - @retval New device path or NULL. -**/ -EFI_DEVICE_PATH_PROTOCOL * -TrailedBooterDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Returns the size of PathName. - - @param[in] FilePath The file Device Path node to inspect. - - @retval Name size in bytes. -**/ -UINTN -OcFileDevicePathNameSize ( - IN CONST FILEPATH_DEVICE_PATH *FilePath - ); - -/** - Returns the length of PathName. - - @param[in] FilePath The file Device Path node to inspect. - - @retval Name length in characters (without trailing zero). -**/ -UINTN -OcFileDevicePathNameLen ( - IN CONST FILEPATH_DEVICE_PATH *FilePath - ); - -/** - Retrieve the size of the full file path described by DevicePath. - - @param[in] DevicePath The Device Path to inspect. - - @returns The size of the full file path. - @retval 0 DevicePath does not start with a File Path node or contains - non-terminating nodes that are not File Path nodes. - -**/ -UINTN -OcFileDevicePathFullNameSize ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Retrieve the full file path described by FilePath. - The caller is expected to call OcFileDevicePathFullNameSize() or ensure its - guarantees are met. - - @param[out] PathName On output, the full file path of FilePath. - @param[in] FilePath The File Device Path to inspect. - @param[in] PathNameSize The size, in bytes, of PathnName. Must equal the - actual fill file path size. - -**/ -VOID -OcFileDevicePathFullName ( - OUT CHAR16 *PathName, - IN CONST FILEPATH_DEVICE_PATH *FilePath, - IN UINTN PathNameSize - ); - -/** - Duplicate device path with DevicePathInstance appended if it is not present. - - @param[in] DevicePath Device Path to append new instance to, optional. - @param[in] DevicePathInstance Device Path instance to append. - - @retval New Device Path or NULL. -**/ -EFI_DEVICE_PATH_PROTOCOL * -OcAppendDevicePathInstanceDedupe ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ); - -/** - Calculate number of device path instances. - - @param[in] DevicePath Device Path to calculate instances in. - - @retval Number of instances in device path. -**/ -UINTN -OcGetNumDevicePathInstances ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/// -/// Used to store information on how to restore a node patched by -/// OcFixAppleBootDevicePathNode(). -/// -typedef union { - struct { - UINT16 PortMultiplierPortNumber; - } Sata; - - struct { - UINT8 SubType; - } SasExNvme; - - struct { - UINT32 HID; - UINT32 UID; - } Acpi; - - struct { - UINT32 HID; - UINT32 CID; - } ExtendedAcpi; -} APPLE_BOOT_DP_PATCH_CONTEXT; - -/** - Fix Apple Boot Device Path node to be compatible with conventional UEFI - implementations. - - @param[in,out] DevicePathNode A pointer to the device path node to fix. - @param[out] RestoreContext A pointer to a context that can be used to - restore DevicePathNode's original content in - the case of failure. - - @retval -1 DevicePathNode could not be fixed. - @retval 0 DevicePathNode was not modified and may be valid. - @retval 1 DevicePathNode was fixed and may be valid. - -**/ -INTN -OcFixAppleBootDevicePathNode ( - IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, - OUT APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext OPTIONAL - ); - -/** - Restore the original content of DevicePathNode before calling - OcFixAppleBootDevicePathNode() with RestoreContext. - - @param[in,out] DevicePathNode A pointer to the device path node to restore. - @param[out] RestoreContext A pointer to a context that was used to call - OcFixAppleBootDevicePathNode(). - -**/ -VOID -OcFixAppleBootDevicePathNodeRestore ( - IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, - IN CONST APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext - ); - -/** - Fix Apple Boot Device Path to be compatible with conventional UEFI - implementations. In case -1 is returned and the first node could not be - located or fixed, DevicePath's original state will be preserved. In all other - cases, it may be destroyed. - - @param[in,out] DevicePath On input, a pointer to the device path to fix. - On output, the device path pointer is modified to - point to the remaining part of the device path. - - @retval -1 *DevicePath could not be fixed. - @retval 0 *DevicePath was not modified and may be valid. - @retval 1 *DevicePath was fixed and may be valid. - -**/ -INTN -OcFixAppleBootDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ); - -/** - Get the next possible full path pointing to the load option. - The routine doesn't guarantee the returned full path points to an existing - file, and it also doesn't guarantee the existing file is a valid load option. - - @param FilePath The device path pointing to a load option. - It could be a short-form device path. - @param FullPath The full path returned by the routine in last call. - Set to NULL in first call. - - @return The next possible full path pointing to the load option. - Caller is responsible to free the memory. -**/ -EFI_DEVICE_PATH_PROTOCOL * -OcGetNextLoadOptionDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN EFI_DEVICE_PATH_PROTOCOL *FullPath - ); - -#endif // OC_DEVICE_PATH_LIB_H diff --git a/Include/Library/OcFileLib.h b/Include/Library/OcFileLib.h deleted file mode 100755 index a27b77cc5..000000000 --- a/Include/Library/OcFileLib.h +++ /dev/null @@ -1,424 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_FILE_LIB_H -#define OC_FILE_LIB_H - -// Include the abstracted protocol for its definitions - -#include - -#include -#include -#include -#include - -/** - Maximum safe volume label size. -**/ -#define OC_MAX_VOLUME_LABEL_SIZE 64 - -/** - Locate file system from Device handle or path. - - @param[in] DeviceHandle Device handle. - @param[in] FilePath Device path. - - @retval simple file system protocol or NULL. -**/ -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * -LocateFileSystem ( - IN EFI_HANDLE DeviceHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ); - -/** - Locate root volume from Device handle or path. - - @param[in] DeviceHandle Device handle. - @param[in] FilePath Device path. - - @retval opened file protocol or NULL. -**/ -EFI_FILE_PROTOCOL * -LocateRootVolume ( - IN EFI_HANDLE DeviceHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ); - -/** - Locate file system from GUID. - - @param[in] Guid GUID of the volume to locate. - - @retval simple file system protocol or NULL. -**/ -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * -LocateFileSystemByGuid ( - IN CONST GUID *Guid - ); - -/** - Retrieves volume label. - - @param[in] FileSystem A pointer to the file system protocol of the volume. - - @retval A pointer to the NULL terminated unicode volume label. -**/ -CHAR16 * -GetVolumeLabel ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem - ); - -/** - Opens a new file relative to the source file's location. - This function is equivalent to EFI_FILE_OPEN but has additional restrictions - to provide board compatibility. Currently the only restriction is - no trailing slash in the filename due to issues in FAT drivers. - - - Multiple boards, namely ASUS P8H61-M and P8H61-M LX2 will not - open directories with trailing slash. It is irrelevant whether - front slash is present for them. - For example, it means that L"EFI\\OC\\" or L"\\EFI\\OC\\" will both - fail to open, while L"EFI\\OC" and L"\\EFI\\OC" will open fine. - - Most newer boards on APTIO IV do handle directories with trailing - slash, however, their driver will modify passed string by removing - the slash by \0. - - @param Protocol File protocol instance. - @param NewHandle Pointer for returned handle. - @param FileName Null-terminated file name. - @param OpenMode File open mode. - @param Attributes Attributes for the newly created file. - - @retval EFI_SUCCESS for successfully opened file. -*/ -EFI_STATUS -SafeFileOpen ( - IN EFI_FILE_PROTOCOL *Protocol, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CONST CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ); - -/** - Read file from device path with implicit double (2 byte) null termination. - Null termination does not affect the returned file size. - Depending on the implementation 0 byte files may return null. - - @param[in] FileSystem A pointer to the file system protocol of the volume. - @param[in] FilePath The full path to the file on the device. - @param[out] FileSize The size of the file read (optional). - @param[in] MaxFileSize Upper file size bound (optional). - - @retval A pointer to a buffer containing file read or NULL. -**/ -VOID * -ReadFile ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *FilePath, - OUT UINT32 *FileSize OPTIONAL, - IN UINT32 MaxFileSize OPTIONAL - ); - -/** - Determine file size if it is less than 4 GB. - - @param[in] FileSystem A pointer to the file system protocol of the volume. - @param[in] FilePath The full path to the file on the device. - @param[out] Size 32-bit file size. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -ReadFileSize ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *FilePath, - OUT UINT32 *Size - ); - -/** - Read exact amount of bytes from EFI_FILE_PROTOCOL at specified position. - - @param[in] File A pointer to the file protocol. - @param[in] Position Position to read data from. - @param[in] Size The size of the data read. - @param[out] Buffer A pointer to previously allocated buffer to read data to. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -GetFileData ( - IN EFI_FILE_PROTOCOL *File, - IN UINT32 Position, - IN UINT32 Size, - OUT UINT8 *Buffer - ); - -/** - Write exact amount of bytes to a newly created file in EFI_FILE_PROTOCOL. - Please note, that several filesystems (or drivers) may limit file name length. - - @param[in] WritableFs A pointer to the file protocol, any will be tried if NULL. - @param[in] FileName File name (possibly with path) to write. - @param[in] Buffer A pointer with the data to be written. - @param[in] Size Amount of data to be written. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -SetFileData ( - IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL, - IN CONST CHAR16 *FileName, - IN CONST VOID *Buffer, - IN UINT32 Size - ); - -/** - Get file information of specified type. - - @param[in] File A pointer to file handle. - @param[in] InformationType A pointer to file info GUID. - @param[in] MinFileInfoSize Minimal size of the info provided. - @param[out] RealFileInfoSize Actual info size read (optional). - - @retval read file info or NULL. -**/ -VOID * -GetFileInfo ( - IN EFI_FILE_PROTOCOL *File, - IN EFI_GUID *InformationType, - IN UINTN MinFileInfoSize, - OUT UINTN *RealFileInfoSize OPTIONAL - ); - -/** - Determine file size if it is less than 4 GB. - - @param[in] File A pointer to the file protocol. - @param[out] Size 32-bit file size. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -GetFileSize ( - IN EFI_FILE_PROTOCOL *File, - OUT UINT32 *Size - ); - -/** - Determine file modification time. - - @param[in] File A pointer to the file protocol. - @param[out] Time Modification time. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -GetFileModifcationTime ( - IN EFI_FILE_PROTOCOL *File, - OUT EFI_TIME *Time - ); - -/** - Determine writeable filesystem. - - @param[in,out] WritableFs First found writeable file system. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -FindWritableFileSystem ( - IN OUT EFI_FILE_PROTOCOL **WritableFs - ); - -/** - Open a file or directory by file system handle and path. - See OcOpenFileByDevicePath() for more details. - - @param[in] FileSystemHandle File System handle. - @param[in] RemainingDevicePath The remaining Device Path (must be all file - path nodes). - @param[out] File Resulting file protocol. - @param[in] OpenMode File open mode. - @param[in] Attributes File attributes. - - @retval EFI_SUCCESS on succesful open. -**/ -EFI_STATUS -EFIAPI -OcOpenFileByRemainingDevicePath ( - IN EFI_HANDLE FileSystemHandle, - IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT EFI_FILE_PROTOCOL **File, - IN UINT64 OpenMode, - IN UINT64 Attributes - ); - -/** - Open a file or directory by device path. This is a modified - version of EfiOpenFileByDevicePath function, which handles paths - with trailing slashes, that cause Open failure on old firmwares. - EfiOpenFileByDevicePath is additionally not available in UDK. - - See more details at: - https://github.com/tianocore/edk2/commit/768b611136d0f2b99a99e446c089d1a30c3fa5d5 - - @param[in,out] FilePath Device path protocol. - @param[out] File Resulting file protocol. - @param[in] OpenMode File open mode. - @param[in] Attributes File attributes. - - @retval EFI_SUCCESS on succesful open. -**/ -EFI_STATUS -EFIAPI -OcOpenFileByDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, - OUT EFI_FILE_PROTOCOL **File, - IN UINT64 OpenMode, - IN UINT64 Attributes - ); - -/** - Retrieve the disk's device handle from a partition's Device Path. - - @param[in] HdDevicePath The Device Path of the partition. - - @retval device handle or NULL -**/ -EFI_HANDLE -OcPartitionGetDiskHandle ( - IN EFI_DEVICE_PATH_PROTOCOL *HdDevicePath - ); - -/** - Locate the disk's EFI System Partition. - - @param[in] DiskDevicePath The Device Path of the disk to scan. - @param[out] EspDevicePathSize The size of the returned Device Path. - @param[out] EspDeviceHandle Device handle of the returned partition. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -OcDiskFindSystemPartitionPath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DiskDevicePath, - OUT UINTN *EspDevicePathSize, - OUT EFI_HANDLE *EspDeviceHandle - ); - -/** - Disk I/O context. -**/ -typedef struct { - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_BLOCK_IO2_PROTOCOL *BlockIo2; - UINT32 MediaId; - UINT32 BlockSize; -} OC_DISK_CONTEXT; - -/** - Initialize disk I/O context. - - @param[out] Context Disk I/O context to intialize. - @param[in] DiskHandle Disk handle with protocols. - @param[in] UseBlockIo2 Try to use BlockIo2 protocol if available. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcDiskInitializeContext ( - OUT OC_DISK_CONTEXT *Context, - IN EFI_HANDLE DiskHandle, - IN BOOLEAN UseBlockIo2 - ); - -/** - Read information from disk. - - @param[in] Context Disk I/O context. - @param[in] Lba LBA number to read from. - @param[in] BufferSize Buffer size allocated in Buffer. - @param[out] Buffer Buffer to store data in. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcDiskRead ( - IN OC_DISK_CONTEXT *Context, - IN UINT64 Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - OC partition list. -**/ -typedef struct { - UINT32 NumPartitions; - UINT32 PartitionEntrySize; - EFI_PARTITION_ENTRY FirstEntry[]; -} OC_PARTITION_ENTRIES; - -/** - Retrieve the disk GPT partitions, if applicable. - - @param[in] DiskHandle Disk device handle to retrive partition table from. - @param[in] UseBlockIo2 Use 2nd revision of Block I/O if available. - - @retval partition entry list or NULL. -**/ -CONST OC_PARTITION_ENTRIES * -OcGetDiskPartitions ( - IN EFI_HANDLE DiskHandle, - IN BOOLEAN UseBlockIo2 - ); - -/** - Retrieve the partition's GPT information, if applicable. - Calls to this function undergo internal lazy caching. - - @param[in] FsHandle The device handle of the partition to retrieve info of. - - @retval partition entry or NULL -**/ -CONST EFI_PARTITION_ENTRY * -OcGetGptPartitionEntry ( - IN EFI_HANDLE FsHandle - ); - -/** - Unblocks all partition handles without a File System protocol attached from - driver connection, if applicable. -**/ -VOID -OcUnblockUnmountedPartitions ( - VOID - ); - -/** - Creates a device path for a firmware file. - - @param[in] FileGuid Firmware file GUID. - - @retval device path allocated from pool on success. - @retval NULL on failure (e.g. when a file is not present). -**/ -EFI_DEVICE_PATH_PROTOCOL * -CreateFvFileDevicePath ( - IN EFI_GUID *FileGuid - ); - -#endif // OC_FILE_LIB_H diff --git a/Include/Library/OcGuardLib.h b/Include/Library/OcGuardLib.h deleted file mode 100644 index 31acbc212..000000000 --- a/Include/Library/OcGuardLib.h +++ /dev/null @@ -1,705 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_GUARD_LIB_H -#define OC_GUARD_LIB_H - -/// -/// Maximum values for common UEFI Data Types -/// -#define MAX_INT8 ((INT8)0x7F) -#define MAX_UINT8 ((UINT8)0xFF) -#define MAX_INT16 ((INT16)0x7FFF) -#define MAX_UINT16 ((UINT16)0xFFFF) -#define MAX_INT32 ((INT32)0x7FFFFFFF) -#define MAX_UINT32 ((UINT32)0xFFFFFFFF) -#define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL) -#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL) - -/// -/// Minimum values for the signed UEFI Data Types -/// -#define MIN_INT8 (((INT8) -127) - 1) -#define MIN_INT16 (((INT16) -32767) - 1) -#define MIN_INT32 (((INT32) -2147483647) - 1) -#define MIN_INT64 (((INT64) -9223372036854775807LL) - 1) - - -// -// The macros below provide compile-time assertions. -// This is important, as UDK only has VERIFY_SIZE_OF, which is limited and broken. -// Since it is implemented as an extern, it neither lets one to verify array size and array -// element size (due to variable redeclaration) at the same time, nor allows macro use -// within a .c file (due to unused variable warnings). -// The reason for split declarations exists due to MSVC legacy. -// -#if defined(__GUNC__) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201100L) -// -// Any supported GCC-compatible implements _Static_assert. -// So do any C11-compliant compilers. -// -#define OC_GLOBAL_STATIC_ASSERT(Expr, Message) _Static_assert (Expr, Message) -#define OC_INLINE_STATIC_ASSERT(Expr, Message) _Static_assert (Expr, Message) -#elif defined(_MSC_VER) && _MSC_VER >= 1600 -// -// Starting from VS 2010 MSVC supports static_assert in both C and C++ modes. -// -#define OC_GLOBAL_STATIC_ASSERT(Expr, Message) static_assert (Expr, Message) -#define OC_INLINE_STATIC_ASSERT(Expr, Message) static_assert (Expr, Message) -#else -// -// For MSVC we implement static assertions via switch, as they do not have compile-time -// offsetof implementation, yet it pointer arithmetics works fine for them in switch. -// The struct declaration is here to avoid a warning for extra ;. -// The concatenation indirection does not permit for multiple assertions on one line -// or within a macro. -// -#define OC_STATIC_ASSERT_CONCAT2(Left, Right) Left ## Right -#define OC_STATIC_ASSERT_CONCAT(Left, Right) OC_STATIC_ASSERT_CONCAT2 (Left, Right) -#define OC_GLOBAL_STATIC_ASSERT(Expr, Message) \ - VOID OC_STATIC_ASSERT_CONCAT(OC_STATIC_ASSERT__, __LINE__) (VOID) { \ - switch (0) { case 0: case (Expr):; } } \ - struct OC_STATIC_ASSERT_CONCAT(OC_STATIC_ASSERT_T__, __LINE__) { UINT32 Dummy; } -#define OC_INLINE_STATIC_ASSERT(Expr, Message) \ - do { switch (0) { case 0: case (Expr):; } } while(0) -#endif - -// -// The macros below provide pointer alignment checking interfaces. -// TypedPtr - pointer of a dedicated type, which alignment is to be checked. -// Align - valid alignment for the target platform (power of two so far). -// Type - valid complete typename. -// Ptr - raw pointer value, must fit into UINTN, meant to be uintptr_t equivalent. -// - -#if defined(OC_FORCE_ALIGN_SUPPORT) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_X64) || defined(MDE_CPU_ARM) || defined(MDE_CPU_IA32) - -#define OC_ALIGNED(TypedPtr) (0ULL == (((UINTN) (TypedPtr)) & \ - (sizeof (*(TypedPtr)) > sizeof (UINTN) ? (sizeof (UINTN) - 1U) : (sizeof (*(TypedPtr)) - 1U)))) - -#define OC_POT_ALIGNED(Align, Ptr) (0ULL == (((UINTN) (Ptr)) & (Align-1))) - -#define OC_TYPE_ALIGNED(Type, Ptr) (0ULL == (((UINTN) (Ptr)) & \ - (sizeof (Type) > sizeof(UINTN) ? (sizeof (UINTN) - 1U) : (sizeof (Type) - 1U)))) - -#else - -#error "Unknown target platform. Alignment macros are not applicable." - -#endif - -// -// The interfaces below provide base safe arithmetics, reporting -// signed integer overflow and unsigned integer wraparound similarly to -// os/overflow.h in macOS SDK. -// -// Each interface may be implemented not only as an actual function, but -// a macro as well. Macro implementations are allowed to evaluate the -// expressions no more than once, and are supposed to provide faster -// compiler builtins if available. -// -// Each interface returns FALSE when the the stored result is equal to -// the infinite precision result, otherwise TRUE. The operands should -// be read left to right with the last argument representing a non-NULL -// pointer to the resulting value of the same type. -// -// More information could be found in Clang Extensions documentation: -// http://releases.llvm.org/7.0.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins -// - -// -// 32-bit integer addition, subtraction, multiplication, triple addition (A+B+C), -// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), -// and multiplication with addition (A*B+C) support. -// - -BOOLEAN -OcOverflowAddU32 ( - UINT32 A, - UINT32 B, - UINT32 *Result - ); - -BOOLEAN -OcOverflowSubU32 ( - UINT32 A, - UINT32 B, - UINT32 *Result - ); - -BOOLEAN -OcOverflowMulU32 ( - UINT32 A, - UINT32 B, - UINT32 *Result - ); - -BOOLEAN -OcOverflowTriAddU32 ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ); - -BOOLEAN -OcOverflowTriMulU32 ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ); - -BOOLEAN -OcOverflowAddMulU32 ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ); - -BOOLEAN -OcOverflowMulAddU32 ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ); - -BOOLEAN -OcOverflowAddS32 ( - INT32 A, - INT32 B, - INT32 *Result - ); - -BOOLEAN -OcOverflowSubS32 ( - INT32 A, - INT32 B, - INT32 *Result - ); - -BOOLEAN -OcOverflowMulS32 ( - INT32 A, - INT32 B, - INT32 *Result - ); - -BOOLEAN -OcOverflowTriAddS32 ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ); - -BOOLEAN -OcOverflowTriMulS32 ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ); - -BOOLEAN -OcOverflowAddMulS32 ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ); - -BOOLEAN -OcOverflowMulAddS32 ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ); - -// -// 64-bit integer addition, subtraction, multiplication, triple addition (A+B+C), -// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), -// and multiplication with addition (A*B+C) support. -// - -BOOLEAN -OcOverflowAddU64 ( - UINT64 A, - UINT64 B, - UINT64 *Result - ); - -BOOLEAN -OcOverflowSubU64 ( - UINT64 A, - UINT64 B, - UINT64 *Result - ); - -BOOLEAN -OcOverflowMulU64 ( - UINT64 A, - UINT64 B, - UINT64 *Result - ); - -BOOLEAN -OcOverflowTriAddU64 ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ); - -BOOLEAN -OcOverflowTriMulU64 ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ); - -BOOLEAN -OcOverflowAddMulU64 ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ); - -BOOLEAN -OcOverflowMulAddU64 ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ); - - -BOOLEAN -OcOverflowAddS64 ( - INT64 A, - INT64 B, - INT64 *Result - ); - -BOOLEAN -OcOverflowSubS64 ( - INT64 A, - INT64 B, - INT64 *Result - ); - -BOOLEAN -OcOverflowMulS64 ( - INT64 A, - INT64 B, - INT64 *Result - ); - -BOOLEAN -OcOverflowTriAddS64 ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ); - -BOOLEAN -OcOverflowTriMulS64 ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ); - -BOOLEAN -OcOverflowAddMulS64 ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ); - -BOOLEAN -OcOverflowMulAddS64 ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ); - -// -// Native integer addition, subtraction, multiplication, triple addition (A+B+C), -// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), -// and multiplication with addition (A*B+C) support. -// - -BOOLEAN -OcOverflowAddUN ( - UINTN A, - UINTN B, - UINTN *Result - ); - -BOOLEAN -OcOverflowSubUN ( - UINTN A, - UINTN B, - UINTN *Result - ); - -BOOLEAN -OcOverflowMulUN ( - UINTN A, - UINTN B, - UINTN *Result - ); - -BOOLEAN -OcOverflowTriAddUN ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ); - -BOOLEAN -OcOverflowTriMulUN ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ); - -BOOLEAN -OcOverflowAddMulUN ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ); - -BOOLEAN -OcOverflowMulAddUN ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ); - -BOOLEAN -OcOverflowAddSN ( - INTN A, - INTN B, - INTN *Result - ); - -BOOLEAN -OcOverflowSubSN ( - INTN A, - INTN B, - INTN *Result - ); - -BOOLEAN -OcOverflowMulSN ( - INTN A, - INTN B, - INTN *Result - ); - -BOOLEAN -OcOverflowTriAddSN ( - INTN A, - INTN B, - INTN C, - INTN *Result - ); - -BOOLEAN -OcOverflowTriMulSN ( - INTN A, - INTN B, - INTN C, - INTN *Result - ); - -BOOLEAN -OcOverflowAddMulSN ( - INTN A, - INTN B, - INTN C, - INTN *Result - ); - -BOOLEAN -OcOverflowMulAddSN ( - INTN A, - INTN B, - INTN C, - INTN *Result - ); - -// -// Macro implemenations of the above declarations -// - -#ifdef __has_builtin - -// -// Type-generic checkers are available -// -#if __has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow) && __has_builtin(__builtin_mul_overflow) - -#define OcOverflowAddU32(A, B, Res) __builtin_add_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowSubU32(A, B, Res) __builtin_sub_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowMulU32(A, B, Res) __builtin_mul_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowAddS32(A, B, Res) __builtin_add_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) -#define OcOverflowSubS32(A, B, Res) __builtin_sub_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) -#define OcOverflowMulS32(A, B, Res) __builtin_mul_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) - -#define OcOverflowAddU64(A, B, Res) __builtin_add_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowSubU64(A, B, Res) __builtin_sub_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowMulU64(A, B, Res) __builtin_mul_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowAddS64(A, B, Res) __builtin_add_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) -#define OcOverflowSubS64(A, B, Res) __builtin_sub_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) -#define OcOverflowMulS64(A, B, Res) __builtin_mul_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) - -#define OcOverflowAddUN(A, B, Res) __builtin_add_overflow((UINTN)(A), (UINTN)(B), (UINTN *)(Res)) -#define OcOverflowSubUN(A, B, Res) __builtin_sub_overflow((UINTN)(A), (UINTN)(B), (UINTN *)(Res)) -#define OcOverflowMulUN(A, B, Res) __builtin_mul_overflow((UINTN)(A), (UINTN)(B), (UINTN *)(Res)) -#define OcOverflowAddSN(A, B, Res) __builtin_add_overflow((INTN)(A), (INTN)(B), (INTN *)(Res)) -#define OcOverflowSubSN(A, B, Res) __builtin_sub_overflow((INTN)(A), (INTN)(B), (INTN *)(Res)) -#define OcOverflowMulSN(A, B, Res) __builtin_mul_overflow((INTN)(A), (INTN)(B), (INTN *)(Res)) - -#elif defined(__GNUC__) || defined(__clang__) - -// -// Builtin type checkers are available, but we have to match their sizes. -// For this reason we force the list of supported architectures here based on ProcessorBind.h, -// and with the assumption that CHAR_BIT is 8. -// - -// -// Implement 32-bit intrinsics with int and unsigned int on architectures that support it. -// -#if defined(MDE_CPU_AARCH64) || defined(MDE_CPU_ARM) || defined(MDE_CPU_X64) || defined(MDE_CPU_IA32) - -VERIFY_SIZE_OF (int, 4); -VERIFY_SIZE_OF (unsigned, 4); - -#define OcOverflowAddU32(A, B, Res) __builtin_uadd_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowSubU32(A, B, Res) __builtin_usub_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowMulU32(A, B, Res) __builtin_umul_overflow((UINT32)(A), (UINT32)(B), (UINT32 *)(Res)) -#define OcOverflowAddS32(A, B, Res) __builtin_sadd_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) -#define OcOverflowSubS32(A, B, Res) __builtin_ssub_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) -#define OcOverflowMulS32(A, B, Res) __builtin_smul_overflow((INT32)(A), (INT32)(B), (INT32 *)(Res)) - -#endif // 32-bit integer support - -// -// Implement 64-bit intrinsics with long long and unsigned long long on architectures that support it. -// Note: ProcessorBind.h may use long on X64, but it is as large as long long. -// -#if defined(MDE_CPU_AARCH64) || defined(MDE_CPU_ARM) || defined(MDE_CPU_X64) || defined(MDE_CPU_IA32) - -typedef long long oc_guard_long_long; -typedef unsigned long long oc_guard_unsigned_long_long; - -VERIFY_SIZE_OF (oc_guard_long_long, 8); -VERIFY_SIZE_OF (oc_guard_unsigned_long_long, 8); - -#define OcOverflowAddU64(A, B, Res) __builtin_uaddll_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowSubU64(A, B, Res) __builtin_usubll_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowMulU64(A, B, Res) __builtin_umulll_overflow((UINT64)(A), (UINT64)(B), (UINT64 *)(Res)) -#define OcOverflowAddS64(A, B, Res) __builtin_saddll_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) -#define OcOverflowSubS64(A, B, Res) __builtin_ssubll_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) -#define OcOverflowMulS64(A, B, Res) __builtin_smulll_overflow((INT64)(A), (INT64)(B), (INT64 *)(Res)) - -#endif // 64-bit integer support - -// -// Implement native intrinsics with 32-bit or 64-bit intrinsics depending on the support. -// -#if defined(MDE_CPU_AARCH64) || defined(MDE_CPU_X64) - -VERIFY_SIZE_OF (INTN, 8); -VERIFY_SIZE_OF (UINTN, 8); - -#define OcOverflowAddUN(A, B, Res) OcOverflowAddU64((A), (B), (Res)) -#define OcOverflowSubUN(A, B, Res) OcOverflowSubU64((A), (B), (Res)) -#define OcOverflowMulUN(A, B, Res) OcOverflowMulU64((A), (B), (Res)) -#define OcOverflowAddSN(A, B, Res) OcOverflowAddS64((A), (B), (Res)) -#define OcOverflowSubSN(A, B, Res) OcOverflowSubS64((A), (B), (Res)) -#define OcOverflowMulSN(A, B, Res) OcOverflowMulS64((A), (B), (Res)) - -#elif defined(MDE_CPU_ARM) || defined(MDE_CPU_IA32) - -VERIFY_SIZE_OF (INTN, 4); -VERIFY_SIZE_OF (UINTN, 4); - -#define OcOverflowAddUN(A, B, Res) OcOverflowAddU32((A), (B), (Res)) -#define OcOverflowSubUN(A, B, Res) OcOverflowSubU32((A), (B), (Res)) -#define OcOverflowMulUN(A, B, Res) OcOverflowMulU32((A), (B), (Res)) -#define OcOverflowAddSN(A, B, Res) OcOverflowAddS32((A), (B), (Res)) -#define OcOverflowSubSN(A, B, Res) OcOverflowSubS32((A), (B), (Res)) -#define OcOverflowMulSN(A, B, Res) OcOverflowMulS32((A), (B), (Res)) - -#endif // native integer support - -#endif // type integer support - -#endif // __has_builtin - -#if defined(__GNUC__) || defined(__clang__) - -// -// Macro implementations for compilers supporting Statement Expressions: -// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html -// - -#define OcOverflowTriAddU32(A, B, C, Res) ({ \ - UINT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddU32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddU32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulU32(A, B, C, Res) ({ \ - UINT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulU32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulU32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulU32(A, B, C, Res) ({ \ - UINT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddU32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulU32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddU32(A, B, C, Res) ({ \ - UINT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulU32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddU32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriAddS32(A, B, C, Res) ({ \ - INT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddS32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddS32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulS32(A, B, C, Res) ({ \ - INT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulS32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulS32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulS32(A, B, C, Res) ({ \ - INT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddS32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulS32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddS32(A, B, C, Res) ({ \ - INT32 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulS32((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddS32(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) - -#define OcOverflowTriAddU64(A, B, C, Res) ({ \ - UINT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddU64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddU64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulU64(A, B, C, Res) ({ \ - UINT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulU64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulU64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulU64(A, B, C, Res) ({ \ - UINT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddU64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulU64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddU64(A, B, C, Res) ({ \ - UINT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulU64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddU64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriAddS64(A, B, C, Res) ({ \ - INT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddS64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddS64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulS64(A, B, C, Res) ({ \ - INT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulS64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulS64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulS64(A, B, C, Res) ({ \ - INT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddS64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulS64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddS64(A, B, C, Res) ({ \ - INT64 OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulS64((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddS64(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) - -#define OcOverflowTriAddUN(A, B, C, Res) ({ \ - UINTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddUN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddUN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulUN(A, B, C, Res) ({ \ - UINTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulUN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulUN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulUN(A, B, C, Res) ({ \ - UINTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddUN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulUN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddUN(A, B, C, Res) ({ \ - UINTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulUN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddUN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriAddSN(A, B, C, Res) ({ \ - INTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddSN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddSN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowTriMulSN(A, B, C, Res) ({ \ - INTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulSN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulSN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowAddMulSN(A, B, C, Res) ({ \ - INTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowAddSN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowMulSN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) -#define OcOverflowMulAddSN(A, B, C, Res) ({ \ - INTN OcTmp__; BOOLEAN OcFirst__, OcSecond__; \ - OcFirst__ = OcOverflowMulSN((A), (B), &OcTmp__); \ - OcSecond__ = OcOverflowAddSN(OcTmp__, (C), (Res)); \ - OcFirst__ | OcSecond__; }) - -#endif // __GNUC__ - -#endif // OC_GUARD_LIB_H diff --git a/Include/Library/OcMemoryLib.h b/Include/Library/OcMemoryLib.h deleted file mode 100644 index c425fa700..000000000 --- a/Include/Library/OcMemoryLib.h +++ /dev/null @@ -1,539 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_MEMORY_LIB_H -#define OC_MEMORY_LIB_H - -#include -#include -#include - -/** - Reverse equivalent of NEXT_MEMORY_DESCRIPTOR. -**/ -#define PREV_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) - -/** - Get last descriptor address. - It is assumed that the descriptor contains pages. -**/ -#define LAST_DESCRIPTOR_ADDR(Desc) \ - ((Desc)->PhysicalStart + (EFI_PAGES_TO_SIZE ((UINTN) (Desc)->NumberOfPages) - 1)) - -/** - Check if area is within the specified descriptor. - It is assumed that the descriptor contains pages and AreaSize is not 0. -**/ -#define AREA_WITHIN_DESCRIPTOR(Desc, Area, AreaSize) \ - ((Area) >= (Desc)->PhysicalStart && ((Area) + ((AreaSize) - 1)) <= LAST_DESCRIPTOR_ADDR (Desc)) - -/** - Reasonable default virtual memory page pool size (2 MB). -**/ -#define OC_DEFAULT_VMEM_PAGE_COUNT 0x200 - -/** - Reasonable default memory map size used when allocations are problematic. - Note, that MacPro5,1 is known to have 8880 memory map. -**/ -#define OC_DEFAULT_MEMORY_MAP_SIZE (EFI_PAGE_SIZE*3) - -/** - Lock the legacy region specified to enable modification. - - @param[in] LegacyAddress The address of the region to lock. - @param[in] LegacyLength The size of the region to lock. - - @retval EFI_SUCCESS The region was locked successfully. -**/ -EFI_STATUS -LegacyRegionLock ( - IN UINT32 LegacyAddress, - IN UINT32 LegacyLength - ); - -/** - Unlock the legacy region specified to enable modification. - - @param[in] LegacyAddress The address of the region to unlock. - @param[in] LegacyLength The size of the region to unlock. - - @retval EFI_SUCCESS The region was unlocked successfully. -**/ -EFI_STATUS -LegacyRegionUnlock ( - IN UINT32 LegacyAddress, - IN UINT32 LegacyLength - ); - -/** - Get current memory map allocated on pool with reserved entries. - - @param[out] MemoryMapSize Resulting memory map size in bytes. - @param[out] DescriptorSize Resulting memory map descriptor size in bytes. - @param[out] MapKey Memory map key, optional. - @param[out] DescriptorVersion Memory map descriptor version, optional. - @param[out] OriginalMemoryMapSize Actual pool allocation memory, optional. - @param[out] IncludeSplitSpace Allocate memory to permit splitting memory map. - - @retval current memory map or NULL. -**/ -EFI_MEMORY_DESCRIPTOR * -OcGetCurrentMemoryMap ( - OUT UINTN *MemoryMapSize, - OUT UINTN *DescriptorSize, - OUT UINTN *MapKey OPTIONAL, - OUT UINT32 *DescriptorVersion OPTIONAL, - OUT UINTN *OriginalMemoryMapSize OPTIONAL, - IN BOOLEAN IncludeSplitSpace - ); - -/** - Get current memory map of custom allocation. - - @param[out] MemoryMapSize Resulting memory map size in bytes. - @param[out] MemoryMap Resulting memory map. - @param[out] MapKey Memory map key. - @param[out] DescriptorSize Resulting memory map descriptor size in bytes. - @param[out] DescriptorVersion Memory map descriptor version. - @param[in] GetMemoryMap Custom GetMemoryMap implementation to use, optional. - @param[in,out] TopMemory Base top address for OcAllocatePagesFromTop allocation, number of pages after return. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcGetCurrentMemoryMapAlloc ( - OUT UINTN *MemoryMapSize, - OUT EFI_MEMORY_DESCRIPTOR **MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN OUT EFI_PHYSICAL_ADDRESS *TopMemory OPTIONAL - ); - -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -VOID -OcSortMemoryMap ( - IN UINTN MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Shrink memory map by joining non-runtime records. - Requires sorted memory map. - - @param[in,out] MemoryMapSize Memory map size in bytes, updated on shrink. - @param[in,out] MemoryMap Memory map to shrink. - @param[in] DescriptorSize Memory map descriptor size in bytes. - - @retval EFI_SUCCESS on success. - @retval EFI_NOT_FOUND when cannot join anything. -**/ -EFI_STATUS -OcShrinkMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Deduplicate memory descriptors. Requires sorted entry list. - - @param[in,out] EntryCount Memory map size in entries, updated on shrink. - @param[in,out] MemoryMap Memory map to shrink. - @param[in] DescriptorSize Memory map descriptor size in bytes. - - @retval EFI_SUCCESS on success. - @retval EFI_NOT_FOUND when cannot join anything. -**/ -EFI_STATUS -OcDeduplicateDescriptors ( - IN OUT UINT32 *EntryCount, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Check range allocation compatibility callback. - - @param[in] Address Starting address. - @param[in] Size Size of memory range. - - @retval TRUE when suitable for allocation. -**/ -typedef -BOOLEAN -(*CHECK_ALLOCATION_RANGE) ( - IN EFI_PHYSICAL_ADDRESS Address, - IN UINTN Size - ); - -/** - Filter memory map entries. - - @param[in] Context Parameterised filter data. - @param[in,out] MemoryMapSize Memory map size in bytes. - @param[in,out] MemoryMap Memory map to filter. - @param[in] DescriptorSize Memory map descriptor size in bytes. -**/ -typedef -VOID -(*OC_MEMORY_FILTER) ( - IN VOID *Context OPTIONAL, - IN UINTN MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Allocate pages from the top of physical memory up to address specified in Memory. - Unlike AllocateMaxAddress, this method guarantees to choose top most address. - - @param[in] MemoryType Allocated memory type. - @param[in] Pages Amount of pages to allocate. - @param[in,out] Memory Top address for input, allocated address for output. - @param[in] GetMemoryMap Custom GetMemoryMap implementation to use, optional. - @param[in] CheckRange Handler allowing to not allocate select ranges, optional. - - @retval EFI_SUCCESS on successful allocation. -**/ -EFI_STATUS -OcAllocatePagesFromTop ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN CHECK_ALLOCATION_RANGE CheckRange OPTIONAL - ); - -/** - Calculate number of runtime pages in the memory map. - - @param[in] MemoryMapSize Memory map size in bytes. - @param[in] MemoryMap Memory map to inspect. - @param[in] DescriptorSize Memory map descriptor size in bytes. - @param[out] DescriptorCount Number of relevant descriptors, optional. - - @retval Number of runtime pages. -**/ -UINT64 -OcCountRuntimePages ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize, - OUT UINTN *DescriptorCount OPTIONAL - ); - -/** - Calculate number of free pages in the memory map. - - @param[out] LowerMemory Number of free pages below 4 GB, optional. - - @retval Number of free pages. -**/ -UINTN -OcCountFreePages ( - OUT UINTN *LowerMemory OPTIONAL - ); - -/** - Print memory attributes table if present. -**/ -VOID -OcPrintMemoryAttributesTable ( - VOID - ); - -/** - Print memory map. - - @param[in] MemoryMapSize Memory map size in bytes. - @param[in] MemoryMap Memory map to print. - @param[in] DescriptorSize Memory map descriptor size in bytes. -**/ -VOID -OcPrintMemoryMap ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Refresh memory descriptor containing the specified address. - - @param[in] MemoryMapSize Memory map size in bytes. - @param[in] MemoryMap Memory map to refresh. - @param[in] DescriptorSize Memory map descriptor size in bytes. - @param[in] Address Address contained in the updated entry. - @param[in] Type Memory type to assign to the entry. - @param[in] SetAttributes Attributes to set. - @param[in] DropAttributes Attributes to remove. - - @retval EFI_SUCCESS on success. - @retval EFI_NOT_FOUND no entry contains the specified address. - @retval EFI_UNSUPPORTED memory attributes are not supported by the platform. -**/ -EFI_STATUS -OcUpdateDescriptors ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize, - IN EFI_PHYSICAL_ADDRESS Address, - IN EFI_MEMORY_TYPE Type, - IN UINT64 SetAttributes, - IN UINT64 DropAttributes - ); - -/** - Obtain memory attributes table. - - @param[out] MemoryAttributesEntry memory descriptor pointer, optional. - - @retval pointer to memory attributes table. - @retval NULL if memory attributes table is unsupported. -**/ -EFI_MEMORY_ATTRIBUTES_TABLE * -OcGetMemoryAttributes ( - OUT EFI_MEMORY_DESCRIPTOR **MemoryAttributesEntry OPTIONAL - ); - -/** - Refresh memory attributes entry containing the specified address. - - @param[in] Address Address contained in the updated entry. - @param[in] GetMemoryMap - - @retval EFI_SUCCESS on success. - @retval EFI_NOT_FOUND no entry contains the specified address. - @retval EFI_UNSUPPORTED memory attributes are not supported by the platform. -**/ -EFI_STATUS -OcRebuildAttributes ( - IN EFI_PHYSICAL_ADDRESS Address, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ); - -/** - Count upper bound of split runtime descriptors. - - @retval amount of runtime descriptors. -**/ -UINTN -OcCountSplitDescriptors ( - VOID - ); - -/** - Split memory map by memory attributes if available. - Requires sorted memory map! - - @param[in] MaxMemoryMapSize Upper memory map size bound for growth. - @param[in,out] MemoryMapSize Current memory map size, updated on return. - @param[in,out] MemoryMap Memory map to split. - @param[in] DescriptorSize Memory map descriptor size. - - Note, the function is guaranteed to return valid memory map, though not necessarily split. - - @retval EFI_SUCCESS on success. - @retval EFI_UNSUPPORTED memory attributes are not supported by the platform. - @retval EFI_OUT_OF_RESOURCES new memory map did not fit. -**/ -EFI_STATUS -OcSplitMemoryMapByAttributes ( - IN UINTN MaxMemoryMapSize, - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ); - -/** - Return pointer to PML4 table in PageTable and PWT and PCD flags in Flags. - - @param[out] Flags Current page table PWT and PCT flags. - - @retval Current page table address. -**/ -PAGE_MAP_AND_DIRECTORY_POINTER * -OcGetCurrentPageTable ( - OUT UINTN *Flags OPTIONAL - ); - -/** - Return physical addrress for given virtual addrress. - - @param[in] PageTable Page table to use for solving. - @param[in] VirtualAddr Virtual address to look up. - @param[out] PhysicalAddr Physical address to return. - - @retval EFI_SUCCESS on successful lookup. -**/ -EFI_STATUS -OcGetPhysicalAddress ( - IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr - ); - -/** - Virtual memory context -**/ -typedef struct OC_VMEM_CONTEXT_ { - /// - /// Memory pool containing memory to be spread across allocations. - /// - UINT8 *MemoryPool; - /// - /// Free pages in the memory pool. - /// - UINTN FreePages; -} OC_VMEM_CONTEXT; - -/** - Allocate EfiBootServicesData virtual memory pool from boot services - in the end of BASE_4GB of RAM. Should be called while boot services are - still usable. - - @param[out] Context Virtual memory pool context. - @param[in] NumPages Number of pages to be allocated in the pool. - @param[in] GetMemoryMap Custom GetMemoryMap implementation to use, optional. - - @retval EFI_SUCCESS on successful allocation. -**/ -EFI_STATUS -VmAllocateMemoryPool ( - OUT OC_VMEM_CONTEXT *Context, - IN UINTN NumPages, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ); - -/** - Allocate pages for e.g. vm page maps. - - @param[in,out] Context Virtual memory pool context. - @param[in] NumPages Number of pages to allocate. - - @retval allocated pages or NULL. -**/ -VOID * -VmAllocatePages ( - IN OUT OC_VMEM_CONTEXT *Context, - IN UINTN NumPages - ); - -/** - Map (remap) given page at physical address to given virtual address in - the specified page table. - - @param[in,out] Context Virtual memory pool context. - @param[in] PageTable Page table to update. - @param[in] VirtualAddr Virtual memory address to map at. - @param[in] PhysicalAddr Physical memory address to map from. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -VmMapVirtualPage ( - IN OUT OC_VMEM_CONTEXT *Context, - IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr - ); - -/** - Map (remap) a range of 4K pages at physical address to given virtual address - in the specified page table. - - @param[in,out] Context Virtual memory pool context. - @param[in] PageTable Page table to update. - @param[in] VirtualAddr Virtual memory address to map at. - @param[in] NumPages Number of 4K pages to map. - @param[in] PhysicalAddr Physical memory address to map from. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -VmMapVirtualPages ( - IN OUT OC_VMEM_CONTEXT *Context, - IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - IN UINT64 NumPages, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr - ); - -/** - Flushes TLB caches. -**/ -VOID -VmFlushCaches ( - VOID - ); - -/** - Check whether built-in allocator is initialized. - - @retval TRUE on success. -**/ -BOOLEAN -UmmInitialized ( - VOID - ); - -/** - Initialize built-in allocator. - - @param[in] Heap Memory pool used for allocations. - @param[in] Size Memory pool size. -**/ -VOID -UmmSetHeap ( - IN VOID *Heap, - IN UINT32 Size - ); - -/** - Perform allocation from built-in allocator. - - @param[in] Size Allocation size. - - @retval allocated memory on success. -**/ -VOID * -UmmMalloc ( - IN UINT32 Size - ); - -/** - Perform free of allocated memory. Accepts NULL pointer - and checks whether memory belongs to itself. - - @param[in] Ptr Memory to free. - - @retval TRUE on success -**/ -BOOLEAN -UmmFree ( - IN VOID *Ptr - ); - -#endif // OC_MEMORY_LIB_H diff --git a/Include/Library/OcMiscLib.h b/Include/Library/OcMiscLib.h deleted file mode 100755 index 55101bb95..000000000 --- a/Include/Library/OcMiscLib.h +++ /dev/null @@ -1,183 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_MISC_LIB_H -#define OC_MISC_LIB_H - -#include -#include - -/** - The size, in Bits, of one Byte. -**/ -#define OC_CHAR_BIT 8 - -/** - Convert seconds to microseconds for use in e.g. gBS->Stall. -**/ -#define SECONDS_TO_MICROSECONDS(x) ((x)*1000000) - -INT32 -FindPattern ( - IN CONST UINT8 *Pattern, - IN CONST UINT8 *PatternMask OPTIONAL, - IN CONST UINT32 PatternSize, - IN CONST UINT8 *Data, - IN UINT32 DataSize, - IN INT32 DataOff - ); - -UINT32 -ApplyPatch ( - IN CONST UINT8 *Pattern, - IN CONST UINT8 *PatternMask OPTIONAL, - IN CONST UINT32 PatternSize, - IN CONST UINT8 *Replace, - IN CONST UINT8 *ReplaceMask OPTIONAL, - IN UINT8 *Data, - IN UINT32 DataSize, - IN UINT32 Count, - IN UINT32 Skip - ); - -/** - Obtain application arguments. - - @param[out] Argc Argument count. - @param[out] Argv Argument list. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -GetArguments ( - OUT UINTN *Argc, - OUT CHAR16 ***Argv - ); - -/** - Uninstall all protocols with the specified GUID. - - @param[in] Protocol The published unique identifier of the protocol. It is the caller's responsibility to pass in - a valid GUID. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcUninstallAllProtocolInstances ( - EFI_GUID *Protocol - ); - -/** - Handle protocol on handle and fallback to any protocol when missing. - - @param[in] Handle Handle to search for protocol. - @param[in] Protocol Protocol to search for. - @param[out] Interface Protocol interface if found. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcHandleProtocolFallback ( - IN EFI_HANDLE Handle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ); - -/** - Release UEFI ownership from USB controllers at booting. -**/ -EFI_STATUS -ReleaseUsbOwnership ( - VOID - ); - -/** - Perform cold reboot directly bypassing UEFI services. Does not return. - Supposed to work in any modern physical or virtual environment. -**/ -VOID -DirectRestCold ( - VOID - ); - -/** - Return the result of (Multiplicand * Multiplier / Divisor). - - @param Multiplicand A 64-bit unsigned value. - @param Multiplier A 64-bit unsigned value. - @param Divisor A 32-bit unsigned value. - @param Remainder A pointer to a 32-bit unsigned value. This parameter is - optional and may be NULL. - - @return Multiplicand * Multiplier / Divisor. - **/ -UINT64 -MultThenDivU64x64x32 ( - IN UINT64 Multiplicand, - IN UINT64 Multiplier, - IN UINT32 Divisor, - OUT UINT32 *Remainder OPTIONAL - ); - -/** - Internal worker macro that calls DebugPrint(). - - This macro calls DebugPrint(), passing in the filename, line number, an - expression that failed the comparison with expected value, - the expected value and the actual value. - - @param Expression Integer expression that evaluated to value different from Value (should be convertible to INTN) - @param ExpectedValue Expected value of the expression (should be convertible to INTN) - -**/ -#define _ASSERT_EQUALS(Expression, ExpectedValue) \ - DebugPrint( \ - DEBUG_ERROR, \ - "ASSERT %a(%d): %a (expected: %d, actual: %d)\n", \ - __FILE__, \ - __LINE__, \ - #Expression, \ - (INTN)(ExpectedValue), \ - (INTN)(Expression)) - -/** - Macro that calls DebugAssert() if the value of an expression differs from the expected value. - - If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED - bit of PcdDebugProperyMask is set, then this macro evaluates the integer - expression specified by Expression. If the value of Expression differs from ExpectedValue, then - DebugPrint() is called passing in the source filename, source line number, - Expression, it's value and ExpectedValue; then ASSERT(FALSE) is called to - cause a breakpoint, deadloop or no-op depending on PcdDebugProperyMask. - - @param Expression Integer expression (should be convertible to INTN). - @param ExpectedValue Expected value (should be convertible to INTN). - -**/ -#if !defined(MDEPKG_NDEBUG) - #define ASSERT_EQUALS(Expression, ExpectedValue) \ - do { \ - if (DebugAssertEnabled ()) { \ - if ((Expression) != (ExpectedValue)) { \ - _ASSERT_EQUALS (Expression, ExpectedValue); \ - ASSERT(FALSE); \ - ANALYZER_UNREACHABLE (); \ - } \ - } \ - } while (FALSE) -#else - #define ASSERT_EQUALS(Expression, ExpectedValue) -#endif - -#endif // OC_MISC_LIB_H diff --git a/Include/Library/OcOSInfoLib.h b/Include/Library/OcOSInfoLib.h deleted file mode 100644 index 5220618a2..000000000 --- a/Include/Library/OcOSInfoLib.h +++ /dev/null @@ -1,32 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_OS_INFO_LIB_H -#define OC_OS_INFO_LIB_H - -#include - -/** - Install and initialise OS Info protocol. - - @param[in] Reinstall Overwrite installed protocol. - - @retval installed or located protocol or NULL. -**/ -EFI_OS_INFO_PROTOCOL * -OcOSInfoInstallProtocol ( - IN BOOLEAN Reinstall - ); - -#endif // OC_OS_INFO_LIB_H diff --git a/Include/Library/OcRngLib.h b/Include/Library/OcRngLib.h deleted file mode 100644 index c0a04a0ad..000000000 --- a/Include/Library/OcRngLib.h +++ /dev/null @@ -1,59 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_RNG_LIB_H -#define OC_RNG_LIB_H - -#include - -/** - Generates a 16-bit pseudo random number. - This generator is still guaranteed to be cryptographically secure - by the use of CPRNG with entropy. - - @retval 16-bit pseudo random number. -**/ -UINT16 -EFIAPI -GetPseudoRandomNumber16 ( - VOID - ); - -/** - Generates a 32-bit pseudo random number. - This generator is still guaranteed to be cryptographically secure - by the use of CPRNG with entropy. - - @retval 32-bit pseudo random number. -**/ -UINT32 -EFIAPI -GetPseudoRandomNumber32 ( - VOID - ); - -/** - Generates a 64-bit pseudo random number. - This generator is still guaranteed to be cryptographically secure - by the use of CPRNG with entropy. - - @retval 64-bit pseudo random number. -**/ -UINT64 -EFIAPI -GetPseudoRandomNumber64 ( - VOID - ); - -#endif // OC_RNG_LIB_H diff --git a/Include/Library/OcRtcLib.h b/Include/Library/OcRtcLib.h deleted file mode 100644 index d87262d57..000000000 --- a/Include/Library/OcRtcLib.h +++ /dev/null @@ -1,94 +0,0 @@ -/** @file - -OcRtcLib - library with RTC I/O functions - -Copyright (c) 2017-2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_RTC_LIB_H -#define OC_RTC_LIB_H - -#include - -// -// Standard interface, available on most Intel chipsets -// - -UINT8 -OcRtcRead ( - IN UINT8 Offset - ); - -VOID -OcRtcWrite ( - IN UINT8 Offset, - IN UINT8 Value - ); - -/** - Calculate Apple CMOS checksum. - This is a modified version of ANSI CRC16 in REFIN mode (0xA001 poly). - See http://zlib.net/crc_v3.txt for more details. - - 1. Effective poly is 0x2001 due to a bitwise OR with BIT15. - The change turns CRC16 into CRC14, making BIT14 and BIT15 always zero. - This modification is commonly found in legacy Phoenix firmwares, - where it was used for password hashing as found by dogbert: - http://sites.google.com/site/dogber1/blag/pwgen-5dec.py - - 2. Only 7 shifts per byte are performed instead of the usual 8. - This might improve checksum quality against specific data, but the exact - reasons are unknown. The algorithm did not change since its introduction - in 10.4.x, and since Apple Developer Transition Kit was based on Phoenix - firmware, this could just be a quick change to get a different checksum. - - @param[in] Data Pointer to data to calculate the checksum of. - @param[in] Size Size of data. - - @retval Resulting checksum. -**/ -UINT16 -OcRtcChecksumApple ( - IN CONST VOID *Data, - IN UINTN Size - ); - -/** - Install and initialise Apple RTC RAM protocol. - - @param[in] Reinstall Overwrite installed protocol. - - @retval installed or located protocol or NULL. -**/ -APPLE_RTC_RAM_PROTOCOL * -OcAppleRtcRamInstallProtocol ( - IN BOOLEAN Reinstall - ); - -// -// Modern faster interface, available on IvyBridge or newer -// - -UINT8 -OcRtcReadIvy ( - IN UINT8 Offset - ); - -VOID -OcRtcWriteIvy ( - IN UINT8 Offset, - IN UINT8 Value - ); - -#endif // OC_RTC_LIB_H diff --git a/Include/Library/OcSerializeLib.h b/Include/Library/OcSerializeLib.h deleted file mode 100644 index 026e70ba4..000000000 --- a/Include/Library/OcSerializeLib.h +++ /dev/null @@ -1,337 +0,0 @@ -/** @file - -OcSerializeLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_SERIALIZE_LIB_H -#define OC_SERIALIZE_LIB_H - -#include -#include - -typedef struct OC_SCHEMA_ OC_SCHEMA; -typedef union OC_SCHEMA_INFO_ OC_SCHEMA_INFO; - -// -// Generic applier interface that knows how to provide Info with data from Node. -// -typedef -VOID -(*OC_APPLY) ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// OC_SCHEMA_INFO for nested dictionaries -// -typedef struct { - // - // Nested schema list. - // - OC_SCHEMA *Schema; - // - // Nested schema list size. - // - UINT32 SchemaSize; -} OC_SCHEMA_DICT; - -// -// OC_SCHEMA_INFO for static values -// - -typedef enum OC_SCHEMA_VALUE_TYPE_ { - OC_SCHEMA_VALUE_BOOLEAN, - OC_SCHEMA_VALUE_INTEGER, - OC_SCHEMA_VALUE_DATA, - OC_SCHEMA_VALUE_STRING, - OC_SCHEMA_VALUE_MDATA -} OC_SCHEMA_VALUE_TYPE; - -typedef struct { - // - // Value pointer. - // - UINTN Field; - // - // Value size. - // - UINT32 FieldSize; - // - // Source type. - // - OC_SCHEMA_VALUE_TYPE Type; -} OC_SCHEMA_VALUE; - -// -// OC_SCHEMA_INFO for blob values -// - -typedef enum OC_SCHEMA_BLOB_TYPE_ { - OC_SCHEMA_BLOB_DATA, - OC_SCHEMA_BLOB_STRING, - OC_SCHEMA_BLOB_MDATA -} OC_SCHEMA_BLOB_TYPE; - -typedef struct { - // - // Blob pointer. - // - UINTN Field; - // - // Source type. - // - OC_SCHEMA_BLOB_TYPE Type; -} OC_SCHEMA_BLOB; - -// -// OC_SCHEMA_INFO for array/map lists -// -typedef struct { - // - // List pointer. - // - UINTN Field; - // - // List entry schema. - // - OC_SCHEMA *Schema; -} OC_SCHEMA_LIST; - -// -// All standard variants of schema info -// -union OC_SCHEMA_INFO_ { - OC_SCHEMA_DICT Dict; - OC_SCHEMA_VALUE Value; - OC_SCHEMA_BLOB Blob; - OC_SCHEMA_LIST List; -}; - -// -// Schema context, allowing node recursion. -// -struct OC_SCHEMA_ { - // - // Key name to match against in the dictionary. - // - CONST CHAR8 *Name; - // - // Node type required to match to be able to call Apply. - // PLIST_NODE_TYPE_ANY could be specified if Apply does the validation. - // - PLIST_NODE_TYPE Type; - // - // Apply handler that will merge Node data into object. - // - OC_APPLY Apply; - // - // Information about Node to object bridge. - // - OC_SCHEMA_INFO Info; -}; - -// -// Find schema in a sorted list -// -OC_SCHEMA * -LookupConfigSchema ( - IN OC_SCHEMA *SortedList, - IN UINT32 Size, - IN CONST CHAR8 *Name - ); - -// -// Apply interface to parse serialized dictionaries -// -VOID -ParseSerializedDict ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// Apply interface to parse serialized OC_SCHEMA_VALUE_TYPE. -// -VOID -ParseSerializedValue ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// Apply interface to parse serialized OC_SCHEMA_BLOB_TYPE. -// -VOID -ParseSerializedBlob ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// Apply interface to parse serialized array -// -VOID -ParseSerializedArray ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// Apply interface to parse serialized map with arbitrary values, -// and OC_STRING strings. -// -VOID -ParseSerializedMap ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ); - -// -// Main interface for parsing serialized data. -// PlistBuffer will be modified during the execution. -// -BOOLEAN -ParseSerialized ( - OUT VOID *Serialized, - IN OC_SCHEMA_INFO *RootSchema, - IN VOID *PlistBuffer, - IN UINT32 PlistSize - ); - -// -// Retrieve typed field pointer from offset -// -#define OC_SCHEMA_FIELD(Base, Type, Offset) \ - ((Type *)(((UINT8 *) (Base)) + (Offset))) - -// -// Smart declaration base macros, see usage below. -// -#define OC_SCHEMA_VALUE(Name, Offset, Type, SourceType) \ - {(Name), PLIST_NODE_TYPE_ANY, ParseSerializedValue, \ - {.Value = {Offset, sizeof (Type), SourceType}}} - -#define OC_SCHEMA_BLOB(Name, Offset, SourceType) \ - {(Name), PLIST_NODE_TYPE_ANY, ParseSerializedBlob, \ - {.Blob = {Offset, SourceType}}} - -// -// Smart declaration macros for builtin appliers, -// which point straight to types. -// -// Name represents dictionary name if any (otherwise NULL). -// Type represents value or value type for size calculation. -// Schema represents element schema. -// -// M prefix stands for Meta, which means meta data type casting is used. -// F suffix stands for Fixed, which means fixed file size is assumed. -// -#define OC_SCHEMA_DICT(Name, Schema) \ - {(Name), PLIST_NODE_TYPE_DICT, ParseSerializedDict, \ - {.Dict = {(Schema), ARRAY_SIZE (Schema)}}} - -#define OC_SCHEMA_BOOLEAN(Name) \ - OC_SCHEMA_VALUE (Name, 0, BOOLEAN, OC_SCHEMA_VALUE_BOOLEAN) - -#define OC_SCHEMA_INTEGER(Name, Type) \ - OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_INTEGER) - -#define OC_SCHEMA_STRING(Name) \ - OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_STRING) - -#define OC_SCHEMA_STRINGF(Name, Type) \ - OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_STRING) - -#define OC_SCHEMA_DATA(Name) \ - OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_DATA) - -#define OC_SCHEMA_DATAF(Name, Type) \ - OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_DATA) - -#define OC_SCHEMA_MDATA(Name) \ - OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_MDATA) - -#define OC_SCHEMA_MDATAF(Name, Type) \ - OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_MDATA) - -#define OC_SCHEMA_ARRAY(Name, ChildSchema) \ - {(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \ - {.List = {0, ChildSchema}}} - -#define OC_SCHEMA_MAP(Name, ChildSchema) \ - {(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \ - {.List = {0, ChildSchema}}} - -// -// Smart declaration macros for builtin appliers, -// which point to structures, containing these types. -// -// Name represents dictionary name if any (otherwise NULL). -// Type represents container structure type for this value. -// Field represents item in the container type. -// Schema represents element schema. -// -#define OC_SCHEMA_BOOLEAN_IN(Name, Type, Field) \ - OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \ - OC_SCHEMA_VALUE_BOOLEAN) - -#define OC_SCHEMA_INTEGER_IN(Name, Type, Field) \ - OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \ - OC_SCHEMA_VALUE_INTEGER) - -#define OC_SCHEMA_STRING_IN(Name, Type, Field) \ - OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_STRING) - -#define OC_SCHEMA_STRINGF_IN(Name, Type, Field) \ - OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \ - OC_SCHEMA_VALUE_STRING) - -#define OC_SCHEMA_DATA_IN(Name, Type, Field) \ - OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_DATA) - -#define OC_SCHEMA_DATAF_IN(Name, Type, Field) \ - OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \ - OC_SCHEMA_VALUE_DATA) - -#define OC_SCHEMA_MDATA_IN(Name, Type, Field) \ - OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_MDATA) - -#define OC_SCHEMA_MDATAF_IN(Name, Type, Field) \ - OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \ - OC_SCHEMA_VALUE_MDATA) - -#define OC_SCHEMA_ARRAY_IN(Name, Type, Field, ChildSchema) \ - {(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \ - {.List = {OFFSET_OF (Type, Field), ChildSchema}}} - -#define OC_SCHEMA_MAP_IN(Name, Type, Field, ChildSchema) \ - {(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \ - {.List = {OFFSET_OF (Type, Field), ChildSchema}}} - -#endif // OC_SERIALIZE_LIB_H diff --git a/Include/Library/OcStorageLib.h b/Include/Library/OcStorageLib.h deleted file mode 100644 index 524441fa4..000000000 --- a/Include/Library/OcStorageLib.h +++ /dev/null @@ -1,155 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_STORAGE_LIB_H -#define OC_STORAGE_LIB_H - -#include -#include -#include -#include - -/** - Storage vault file containing a dictionary with SHA-256 hashes for all files. -**/ -#define OC_STORAGE_VAULT_PATH L"vault.plist" - -/** - RSA-2048 signature of SHA-256 hash of vault.plist. -**/ -#define OC_STORAGE_VAULT_SIGNATURE_PATH L"vault.sig" - -/** - Storage vault version declaring vault compatibility. -**/ -#define OC_STORAGE_VAULT_VERSION 1 - -/** - Safe maximum file path in the storage. -**/ -#define OC_STORAGE_SAFE_PATH_MAX 128 - -/** - Structure declaration for valult file. -**/ -#define OC_STORAGE_VAULT_HASH_FIELDS(_, __) \ - _(UINT8 , Hash , [SHA256_DIGEST_SIZE] , {0} , () ) - OC_DECLARE (OC_STORAGE_VAULT_HASH) - -#define OC_STORAGE_VAULT_FILES_FIELDS(_, __) \ - OC_MAP (OC_STRING, OC_STORAGE_VAULT_HASH, _, __) - OC_DECLARE (OC_STORAGE_VAULT_FILES) - -#define OC_STORAGE_VAULT_FIELDS(_, __) \ - _(UINT32 , Version , , 0 , () ) \ - _(OC_STORAGE_VAULT_FILES , Files , , OC_CONSTR (OC_STORAGE_VAULT_FILES, _, __) , OC_DESTR (OC_STORAGE_VAULT_FILES)) - OC_DECLARE (OC_STORAGE_VAULT) - -/** - Storage abstraction context -**/ -typedef struct { - /// - /// Storage file system if any. - /// - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - /// - /// Storage root owned by context. - /// - EFI_FILE_PROTOCOL *StorageRoot; - /// - /// Device handle with storage (dummy) device path for loading. - /// - EFI_HANDLE StorageHandle; - /// - /// Dummy file path for file storage. - /// - EFI_DEVICE_PATH_PROTOCOL *DummyDevicePath; - /// - /// Dummy file path relative to storage. - /// - EFI_DEVICE_PATH_PROTOCOL *DummyFilePath; - /// - /// Vault context. - /// - OC_STORAGE_VAULT Vault; - /// - /// Vault status. - /// - BOOLEAN HasVault; -} OC_STORAGE_CONTEXT; - -/** - Create storage context from UEFI file system at specified path. - - @param[out] Context Resulting storage context. - @param[in] FileSystem Storage file system. - @param[in] Path Storage file system path (e.g. L"\\"). - @param[in] StorageKey Storage signature verification key, optional. - - @retval EFI_SUCCESS on success. -**/ -EFI_STATUS -OcStorageInitFromFs ( - OUT OC_STORAGE_CONTEXT *Context, - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *Path, - IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL - ); - -/** - Free storage context resources. - - @param[in,out] Context Storage context. -**/ -VOID -OcStorageFree ( - IN OUT OC_STORAGE_CONTEXT *Context - ); - -/** - Check whether file exists. - - @param[in] Context Storage context. - @param[in] FilePath The full path to the file on the device. - - @retval TRUE if file is present in vault or ondisk. -**/ -BOOLEAN -OcStorageExistsFileUnicode ( - IN OC_STORAGE_CONTEXT *Context, - IN CONST CHAR16 *FilePath - ); - -/** - Read file from storage with implicit double (2 byte) null termination. - Null termination does not affect the returned file size. - Depending on the implementation 0 byte files may return null. - If storage context was created with valid storage key, then signature - checking will be performed - - @param[in] Context Storage context. - @param[in] FilePath The full path to the file on the device. - @param[out] FileSize The size of the file read (optional). - - @retval A pointer to a buffer containing file read or NULL. -**/ -VOID * -OcStorageReadFileUnicode ( - IN OC_STORAGE_CONTEXT *Context, - IN CONST CHAR16 *FilePath, - OUT UINT32 *FileSize OPTIONAL - ); - -#endif // OC_STORAGE_LIB_H diff --git a/Include/Library/OcStringLib.h b/Include/Library/OcStringLib.h deleted file mode 100755 index 5e2ea21e0..000000000 --- a/Include/Library/OcStringLib.h +++ /dev/null @@ -1,294 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_STRING_LIB_H -#define OC_STRING_LIB_H - -#include - -/** - Returns the length of a Null-terminated string literal. - - @param[in] String The Null-terminated string literal. - -**/ -#define L_STR_LEN(String) (ARRAY_SIZE (String) - 1) - -/** - Returns the size of a Null-terminated string literal in bytes, including the - Null terminator. - - @param[in] String The Null-terminated string literal. - -**/ -#define L_STR_SIZE(String) (sizeof (String)) - -/** - Returns the size of a Null-terminated string literal in bytes, excluding the - Null terminator. - - @param[in] String The Null-terminated string literal. - -**/ -#define L_STR_SIZE_NT(String) (sizeof (String) - sizeof (*(String))) - -/** Check if character is printable - - @param[in] Char The ascii character to check if is printable. - - @retval TRUE, if character is printable. -**/ -BOOLEAN -IsAsciiPrint ( - IN CHAR8 Char - ); - -/** Check if character is a white space character - - @param[in] Char The ascii character to check if is white space. - - @retval TRUE, if character is a white space character -**/ -INTN -IsAsciiSpace ( - IN CHAR8 Char - ); - -/** Convert null terminated ascii string to unicode. - - @param[in] String A pointer to the ascii string to convert to unicode. - @param[in] Length Length or 0 to calculate the length of the ascii string to convert. - - @retval A pointer to the converted unicode string allocated from pool. -**/ -CHAR16 * -AsciiStrCopyToUnicode ( - IN CONST CHAR8 *String, - IN UINTN Length - ); - -/** - Convert 64-bit unsigned integer to a nul-termianted hex string. - - @param[out] Buffer Destination buffer. - @param[in] BufferSize Destination buffer size in bytes. - @param[in] Value Value to convert. -**/ -BOOLEAN -AsciiUint64ToLowerHex ( - OUT CHAR8 *Buffer, - IN UINT32 BufferSize, - IN UINT64 Value - ); - -/** - Alternative to AsciiSPrint, which checks that the buffer can contain all the characters. - - @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated - ASCII string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString A Null-terminated ASCII format string. - @param ... Variable argument list whose contents are accessed based on the - format string specified by FormatString. - - @retval EFI_SUCCESS When data was printed to supplied buffer. - @retval EFI_OUT_OF_RESOURCES When supplied buffer cannot contain all the characters. -**/ -EFI_STATUS -EFIAPI -OcAsciiSafeSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ); - -/** - Performs a case insensitive comparison of two Null-terminated Unicode strings, - and returns the difference between the first mismatched Unicode characters. - - This function performs a case insensitive comparison of the Null-terminated - Unicode string FirstString to the Null-terminated Unicode string - SecondString. If FirstString is identical to SecondString, then 0 is - returned. Otherwise, the value returned is the first mismatched upper case - Unicode character in SecondString subtracted from the first mismatched upper - case Unicode character in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero and FirstString contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero and SecondString contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param FirstString A pointer to a Null-terminated Unicode string. - @param SecondString A pointer to a Null-terminated Unicode string. - - @retval ==0 FirstString is identical to SecondString using case - insensitiv comparisons. - @retval !=0 FirstString is not identical to SecondString using case - insensitive comparisons. - -**/ -INTN -EFIAPI -OcStriCmp ( - IN CHAR16 *FirstString, - IN CHAR16 *SecondString - ); - -/** - Compares up to a specified length the contents of two Null-terminated Unicode - strings using case insensitive comparisons, and returns the difference - between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString using case insensitive - comparisons. At most, Length Unicode characters will be compared. If Length - is 0, then 0 is returned. If FirstString is identical to SecondString, then 0 - is returned. Otherwise, the value returned is the first mismatched upper case - Unicode character in SecondString subtracted from the first mismatched upper - case Unicode character in FirstString. - - If Length > 0 and FirstString is NULL, then ASSERT(). - If Length > 0 and FirstString is not aligned on a 16-bit boundary, then - ASSERT(). - If Length > 0 and SecondString is NULL, then ASSERT(). - If Length > 0 and SecondString is not aligned on a 16-bit boundary, then - ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Length is greater than - PcdMaximumUnicodeStringLength, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more - than PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param FirstString A pointer to a Null-terminated Unicode string. - @param SecondString A pointer to a Null-terminated Unicode string. - @param Length The maximum number of Unicode characters to compare. - - @retval ==0 FirstString is identical to SecondString using case - insensitive comparisons. - @retval others FirstString is not identical to SecondString using case - insensitive comparisons. - -**/ -INTN -EFIAPI -OcStrniCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString, - IN UINTN Length - ); - -/** - Returns the first occurrence of a Null-terminated Unicode sub-string - in a Null-terminated Unicode string through a case insensitive comparison. - - This function scans the contents of the Null-terminated Unicode string - specified by String and returns the first occurrence of SearchString. - If SearchString is not found in String, then NULL is returned. If - the length of SearchString is zero, then String is returned. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If SearchString is NULL, then ASSERT(). - If SearchString is not aligned on a 16-bit boundary, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero, and SearchString - or String contains more than PcdMaximumUnicodeStringLength Unicode - characters, not including the Null-terminator, then ASSERT(). - - @param String The pointer to a Null-terminated Unicode string. - @param SearchString The pointer to a Null-terminated Unicode string to search for. - - @retval NULL If the SearchString does not appear in String. - @return others If there is a match. - -**/ -CHAR16 * -EFIAPI -OcStriStr ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *SearchString - ); - -/** - Search substring in string. - - @param[in] String Search string. - @param[in] StringLength Search string length. - @param[in] SearchString String to search. - @param[in] SearchStringLength String to search length. - - @retval NULL If the SearchString does not appear in String. - @retval others If there is a match. -**/ -CONST CHAR16 * -OcStrStrLength ( - IN CONST CHAR16 *String, - IN UINTN StringLength, - IN CONST CHAR16 *SearchString, - IN UINTN SearchStringLength - ); - -/** - Alternative to UnicodeSPrint, which checks that the buffer can contain all the characters. - - @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString A Null-terminated Unicode format string. - @param ... Variable argument list whose contents are accessed based on the - format string specified by FormatString. - - @retval EFI_SUCCESS When data was printed to supplied buffer. - @retval EFI_OUT_OF_RESOURCES When supplied buffer cannot contain all the characters. -**/ -EFI_STATUS -EFIAPI -OcUnicodeSafeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ); - -/** - Convert path with mixed slashes to UEFI slashes (\\). - - @param[in,out] String Path. -**/ -VOID -UnicodeUefiSlashes ( - IN OUT CHAR16 *String - ); - -/** - Filter string from unprintable characters. - - @param[in,out] String String to filter. - @param[in] SingleLine Enforce only one line. -**/ -VOID -UnicodeFilterString ( - IN OUT CHAR16 *String, - IN BOOLEAN SingleLine - ); - -#endif // OC_STRING_LIB_H diff --git a/Include/Library/OcTemplateLib.h b/Include/Library/OcTemplateLib.h deleted file mode 100644 index 89196506e..000000000 --- a/Include/Library/OcTemplateLib.h +++ /dev/null @@ -1,290 +0,0 @@ -/** @file - -OcTemplateLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_TEMPLATE_LIB_H -#define OC_TEMPLATE_LIB_H - -#include - -// -// Common structor prototype. -// -typedef -VOID -(*OC_STRUCTOR) ( - VOID *Ptr, - UINT32 Size - ); - -// -// Private primitives for type generations -// - -#define PRIV_OC_STRUCTOR_IGNORE(...) -#define PRIV_OC_STRUCTOR_EXPAND(...) __VA_ARGS__ - -#define PRIV_OC_SELECT_NEXT_INNER(Dummy, Next, ...) Next -// -// Without this layer of indirection, MSVC evaluates __VA_ARGS__ early and -// PRIV_OC_SELECT_NEXT_INNER receives only two arguments, the second always -// being Unused as per PRIV_OC_SELECT_NEXT. -// -#define PRIV_OC_SELECT_NEXT_INNER_INDIR(...) PRIV_OC_SELECT_NEXT_INNER __VA_ARGS__ -#define PRIV_OC_SELECT_NEXT(...) PRIV_OC_SELECT_NEXT_INNER_INDIR((__VA_ARGS__, Unused)) -#define PRIV_OC_REMOVE_NEXT(...) , do { } while (0), - -#define PRIV_OC_DECLARE_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \ - Type Name Suffix; - -#define PRIV_OC_CONSTRUCT_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \ - .Name = Constructor, - -#define PRIV_OC_DESTRUCT_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \ - PRIV_OC_SELECT_NEXT(PRIV_OC_REMOVE_NEXT Destructor, Destructor(&Obj->Name, sizeof (Type Suffix))); - -#define PRIV_OC_INVOKE_DESTRUCTOR(Destructor, Obj, Size) \ - PRIV_OC_SELECT_NEXT(PRIV_OC_REMOVE_NEXT Destructor, Destructor(Obj, Size)) - -#define PRIV_NO_KEY_TYPE UINT8 - -// -// Declare structure type NAME. Construction and destruction interfaces will also be -// available with corresponding prototypes: -// VOID NAME_CONSTRUCT(Void *Ptr, UINTN Size); -// VOID NAME_DESTRUCT(Void *Ptr, UINTN Size); -// -// Field information will be retrieved from NAME_FIELDS X-Macro, written as follows: -#if 0 -#define NAME_FIELDS(_, __) \ - _(Type, Name, Type Suffix, __(Constant Initializer), Destructor Function) \ - _(Type, Name, Type Suffix, OC_CONSTR(Type, _, __), OC_DESTR(Type)) -#endif -// - -#define OC_DECLARE(Name) \ - typedef struct Name ## _ { \ - Name ## _FIELDS (PRIV_OC_DECLARE_STRUCT_MEMBER, PRIV_OC_STRUCTOR_IGNORE) \ - } Name; \ - VOID Name ## _CONSTRUCT(VOID *Ptr, UINT32 Size); \ - VOID Name ## _DESTRUCT(VOID *Ptr, UINT32 Size); - -// -// Generate constructors and destructors for structure type NAME. -// Second argument permits to do extra actions prior to field destruction. -// Pass () to the second argument to ignore this option. -// -#define OC_STRUCTORS(Name, Destructor) \ - VOID Name ## _CONSTRUCT(VOID *Ptr, UINT32 Size) { \ - STATIC Name Obj = { \ - Name ## _FIELDS(PRIV_OC_CONSTRUCT_STRUCT_MEMBER, PRIV_OC_STRUCTOR_EXPAND) \ - }; \ - CopyMem (Ptr, &Obj, sizeof (Name)); \ - } \ - VOID Name ## _DESTRUCT(VOID *Ptr, UINT32 Size) { \ - Name *Obj = (Name *) Ptr; (VOID) Obj; \ - PRIV_OC_INVOKE_DESTRUCTOR(Destructor, Obj, sizeof (Name)); \ - Name ## _FIELDS(PRIV_OC_DESTRUCT_STRUCT_MEMBER, PRIV_OC_STRUCTOR_EXPAND) \ - } - -// -// Use previously defined structure constructor or destructor -// FIXME: We need to use these recursively, and normally one would implement -// it with deferred execution, like this: -// #define OC_CONSTR_REAL(A, _, __) ({A ## _FIELDS(_, __)}) -// #define OC_CONSTR_REAL_ID() OC_CONSTR_REAL -// #define OC_CONSTR DEFER(OC_CONSTR_REAL_ID)() -// However, this will not work in this exact case, as _, which itself is a macro, -// changes the expansion order. The right fix here is to entirely remove the mess -// and use external tool for template generation. -// -#define OC_CONSTR(A, _, __) {A ## _FIELDS(_, __)} -#define OC_CONSTR1(A, _, __) {A ## _FIELDS(_, __)} -#define OC_CONSTR2(A, _, __) {A ## _FIELDS(_, __)} -#define OC_CONSTR3(A, _, __) {A ## _FIELDS(_, __)} -#define OC_CONSTR5(A, _, __) {A ## _FIELDS(_, __)} -#define OC_DESTR(A) A ## _DESTRUCT - -// -// Generate array-like blob (string, data, metadata) of type Type, -// Count static size, MaxSize is real size, and default value Default. -// -#define OC_BLOB(Type, Count, Default, _, __) \ - _(UINT32 , Size , , 0 , OcZeroField ) \ - _(UINT32 , MaxSize , , sizeof (Type Count) , OcZeroField ) \ - _(Type * , DynValue , , NULL , OcFreePointer ) \ - _(Type , Value , Count , __(Default) , () ) - -#define OC_BLOB_STRUCTORS(Name) \ - OC_STRUCTORS(Name, ()) - -#define OC_BLOB_CONSTR(Type, Constructor, SizeConstructor, _, __) \ - __({.Size = SizeConstructor, .MaxSize = sizeof (((Type *)0)->Value), .DynValue = NULL, .Value = Constructor}) - -// -// Generate map-like container with key elements of type KeyType, OC_BLOB derivative, -// value types of Type constructed by Constructor and destructed by Destructor: -#if 0 -#define CONT_FIELDS(_, __) \ - OC_MAP (KEY, ELEM, _, __) - OC_DECLARE (CONT) -#endif -// - -#define OC_MAP(KeyType, Type, _, __) \ - _(UINT32 , Count , , 0 , () ) \ - _(UINT32 , AllocCount , , 0 , () ) \ - _(OC_STRUCTOR , Construct , , Type ## _CONSTRUCT , () ) \ - _(OC_STRUCTOR , Destruct , , Type ## _DESTRUCT , () ) \ - _(Type ** , Values , , NULL , () ) \ - _(UINT32 , ValueSize , , sizeof (Type) , () ) \ - _(UINT32 , KeySize , , sizeof (KeyType) , () ) \ - _(OC_STRUCTOR , KeyConstruct , , KeyType ## _CONSTRUCT , () ) \ - _(OC_STRUCTOR , KeyDestruct , , KeyType ## _DESTRUCT , () ) \ - _(KeyType ** , Keys , , NULL , () ) - -#define OC_MAP_STRUCTORS(Name) \ - OC_STRUCTORS(Name, OcFreeMap) - -// -// Generate array-like container with elements of type Type, constructed -// by Constructor and destructed by Destructor. -#if 0 -#define CONT_FIELDS(_, __) \ - OC_ARRAY (ELEM, _, __) - OC_DECLARE (CONT) -#endif -// - -#define OC_ARRAY(Type, _, __) \ - _(UINT32 , Count , , 0 , () ) \ - _(UINT32 , AllocCount , , 0 , () ) \ - _(OC_STRUCTOR , Construct , , Type ## _CONSTRUCT , () ) \ - _(OC_STRUCTOR , Destruct , , Type ## _DESTRUCT , () ) \ - _(Type ** , Values , , NULL , () ) \ - _(UINT32 , ValueSize , , sizeof (Type) , () ) - -#define OC_ARRAY_STRUCTORS(Name) \ - OC_STRUCTORS(Name, OcFreeArray) - -// -// Free dynamically allocated memory if non NULL. -// Note, that the first argument is actually VOID **. -// -VOID -OcFreePointer ( - VOID *Pointer, - UINT32 Size - ); - -// -// Zero field memory. -// -VOID -OcZeroField ( - VOID *Pointer, - UINT32 Size - ); - -// -// Do not invoke any actions at destruction. -// -VOID -OcDestructEmpty ( - VOID *Pointer, - UINT32 Size - ); - -// -// OC_MAP-like destructor. -// -VOID -OcFreeMap ( - VOID *Pointer, - UINT32 Size - ); - -// -// OC_ARRAY-like destructor. -// -VOID -OcFreeArray ( - VOID *Pointer, - UINT32 Size - ); - -// -// Prepare memory for blob at Pointer to contain Size bytes. -// Assignable size may be returned via OutSize. -// This method guarantees not to overwrite "Default" value, -// but may destroy the previous value. -// NULL is returned on allocation failure. -// -VOID * -OcBlobAllocate ( - VOID *Pointer, - UINT32 Size, - UINT32 **OutSize OPTIONAL - ); - -// -// Obtain blob value -// -#define OC_BLOB_GET(Blob) (((Blob)->DynValue) != NULL ? ((Blob)->DynValue) : ((Blob)->Value)) - -// -// Insert new empty element into the OC_MAP or OC_ARRAY, depending -// on Key value. -// -BOOLEAN -OcListEntryAllocate ( - VOID *Pointer, - VOID **Value, - VOID **Key - ); - -// -// Some useful generic types -// OC_STRING - implements support for resizable ASCII strings. -// OC_DATA - implements support for resizable data blobs. -// OC_ASSOC - implements support for maps with ASCII keys and data values. -// -#define OC_STRING_FIELDS(_, __) \ - OC_BLOB (CHAR8, [64], {0}, _, __) - OC_DECLARE (OC_STRING) - -#define OC_STRING_CONSTR(Constructor, _, __) \ - OC_BLOB_CONSTR (OC_STRING, __(Constructor), sizeof (Constructor), _, __) - -#define OC_ESTRING_CONSTR(_, __) \ - OC_BLOB_CONSTR (OC_STRING, __(""), 0, _, __) - -#define OC_DATA_FIELDS(_, __) \ - OC_BLOB (UINT8, [64], {0}, _, __) - OC_DECLARE (OC_DATA) - -#define OC_EDATA_CONSTR(_, __) \ - OC_BLOB_CONSTR (OC_DATA, __({0}), 0, _, __) - -#define OC_DATA_CONSTR(Constructor, _, __) \ - OC_BLOB_CONSTR (OC_DATA, __(Constructor), sizeof ((UINT8[]) Constructor), _, __) - -#define OC_ASSOC_FIELDS(_, __) \ - OC_MAP (OC_STRING, OC_DATA, _, __) - OC_DECLARE (OC_ASSOC) - -#endif // OC_TEMPLATE_LIB_H diff --git a/Include/Library/OcTimerLib.h b/Include/Library/OcTimerLib.h deleted file mode 100755 index 70b0d888c..000000000 --- a/Include/Library/OcTimerLib.h +++ /dev/null @@ -1,30 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_TIMER_LIB_H -#define OC_TIMER_LIB_H - -#include - -/** - Calculate the TSC frequency - - @retval The calculated TSC frequency. -**/ -UINT64 -RecalculateTSC ( - VOID - ); - -#endif // OC_TIMER_LIB_H diff --git a/Include/Library/OcXmlLib.h b/Include/Library/OcXmlLib.h deleted file mode 100755 index 8543c3ac8..000000000 --- a/Include/Library/OcXmlLib.h +++ /dev/null @@ -1,388 +0,0 @@ -/** @file - -OcXmlLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -// -// Copyright (c) 2012 ooxi/xml.c -// https://github.com/ooxi/xml.c -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the -// use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software in a -// product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#ifndef OC_XML_LIB_H -#define OC_XML_LIB_H - -#include - -// -// Maximum nest level. -// XML_PARSER_NEST_LEVEL is required to fit into INT32. -// -#ifndef XML_PARSER_NEST_LEVEL -#define XML_PARSER_NEST_LEVEL 32ULL -#endif - -// -// Maximum child node count -// XML_PARSER_NODE_COUNT*2 is required to fit into INT32. -// -#ifndef XML_PARSER_NODE_COUNT -#define XML_PARSER_NODE_COUNT 32768ULL -#endif - -// -// Maximum reference count. -// XML_PARSER_MAX_REFERENCE_COUNT*2 is required to fit into INT32. -// -#ifndef XML_PARSER_MAX_REFERENCE_COUNT -#define XML_PARSER_MAX_REFERENCE_COUNT (32ULL*1024) -#endif - -// -// Maximum input data size, currently 32 MB. -// XML_PARSER_MAX_SIZE is required to fit into INT32. -// -#ifndef XML_PARSER_MAX_SIZE -#define XML_PARSER_MAX_SIZE (32ULL*1024*1024) -#endif - -// -// Debug controls -// -//#define XML_PARSER_VERBOSE -//#define XML_PRINT_ERRORS - -// -// Plist node types. -// -typedef enum PLIST_NODE_TYPE_ { - PLIST_NODE_TYPE_ANY, - PLIST_NODE_TYPE_ARRAY, - PLIST_NODE_TYPE_DICT, - PLIST_NODE_TYPE_KEY, - PLIST_NODE_TYPE_STRING, - PLIST_NODE_TYPE_DATA, - PLIST_NODE_TYPE_DATE, - PLIST_NODE_TYPE_TRUE, - PLIST_NODE_TYPE_FALSE, - PLIST_NODE_TYPE_REAL, - PLIST_NODE_TYPE_INTEGER, - PLIST_NODE_TYPE_MAX -} PLIST_NODE_TYPE; - -// -// Opaque structure holding the parsed xml document. -// -struct XML_DOCUMENT_; -struct XML_NODE_; -typedef struct XML_DOCUMENT_ XML_DOCUMENT; -typedef struct XML_NODE_ XML_NODE; - - -// -// Tries to parse the XML fragment in buffer -// References in the document to allow deduplicated node reading: -// 0x0 -// -// -// @param Buffer Chunk to parse -// @param Length Size of the buffer -// @param WithRef Enable reference lookup support -// -// @warning `Buffer` will be referenced by the document, you may not free it -// until you free the XML_DOCUMENT -// @warning You have to call XmlDocumentFree after you finished using the -// document -// @warning `Buffer` contents are permanently modified during parsing -// -// @return The parsed xml fragment iff parsing was successful, 0 otherwise -// -XML_DOCUMENT * -XmlDocumentParse ( - CHAR8 *Buffer, - UINT32 Length, - BOOLEAN WithRefs - ); - -// -// Exports parsed document into the buffer. -// -// @param Document XML_DOCUMENT to export -// @param Length Resulting length of the buffer without trailing \0 (optional) -// @param Skip N root levels before exporting, normally 0. -// -// @return Exported buffer allocated from pool or NULL. -// -CHAR8 * -XmlDocumentExport ( - XML_DOCUMENT *Document, - UINT32 *Length, - UINT32 Skip - ); - -// -// Frees all resources associated with the document. All XML_NODE -// references obtained through the document will be invalidated. -// -// @param Document XML_DOCUMENT to free -// -VOID -XmlDocumentFree ( - XML_DOCUMENT *Document - ); - -// -// @return XML_NODE representing the document root. -// -XML_NODE * -XmlDocumentRoot ( - XML_DOCUMENT *Document - ); - -// -// @return The XML_NODE's tag name. -// -CONST CHAR8 * -XmlNodeName ( - XML_NODE *Node - ); - -// -// @return The XML_NODE's string content (if available, otherwise NULL). -// -CONST CHAR8 * -XmlNodeContent ( - XML_NODE *Node - ); - -// -// @return Number of child nodes. -// -UINT32 -XmlNodeChildren ( - XML_NODE *Node - ); - -// -// @return The n-th child, behaviour is undefined if out of range. -// -XML_NODE * -XmlNodeChild ( - XML_NODE *Node, - UINT32 Child - ); - -// -// @return The node described by the path or NULL if child cannot be found. -// @warning Each element on the way must be unique. -// @warning Last argument must be NULL. -// -XML_NODE * -EFIAPI -XmlEasyChild ( - XML_NODE *Node, - CONST CHAR8 *Child, - ... - ); - -// -// Append new node to current node. -// -// @param Node Current node. -// @param Name Name of the new node. -// @param Attributes Attributes of the new node (optional). -// @param Content New node content (optional). -// -// @return Newly created node or NULL. -// -// @warning Name, Attributes, and Content must stay valid till XmlDocumentFree. -// -XML_NODE * -XmlNodeAppend ( - XML_NODE *Node, - CONST CHAR8 *Name, - CONST CHAR8 *Attributes, - CONST CHAR8 *Content - ); - -// -// Prepend new node to current node. -// Otherwise equivalent to XmlNodeAppend. -// -XML_NODE * -XmlNodePrepend ( - XML_NODE *Node, - CONST CHAR8 *Name, - CONST CHAR8 *Attributes, - CONST CHAR8 *Content - ); - -// -// @return XML_NODE representing plist root or NULL. -// @warning Only a subset of plist is supported. -// @warning No validation of plist format is performed. -// -XML_NODE * -PlistDocumentRoot ( - XML_DOCUMENT *Document - ); - -// -// Performs basic type casting (up to PLIST_NODE_TYPE_MAX). -// Guarantees that node represents passed type. -// Guarantees that arrays and dicts have valid amount of children, while others have 0. -// Guarantees that keys have names and integers have values. -// -// @return Node if it is not NULL and represents passed Type or NULL. -// @warning It is not guaranteed that Node has valid data for data or integer types. -// -XML_NODE * -PlistNodeCast ( - XML_NODE *Node, - PLIST_NODE_TYPE Type - ); - -// -// @return Number of plist dictionary entries. -// -UINT32 -PlistDictChildren ( - XML_NODE *Node - ); - -// -// @return The n-th dictionary key, behaviour is undefined if out of range. -// -XML_NODE * -PlistDictChild ( - XML_NODE *Node, - UINT32 Child, - XML_NODE **Value OPTIONAL - ); - -// -// @return key value for valid type or NULL. -// -CONST CHAR8 * -PlistKeyValue ( - XML_NODE *Node - ); - -// -// @return string value for valid type or empty string (""). -// -BOOLEAN -PlistStringValue ( - XML_NODE *Node, - CHAR8 *Value, - UINT32 *Size - ); - -// -// Decodes data content for valid type or sets *Size to 0. -// -// @param Buffer output buffer. -// @param Size size of buffer. -// -BOOLEAN -PlistDataValue ( - XML_NODE *Node, - UINT8 *Buffer, - UINT32 *Size - ); - -// -// @return boolean value for valid type or FALSE. -// -BOOLEAN -PlistBooleanValue ( - XML_NODE *Node, - BOOLEAN *Value - ); - -// -// @return integral value for valid type or 0. -// -BOOLEAN -PlistIntegerValue ( - XML_NODE *Node, - VOID *Value, - UINT32 Size, - BOOLEAN Hex - ); - -// -// Decodes data content for valid type or sets *Size to 0. -// Valid type for MetaData is DATA itself, STRING, INTEGER, -// or BOOLEAN (as 1 byte with 1 or 0 value). -// -// @param Buffer output buffer. -// @param Size size of buffer. -// @warn Integer must fit 32-bit UNSIGNED. -// @warn Buffer must be at least 1 byte long. -// -BOOLEAN -PlistMetaDataValue ( - XML_NODE *Node, - VOID *Buffer, - UINT32 *Size - ); - -// -// Estimates string content size. -// -BOOLEAN -PlistStringSize ( - XML_NODE *Node, - UINT32 *Size - ); - -// -// Estimates data content size. -// -BOOLEAN -PlistDataSize ( - XML_NODE *Node, - UINT32 *Size - ); - -// -// Estimates meta data content size. -// -BOOLEAN -PlistMetaDataSize ( - XML_NODE *Node, - UINT32 *Size - ); - -#endif // OC_XML_LIB_H diff --git a/Include/Protocol/AmiKeycode.h b/Include/Protocol/AmiKeycode.h deleted file mode 100644 index 7cc29dbe9..000000000 --- a/Include/Protocol/AmiKeycode.h +++ /dev/null @@ -1,59 +0,0 @@ -/** @file - Header file for AMI EfiKeycode protocol definitions. - -Copyright (c) 2016, vit9696. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#ifndef AMI_KEYCODE_H -#define AMI_KEYCODE_H - -// 0ADFB62D-FF74-484C-8944-F85C4BEA87A8 -#define AMI_EFIKEYCODE_PROTOCOL_GUID \ - { 0x0ADFB62D, 0xFF74, 0x484C, { 0x89, 0x44, 0xF8, 0x5C, 0x4B, 0xEA, 0x87, 0xA8 } } - -extern EFI_GUID gAmiEfiKeycodeProtocolGuid; - -typedef struct _AMI_EFIKEYCODE_PROTOCOL AMI_EFIKEYCODE_PROTOCOL; - -#ifndef KEY_STATE_EXPOSED -#define KEY_STATE_EXPOSED 0x40 -#endif - -typedef struct { - EFI_INPUT_KEY Key; - EFI_KEY_STATE KeyState; - EFI_KEY EfiKey; - UINT8 EfiKeyIsValid; - UINT8 PS2ScanCode; - UINT8 PS2ScanCodeIsValid; -} AMI_EFI_KEY_DATA; - -typedef EFI_STATUS (EFIAPI *AMI_READ_EFI_KEY) ( - IN AMI_EFIKEYCODE_PROTOCOL *This, - OUT AMI_EFI_KEY_DATA *KeyData - ); - -typedef -EFI_STATUS -(EFIAPI *AMI_RESET_EX) ( - IN AMI_EFIKEYCODE_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -struct _AMI_EFIKEYCODE_PROTOCOL { - AMI_RESET_EX Reset; - AMI_READ_EFI_KEY ReadEfikey; - EFI_EVENT WaitForKeyEx; - EFI_SET_STATE SetState; - EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; - EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; -}; - -#endif diff --git a/Include/Protocol/AmiPointer.h b/Include/Protocol/AmiPointer.h deleted file mode 100644 index 127fdc92a..000000000 --- a/Include/Protocol/AmiPointer.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - Header file for AMI EfiPointer protocol definitions. - -Copyright (c) 2016, vit9696. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#ifndef AMI_POINTER_H -#define AMI_POINTER_H - -// 15A10CE7-EAB5-43BF-9042-74432E696377 -#define AMI_EFIPOINTER_PROTOCOL_GUID \ - { 0x15A10CE7, 0xEAB5, 0x43BF, { 0x90, 0x42, 0x74, 0x43, 0x2E, 0x69, 0x63, 0x77 } } - -extern EFI_GUID gAmiEfiPointerProtocolGuid; - -typedef struct _AMI_EFIPOINTER_PROTOCOL AMI_EFIPOINTER_PROTOCOL; - -// Unless Changed == 1, no data is provided -typedef struct { - UINT8 Absolute; - UINT8 One; - UINT8 Changed; - UINT8 Reserved; - INT32 PositionX; - INT32 PositionY; - INT32 PositionZ; -} AMI_POINTER_POSITION_STATE_DATA; - -VERIFY_SIZE_OF(AMI_POINTER_POSITION_STATE_DATA, 16); - -// Unless Changed == 1, no data is provided -typedef struct { - UINT8 Changed; - UINT8 LeftButton; - UINT8 MiddleButton; - UINT8 RightButton; -} AMI_POINTER_BUTTON_STATE_DATA; - -VERIFY_SIZE_OF(AMI_POINTER_BUTTON_STATE_DATA, 4); - -typedef VOID (EFIAPI *AMI_EFIPOINTER_RESET) ( - IN AMI_EFIPOINTER_PROTOCOL *This -); - -typedef VOID (EFIAPI *AMI_EFIPOINTER_GET_BUTTON_STATE) ( - IN AMI_EFIPOINTER_PROTOCOL *This, - OUT AMI_POINTER_BUTTON_STATE_DATA *State -); - -typedef VOID (EFIAPI *AMI_EFIPOINTER_GET_POSITION_STATE) ( - IN AMI_EFIPOINTER_PROTOCOL *This, - OUT AMI_POINTER_POSITION_STATE_DATA *State -); - -struct _AMI_EFIPOINTER_PROTOCOL { - AMI_EFIPOINTER_RESET Reset; - AMI_EFIPOINTER_GET_POSITION_STATE GetPositionState; - AMI_EFIPOINTER_GET_BUTTON_STATE GetButtonState; -}; - -#endif diff --git a/Include/Protocol/AppleBeepGen.h b/Include/Protocol/AppleBeepGen.h deleted file mode 100644 index 5a452110a..000000000 --- a/Include/Protocol/AppleBeepGen.h +++ /dev/null @@ -1,76 +0,0 @@ -/** @file -Copyright (C) 2014 - 2016, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_BEEP_GEN_H -#define APPLE_BEEP_GEN_H - -/** - Apple Beep Generator protocol - C32332DF-FC56-4FE1-9358-BA0D529B24CD -**/ -#define APPLE_BEEP_GEN_PROTOCOL_GUID \ - { 0xC32332DF, 0xFC56, 0x4FE1, \ - { 0x93, 0x58, 0xBA, 0x0D, 0x52, 0x9B, 0x24, 0xCD } } - -/** - Note, ToneLength and SilenceLength were in microseconds for older models: - - MacBookPro1,1 - - MacBookPro1,1 - - MacBookPro1,2 - - MacBookPro2,1 - - MacBookPro2,2 - - MacBookP1,1 - - MacBookP1,2 - - MacBookP2,1 - - MacBookP2,2 - - MacBook1,1 - - MacBook2,1 - - Macmini1,1 - - Macmini2,1 - - iMac4,1 - - iMac4,2 - - iMac5,1 - - iMac5,2 - - iMac6,1 - - MacPro1,1 - - MacPro2,1 - - XServe1,1 -**/ - -/** - Generate cycles of beep signals with silence afterwards, blocking. - - @param[in] ToneCount Number of signals to produce. - @param[in] ToneLength Signal length in milliseconds. - @param[in] SilenceLength Silence length in milliseconds. - - @retval EFI_SUCCESS after signal completion. - @retval EFI_SUCCESS if ToneCount is 0. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_BEEP_GEN_BEEP) ( - IN UINT32 ToneCount, - IN UINTN ToneLength, - IN UINTN SilenceLength - ); - -/** - All protocol members are optional and can be NULL. -**/ -typedef struct { - APPLE_BEEP_GEN_BEEP GenBeep; ///< Can be NULL. -} APPLE_BEEP_GEN_PROTOCOL; - -extern EFI_GUID gAppleBeepGenProtocolGuid; - -#endif // APPLE_BEEP_GEN_H diff --git a/Include/Protocol/AppleBootPolicy.h b/Include/Protocol/AppleBootPolicy.h deleted file mode 100644 index a47d3bc50..000000000 --- a/Include/Protocol/AppleBootPolicy.h +++ /dev/null @@ -1,139 +0,0 @@ -/** @file -Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_BOOT_POLICY_H -#define APPLE_BOOT_POLICY_H - -#include - -#define APPLE_BOOT_POLICY_PROTOCOL_REVISION 0x00000003 - -/// -/// The GUID of the APPLE_BOOT_POLICY_PROTOCOL. -/// -#define APPLE_BOOT_POLICY_PROTOCOL_GUID \ - { 0x62257758, 0x350C, 0x4D0A, \ - { 0xB0, 0xBD, 0xF6, 0xBE, 0x2E, 0x1E, 0x27, 0x2C } } - -// BOOT_POLICY_GET_BOOT_FILE -/** Locates the bootable file of the given volume. Prefered are the values - blessed, though if unavailable, hard-coded names are being verified and - used if existing. - - The blessed paths are to be determined by the HFS Driver via - EFI_FILE_PROTOCOL.GetInfo(). The related identifier definitions are to be - found in AppleBless.h. - - @param[in] Device The Device's Handle to perform the search on. - @param[out] FilePath A pointer to the device path pointer to set to the file - path of the boot file. - - @retval EFI_NOT_FOUND A bootable file could not be found on the given - volume. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval EFI_SUCCESS The operation completed successfully and the - BootFilePath Buffer has been filled. - @retval other The status of an operation used to complete - this operation is returned. -**/ -typedef -EFI_STATUS -(EFIAPI *BOOT_POLICY_GET_BOOT_FILE) ( - IN EFI_HANDLE Device, - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -// -// Neither is used at this moment. -// https://opensource.apple.com/source/kext_tools/kext_tools-528.220.8/KextAudit/efi_smc.h.auto.html -// -typedef enum { - // Boot Policy not valid retry. - BootPolicyNotReady, - - // Boot Selected macOS. - BootPolicyOk, - - // Boot Recovery OS, update bridgeOS. - BootPolicyUpdate, - - // Full system reboot, boot selected macOS. - BootPolicyReboot, - - // Version unknown boot to recovery OS to get more info. - BootPolicyUnknown, - - // Update failed take the failure path. - BootPolicyBridgeOSUpdateFailed, - - // Boot Recovery OS to change security policy. - BootPolicyRecoverySecurityPolicyUpdate, - - // Valid values will be less that this version. - BootPolicyMaxValue -} BOOT_POLICY_ACTION; - -typedef -EFI_STATUS -(EFIAPI *BOOT_POLICY_GET_BOOT_FILE_EX) ( - IN EFI_HANDLE Device, - IN BOOT_POLICY_ACTION Action, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -typedef -EFI_STATUS -(EFIAPI *BOOT_POLICY_DEVICE_PATH_TO_DIR_PATH) ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device, - OUT EFI_HANDLE *ApfsVolumeHandle - ); - -typedef -EFI_STATUS -(EFIAPI *BOOT_POLICY_GET_APFS_RECOVERY_FILE_PATH) ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *PathName, - OUT CHAR16 **FullPathName, - OUT VOID **Reserved, - OUT EFI_FILE_PROTOCOL **Root, - OUT EFI_HANDLE *DeviceHandle - ); - -typedef -EFI_STATUS -(EFIAPI *BOOT_POLICY_GET_ALL_APFS_RECOVERY_FILE_PATH) ( - IN EFI_HANDLE Handle, - OUT VOID **Volumes, - OUT UINTN *NumberOfEntries - ); - -/// -/// The structure exposed by the APPLE_BOOT_POLICY_PROTOCOL. -/// -typedef struct { - UINTN Revision; ///< The revision of the installed protocol. - BOOT_POLICY_GET_BOOT_FILE GetBootFile; ///< Present as of Revision 1. - BOOT_POLICY_GET_BOOT_FILE_EX GetBootFileEx; ///< Present as of Revision 3. - BOOT_POLICY_DEVICE_PATH_TO_DIR_PATH DevicePathToDirPath; ///< Present as of Revision 3. - BOOT_POLICY_GET_APFS_RECOVERY_FILE_PATH GetApfsRecoveryFilePath; ///< Present as of Revision 3. - BOOT_POLICY_GET_ALL_APFS_RECOVERY_FILE_PATH GetAllApfsRecoveryFilePath; ///< Present as of Revision 3. -} APPLE_BOOT_POLICY_PROTOCOL; - -/// -/// A global variable storing the GUID of the APPLE_BOOT_POLICY_PROTOCOL. -/// -extern EFI_GUID gAppleBootPolicyProtocolGuid; - -#endif // APPLE_BOOT_POLICY_H diff --git a/Include/Protocol/AppleDebugLog.h b/Include/Protocol/AppleDebugLog.h deleted file mode 100644 index 7deb648d3..000000000 --- a/Include/Protocol/AppleDebugLog.h +++ /dev/null @@ -1,150 +0,0 @@ -/** @file - Apple Debug Log protocol. - -Copyright (C) 2020, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_DEBUG_LOG_H -#define APPLE_DEBUG_LOG_H - -/** - Apple Debug Log protocol GUID. - DDFA34FB-FE1F-48EA-B213-FB4A4CD57BE3 -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_GUID \ - { 0xDDFA34FB, 0xFE1F, 0x48EA, \ - { 0xB2, 0x13, 0xFB, 0x4A, 0x4C, 0xD5, 0x7B, 0xE3 } } - -/** - Current supported revision. -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_REVISION 0x10000 - -/** - Maximum logfile size. -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_FILESIZE BASE_2MB - -/** - Logfile name on EFI system partition (indices 1~8). -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_FILENAME L"\\EFI\\APPLE\\LOG\\BOOT-%u.LOG" - -/** - Legacy boot.efi logfile. -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_BOOTLOG L"\\BOOTLOG" - -/** - Legacy previous boot.efi logfile. -**/ -#define APPLE_DEBUG_LOG_PROTOCOL_BOOTLOG_OLD L"\\BOOTLOG.OLD" - -/** - Apple Debug Log protocol structure forward declaration. -**/ -typedef struct APPLE_DEBUG_LOG_PROTOCOL_ APPLE_DEBUG_LOG_PROTOCOL; - -/** - Send debug message to the protocol. - - @param[in] Message ASCII message to log. - - @retval EFI_SUCCESS on success. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DEBUG_LOG_PRINT) ( - IN CONST CHAR8 *Message - ); - -/** - Extract characters from the log buffer. - - @param[in,out] Position Starting position for extraction. - @param[in,out] BufferSize Extraction buffer size. - @param[out] Buffer Extraction buffer, optional. - @param[out] LostCharacters Amount of characters that did not fit the buffer, optional. - - - Position is automatically updated to point to the end of the buffer if provided - value is too large. - - Position is automatically updated to point after extracted characters if Buffer is - not NULL. - - @retval EFI_INVALID_PARAMETER if Position or BufferSize are NULL. - @retval EFI_SUCCESS on successful extraction. - @retval EFI_SUCCESS on reported size in BufferSize if Buffer is NULL. - @retval EFI_END_OF_FILE on empty buffer. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DEBUG_LOG_EXTRACT_BUFFER) ( - IN OUT UINT32 *Position, - IN OUT UINTN *BufferSize, - OUT CHAR8 *Buffer OPTIONAL, - OUT UINT32 *LostCharacters OPTIONAL - ); - -/** - Save debug log to 1st APPLE_DEBUG_LOG_PROTOCOL_FILENAME - on logging partition. Saving debug log includes extracting - all previously unsaved characters from the debug log buffer. - - On first call this function performs log rotation: - - 8th APPLE_DEBUG_LOG_PROTOCOL_FILENAME is removed. - - APPLE_DEBUG_LOG_PROTOCOL_FILENAMEs from 1st to 7th are renamed to 2nd to 8th. - - Truncated character amount is reflected in the log before writing to file. - - @retval EFI_SUCCESS on success. - @retval EFI_UNSUPPORTED if current TPL is above TPL_CALLBACK. - @retval EFI_NOT_FOUND on write failure. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DEBUG_LOG_WRITE_FILES) ( - VOID - ); - -/** - Performs a one-time operation of setting up an event for - EfiSimpleFileSystem protocol installation and triggering - its handler for all currently present file systems. - - Event handler is supposed to handle all ESP partitions: - - Set modification time of APPLE_DEBUG_LOG_PROTOCOL_FILENAME - to current if it is before 2000 year. - - Remove APPLE_DEBUG_LOG_PROTOCOL_FILENAME created or modified - more than a month ago. - - Remove APPLE_DEBUG_LOG_PROTOCOL_BOOTLOG and - APPLE_DEBUG_LOG_PROTOCOL_BOOTLOG_OLD files if present. - - Update logging partition to current handled partition. -**/ -typedef -VOID -(EFIAPI *APPLE_DEBUG_LOG_SETUP_FILES) ( - VOID - ); - -/** - Apple debug log protocol. -**/ -struct APPLE_DEBUG_LOG_PROTOCOL_ { - UINTN Revision; - APPLE_DEBUG_LOG_PRINT Print; - APPLE_DEBUG_LOG_EXTRACT_BUFFER ExtractBuffer; - APPLE_DEBUG_LOG_WRITE_FILES WriteFiles; - APPLE_DEBUG_LOG_SETUP_FILES SetupFiles; -}; - -extern EFI_GUID gAppleDebugLogProtocolGuid; - -#endif // APPLE_DEBUG_LOG_H diff --git a/Include/Protocol/AppleDiskImage.h b/Include/Protocol/AppleDiskImage.h deleted file mode 100644 index df58493d7..000000000 --- a/Include/Protocol/AppleDiskImage.h +++ /dev/null @@ -1,110 +0,0 @@ -/** @file - Apple Disk Image protocol. - -Copyright (C) 2019, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_DISK_IMAGE_PROTOCOL_H -#define APPLE_DISK_IMAGE_PROTOCOL_H - -/** - Apple Disk Image protocol GUID. - 004B07E8-0B9C-427E-B0D4-A466E6E57A62 -**/ -#define APPLE_DISK_IMAGE_PROTOCOL_GUID \ - { 0x004B07E8, 0x0B9C, 0x427E, \ - { 0xB0, 0xD4, 0xA4, 0x66, 0xE6, 0xE5, 0x7A, 0x62 } } - -/** - Apple Disk Image protocol revision. -**/ -#define APPLE_DISK_IMAGE_PROTOCOL_REVISION 2 - -/** - Checks whether dmg file at DevicePath is valid. - Essentially this is done by verifying last 512 bytes - of the file. - - @param[in] DevicePath Path to dmg file. - - @retval EFI_SUCCESS Dmg looks valid and can be loaded. - @retval EFI_UNSUPPORTED Dmg is unsupported. - @retval EFI_NOT_FOUND Dmg was not found at this device path. - @retval EFI_OUT_OF_RESOURCES Memory allocation error happened. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DISK_IMAGE_SUPPORTED) ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Mounts dmg file at DevicePath providing relevant protocols: - - gEfiDevicePathProtocolGuid - - gEfiBlockIoProtocolGuid - - gTDMApprovedGuid - - gAppleDiskImageProtocolGuid (as NULL) - Mounted dmg handle is to be connnected recursively on all protocols - with connection status unchecked. - - Note, that DiskImage protocol does not protect DMG memory from the kernel. - It only works in UEFI scope. For the kernel to boot the parent protocol, - namely RamDisk, should have us covered by allocating DMG extent memory - as wired (EfiACPIMemoryNVS). - - @param[in] DevicePath Path to dmg file. - @param[out] Handle Dmg handle. - - @retval EFI_SUCCESS Dmg was mounted with relevant protocols. - @retval EFI_INVALID_PARAMETER Dmg is not valid. - @retval EFI_UNSUPPORTED Dmg is less than 512 bytes. - @retval EFI_NOT_FOUND Dmg was not found at this device path. - @retval EFI_OUT_OF_RESOURCES Memory allocation error happened. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DISK_IMAGE_MOUNT_IMAGE) ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT EFI_HANDLE *Handle OPTIONAL - ); - -/** - Unmounts dmg file at handle and uninstalls the following protocols: - - gEfiDevicePathProtocolGuid - - gEfiBlockIoProtocolGuid - - gAppleDiskImageProtocolGuid - All the resources consumed by the dmg will be freed. - - @param[in] Handle Dmg handle. - - @retval EFI_SUCCESS Dmg was unmounted with relevant protocols. - @retval EFI_INVALID_PARAMETER Dmg handle is not valid. - @retval EFI_NOT_FOUND Relevant protocols were not found. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_DISK_IMAGE_UNMOUNT_IMAGE) ( - IN EFI_HANDLE Handle - ); - -/** - Apple disk imge protocol. -**/ -typedef struct { - UINT32 Revision; - APPLE_DISK_IMAGE_SUPPORTED Supported; - APPLE_DISK_IMAGE_MOUNT_IMAGE MountImage; - APPLE_DISK_IMAGE_UNMOUNT_IMAGE UnmountImage; -} APPLE_DISK_IMAGE_PROTOCOL; - -extern EFI_GUID gAppleDiskImageProtocolGuid; - -#endif // APPLE_DISK_IMAGE_PROTOCOL_H diff --git a/Include/Protocol/AppleEvent.h b/Include/Protocol/AppleEvent.h deleted file mode 100644 index 564279fa5..000000000 --- a/Include/Protocol/AppleEvent.h +++ /dev/null @@ -1,174 +0,0 @@ -/** @file - Copyright (C) 2005 - 2016, Apple Inc. All rights reserved. - Portions Copyright (C) 2014 - 2016, CupertinoNet. All rights reserved.
- - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -**/ - -#ifndef APPLE_EVENT_H_ -#define APPLE_EVENT_H_ - -// Related definitions - -typedef struct _APPLE_EVENT_PROTOCOL APPLE_EVENT_PROTOCOL; - -// Apple Event Type - -#define APPLE_EVENT_TYPE_NONE 0 -#define APPLE_EVENT_TYPE_MOUSE_MOVED BIT (0) -#define APPLE_EVENT_TYPE_MOUSE_DOWN BIT (1) -#define APPLE_EVENT_TYPE_MOUSE_UP BIT (2) -#define APPLE_EVENT_TYPE_MOUSE_CLICK BIT (3) -#define APPLE_EVENT_TYPE_MOUSE_DOUBLE_CLICK BIT (4) -#define APPLE_EVENT_TYPE_LEFT_BUTTON BIT (5) -#define APPLE_EVENT_TYPE_RIGHT_BUTTON BIT (6) -#define APPLE_EVENT_TYPE_RESERVED_BUTTON BIT (7) -#define APPLE_EVENT_TYPE_KEY_DOWN BIT (8) -#define APPLE_EVENT_TYPE_KEY_UP BIT (9) -#define APPLE_EVENT_TYPE_MODIFIER_DOWN BIT (10) -#define APPLE_EVENT_TYPE_MODIFIER_UP BIT (11) - -#define APPLE_CLICK_MOUSE_EVENTS \ - (APPLE_EVENT_TYPE_MOUSE_DOWN \ - | APPLE_EVENT_TYPE_MOUSE_UP \ - | APPLE_EVENT_TYPE_MOUSE_CLICK \ - | APPLE_EVENT_TYPE_LEFT_BUTTON \ - | APPLE_EVENT_TYPE_RIGHT_BUTTON) - -#define APPLE_ALL_MOUSE_EVENTS 0x00FF -#define APPLE_ALL_KEYBOARD_EVENTS 0xFF00 - -// APPLE_EVENT_TYPE -typedef UINT32 APPLE_EVENT_TYPE; - -// APPLE_POINTER_EVENT_TYPE -typedef UINTN APPLE_POINTER_EVENT_TYPE; - -// APPLE_KEY_EVENT_DATA -typedef PACKED struct { - UINT16 NumberOfKeyPairs; ///< - PACKED struct { - EFI_INPUT_KEY InputKey; ///< - APPLE_KEY AppleKey; ///< - } KeyPair; ///< - UINT16 Unknown; ///< -} APPLE_KEY_EVENT_DATA; - -typedef union { - APPLE_KEY_EVENT_DATA *KeyData; ///< - APPLE_POINTER_EVENT_TYPE PointerEventType; ///< - UINTN Raw; ///< -} APPLE_EVENT_DATA; - -// DIMENSION -typedef struct { - INT32 Horizontal; ///< - INT32 Vertical; ///< -} DIMENSION; - -// APPLE_EVENT_QUERY_INFORMATION -typedef struct { - struct { - UINT16 Year; ///< - UINT8 Month; ///< - UINT8 Day; ///< - UINT8 Hour; ///< - UINT8 Minute; ///< - UINT8 Second; ///< - UINT8 Pad1; ///< - } CreationTime; ///< - APPLE_EVENT_TYPE EventType; ///< - APPLE_EVENT_DATA EventData; ///< - APPLE_MODIFIER_MAP Modifiers; ///< - DIMENSION PointerPosition; ///< -} APPLE_EVENT_QUERY_INFORMATION; - -// APPLE_EVENT_NOTIFY_FUNCTION -typedef -VOID -(EFIAPI *APPLE_EVENT_NOTIFY_FUNCTION)( - IN APPLE_EVENT_QUERY_INFORMATION *Information, - IN VOID *NotifyContext - ); - -typedef VOID *APPLE_EVENT_HANDLE; - -// Protocol declaration - -// APPLE_EVENT_PROTOCOL_GUID -#define APPLE_EVENT_PROTOCOL_GUID \ - {0x33BE0EF1, 0x89C9, 0x4A6D, \ - {0xBB, 0x9F, 0x69, 0xDC, 0x8D, 0xD5, 0x16, 0xB9}} - -// EVENT_REGISTER_HANDLER -typedef -EFI_STATUS -(EFIAPI *EVENT_REGISTER_HANDLER)( - IN APPLE_EVENT_TYPE Type, - IN APPLE_EVENT_NOTIFY_FUNCTION NotifyFunction, - OUT APPLE_EVENT_HANDLE *Handle, - IN VOID *NotifyContext - ); - -// EVENT_UNREGISTER_HANDLER -typedef -EFI_STATUS -(EFIAPI *EVENT_UNREGISTER_HANDLER)( - IN APPLE_EVENT_HANDLE EventHandle - ); - -// EVENT_SET_CURSOR_POSITION -typedef -EFI_STATUS -(EFIAPI *EVENT_SET_CURSOR_POSITION)( - IN DIMENSION *Position - ); - -// EVENT_SET_EVENT_NAME -typedef -EFI_STATUS -(EFIAPI *EVENT_SET_EVENT_NAME)( - IN OUT APPLE_EVENT_HANDLE Handle, - IN CHAR8 *Name - ); - -// EVENT_IS_CAPS_LOCK_ON -/** Retrieves the state of the CapsLock key. - - @param[in, out] CLockOn This parameter indicates the state of the CapsLock - key. - - @retval EFI_SUCCESS The CapsLock state was successfully returned - in ClockOn. - @retval EFI_INVALID_PARAMETER ClockOn is NULL. -**/ -typedef -EFI_STATUS -(EFIAPI *EVENT_IS_CAPS_LOCK_ON)( - IN OUT BOOLEAN *CLockOn - ); - -// APPLE_EVENT_PROTOCOL -struct _APPLE_EVENT_PROTOCOL { - UINT32 Revision; ///< - EVENT_REGISTER_HANDLER RegisterHandler; ///< - EVENT_UNREGISTER_HANDLER UnregisterHandler; ///< - EVENT_SET_CURSOR_POSITION SetCursorPosition; ///< - EVENT_SET_EVENT_NAME SetEventName; ///< - EVENT_IS_CAPS_LOCK_ON IsCapsLockOn; ///< -}; - -// gAppleEventProtocolGuid -extern EFI_GUID gAppleEventProtocolGuid; - -#endif // APPLE_EVENT_H_ diff --git a/Include/Protocol/AppleFramebufferInfo.h b/Include/Protocol/AppleFramebufferInfo.h deleted file mode 100644 index 9a691c1db..000000000 --- a/Include/Protocol/AppleFramebufferInfo.h +++ /dev/null @@ -1,43 +0,0 @@ -/** @file -Copyright (C) 2020, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_FRAMEBUFFER_INFO_H -#define APPLE_FRAMEBUFFER_INFO_H - -/// -/// The GUID of the APPLE_FRAMEBUFFER_INFO_PROTOCOL. -/// -#define APPLE_FRAMEBUFFER_INFO_PROTOCOL_GUID \ - { 0xE316E100, 0x0751, 0x4C49, \ - { 0x90, 0x56, 0x48, 0x6C, 0x7E, 0x47, 0x29, 0x03 } } - -typedef struct APPLE_FRAMEBUFFER_INFO_PROTOCOL_ APPLE_FRAMEBUFFER_INFO_PROTOCOL; - -typedef -EFI_STATUS -(EFIAPI *APPLE_FRAMEBUFFER_INFO_GET_INFO) ( - IN APPLE_FRAMEBUFFER_INFO_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *FramebufferBase, - OUT UINT32 *FramebufferSize, - OUT UINT32 *ScreenRowBytes, - OUT UINT32 *ScreenWidth, - OUT UINT32 *ScreenHeight, - OUT UINT32 *ScreenDepth - ); - -struct APPLE_FRAMEBUFFER_INFO_PROTOCOL_ { - APPLE_FRAMEBUFFER_INFO_GET_INFO GetInfo; -}; - -extern EFI_GUID gAppleFramebufferInfoProtocolGuid; - -#endif // APPLE_FRAMEBUFFER_INFO_H diff --git a/Include/Protocol/AppleKeyMapAggregator.h b/Include/Protocol/AppleKeyMapAggregator.h deleted file mode 100644 index 0bd75f0ce..000000000 --- a/Include/Protocol/AppleKeyMapAggregator.h +++ /dev/null @@ -1,94 +0,0 @@ -/** @file -Copyright (C) 2014 - 2016, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_KEY_MAP_AGGREGATOR_H -#define APPLE_KEY_MAP_AGGREGATOR_H - -#include - -// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION -#define APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION 0x00010000 - -// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_GUID -#define APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_GUID \ - { 0x5B213447, 0x6E73, 0x4901, \ - { 0xA4, 0xF1, 0xB8, 0x64, 0xF3, 0xB7, 0xA1, 0x72 } } - -typedef -struct APPLE_KEY_MAP_AGGREGATOR_PROTOCOL -APPLE_KEY_MAP_AGGREGATOR_PROTOCOL; - -// KEY_MAP_GET_KEY_STROKES -/** Returns all pressed keys and key modifiers into the appropiate buffers. - - @param[in] This Protocol instance pointer. - @param[out] Modifiers The modifiers manipulating the given keys. - @param[out] NumberOfKeyCodes On input the number of keys allocated. - On output the number of keys returned into - KeyCodes. - @param[out] KeyCodes A Pointer to a caller-allocated the pressed - keys get returned in. - - @retval EFI_SUCCESS The pressed keys have been returned into - KeyCodes. - @retval EFI_BUFFER_TOO_SMALL The memory required to return the value exceeds - the size of the allocated Buffer. - The required number of keys to allocate to - complete the operation has been returned into - NumberOfKeyCodes. - @retval other An error returned by a sub-operation. -**/ -typedef -EFI_STATUS -(EFIAPI *KEY_MAP_GET_KEY_STROKES)( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This, - OUT APPLE_MODIFIER_MAP *Modifiers, - OUT UINTN *NumberOfKeyCodes, - OUT APPLE_KEY *KeyCodes - ); - -// KEY_MAP_CONTAINS_KEY_STROKES -/** Returns whether or not a list of keys and their modifiers are part of the - database of pressed keys. - - @param[in] This Protocol instance pointer. - @param[in] Modifiers The modifiers manipulating the given keys. - @param[in] NumberOfKeyCodes The number of keys present in KeyCodes. - @param[in,out] KeyCodes The list of keys to check for. The - children may be sorted in the process. - @param[in] ExactMatch Specifies whether Modifiers and KeyCodes - should be exact matches or just contained. - - @retval EFI_SUCCESS The queried keys are part of the database. - @retval EFI_NOT_FOUND The queried keys could not be found. -**/ -typedef -EFI_STATUS -(EFIAPI *KEY_MAP_CONTAINS_KEY_STROKES)( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This, - IN APPLE_MODIFIER_MAP Modifiers, - IN UINTN NumberOfKeyCodes, - IN OUT APPLE_KEY *KeyCodes, - IN BOOLEAN ExactMatch - ); - -// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL -struct APPLE_KEY_MAP_AGGREGATOR_PROTOCOL { - UINTN Revision; - KEY_MAP_GET_KEY_STROKES GetKeyStrokes; - KEY_MAP_CONTAINS_KEY_STROKES ContainsKeyStrokes; -}; - -// gAppleKeyStateProtocolGuid -extern EFI_GUID gAppleKeyStateProtocolGuid; - -#endif // APPLE_KEY_MAP_AGGREGATOR_H diff --git a/Include/Protocol/AppleKeyMapDatabase.h b/Include/Protocol/AppleKeyMapDatabase.h deleted file mode 100644 index 33088f8be..000000000 --- a/Include/Protocol/AppleKeyMapDatabase.h +++ /dev/null @@ -1,120 +0,0 @@ -/** @file - Copyright (C) 2005 - 2016, Apple Inc. All rights reserved. - Portions Copyright (C) 2014 - 2016, CupertinoNet. All rights reserved.
- - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -**/ - -#ifndef APPLE_KEY_MAP_DATABASE_H_ -#define APPLE_KEY_MAP_DATABASE_H_ - -#include - -// APPLE_KEY_MAP_DATABASE_PROTOCOL_REVISION -#define APPLE_KEY_MAP_DATABASE_PROTOCOL_REVISION 0x00010000 - -#define APPLE_KEY_MAP_DATABASE_PROTOCOL_GUID \ - {0x584B9EBE, 0x80C1, 0x4BD6, \ - {0x98, 0xB0, 0xA7, 0x78, 0x6E, 0xC2, 0xF2, 0xE2}} - -typedef struct _APPLE_KEY_MAP_DATABASE_PROTOCOL APPLE_KEY_MAP_DATABASE_PROTOCOL; - -// KEY_MAP_CREATE_KEY_STROKES_BUFFER -/** Creates a new key set with a given number of keys allocated. The index - within the database is returned. - - @param[in] This A pointer to the protocol instance. - @param[in] KeyBufferSize The amount of keys to allocate for the key set. - @param[out] Index The assigned index of the created key set. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS A key set with the given number of keys - allocated has been created. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval other An error returned by a sub-operation. -**/ -typedef -EFI_STATUS -(EFIAPI *KEY_MAP_CREATE_KEY_STROKES_BUFFER)( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN KeyBufferSize, - OUT UINTN *Index - ); - -// KEY_MAP_REMOVE_KEY_STROKES_BUFFER -/** Removes a key set specified by its index from the database. - - @param[in] This A pointer to the protocol instance. - @param[in] Index The index of the key set to remove. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS The specified key set has been removed. - @retval EFI_NOT_FOUND No key set could be found for the given index. - @retval other An error returned by a sub-operation. -**/ -typedef -EFI_STATUS -(EFIAPI *KEY_MAP_REMOVE_KEY_STROKES_BUFFER)( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN Index - ); - -// KEY_MAP_SET_KEY_STROKES_KEYS -/** Sets the keys of a key set specified by its index to the given Keys Buffer. - - @param[in] This A pointer to the protocol instance. - @param[in] Index The index of the key set to edit. - @param[in] Modifiers The key modifiers manipulating the given keys. - @param[in] NumberOfKeys The number of keys contained in Keys. - @param[in] Keys An array of keys to add to the specified key set. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS The given keys were set for the specified key - set. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval EFI_NOT_FOUND No key set could be found for the given index. - @retval other An error returned by a sub-operation. -**/ -typedef -EFI_STATUS -(EFIAPI *KEY_MAP_SET_KEY_STROKES_KEYS)( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN Index, - IN APPLE_MODIFIER_MAP Modifiers, - IN UINTN NumberOfKeys, - IN APPLE_KEY *Keys - ); - -// APPLE_KEY_MAP_DATABASE_PROTOCOL -/// The structure exposed by the APPLE_KEY_MAP_DATABASE_PROTOCOL. -struct _APPLE_KEY_MAP_DATABASE_PROTOCOL { - /// The revision of the installed protocol. - UINTN Revision; - - /// A pointer to the CreateKeyStrokesBuffer function. - KEY_MAP_CREATE_KEY_STROKES_BUFFER CreateKeyStrokesBuffer; - - /// A pointer to the RemoveKeyStrokes function. - KEY_MAP_REMOVE_KEY_STROKES_BUFFER RemoveKeyStrokesBuffer; - - /// A pointer to the SetKeyStrokeBufferKeys function. - KEY_MAP_SET_KEY_STROKES_KEYS SetKeyStrokeBufferKeys; -}; - -// gAppleKeyMapDatabaseProtocolGuid -/// A global variable storing the GUID of the APPLE_KEY_MAP_DATABASE_PROTOCOL. -extern EFI_GUID gAppleKeyMapDatabaseProtocolGuid; - -#endif // APPLE_KEY_MAP_DATABASE_H_ diff --git a/Include/Protocol/AppleKeyState.h b/Include/Protocol/AppleKeyState.h index b816efa5d..796dc3b0b 100644 --- a/Include/Protocol/AppleKeyState.h +++ b/Include/Protocol/AppleKeyState.h @@ -10,7 +10,7 @@ #define APPLE_KEY_STATE_PROTOCOL_GUID {0x5b213447, 0x6e73, 0x4901, {0xa4, 0xf1, 0xb8, 0x64, 0xf3, 0xb7, 0xa1, 0x72}} -typedef UINT16 APPLE_KEY; +typedef UINT16 APPLE_KEY_CODE; // APPLE_MODIFIER_MAP typedef UINT16 APPLE_MODIFIER_MAP; @@ -123,9 +123,9 @@ typedef UINT16 APPLE_MODIFIER_MAP; typedef struct _APPLE_KEY_STATE_PROTOCOL APPLE_KEY_STATE_PROTOCOL; -typedef EFI_STATUS (EFIAPI *READ_KEY_STATE)(IN APPLE_KEY_STATE_PROTOCOL *This, OUT UINT16 *ModifyFlags, OUT UINTN *PressedKeyStatesCount, OUT APPLE_KEY *PressedKeyStates); +typedef EFI_STATUS (EFIAPI *READ_KEY_STATE)(IN APPLE_KEY_STATE_PROTOCOL *This, OUT UINT16 *ModifyFlags, OUT UINTN *PressedKeyStatesCount, OUT APPLE_KEY_CODE *PressedKeyStates); //it seems key stroke assumed <8 AppleKeys -typedef EFI_STATUS (EFIAPI *SEARCH_KEY_STROKE)(IN APPLE_KEY_STATE_PROTOCOL *This, IN UINT16 ModifyFlags, IN UINTN PressedKeyStatesCount, IN OUT APPLE_KEY *PressedKeyStates, IN BOOLEAN ExactMatch); +typedef EFI_STATUS (EFIAPI *SEARCH_KEY_STROKE)(IN APPLE_KEY_STATE_PROTOCOL *This, IN UINT16 ModifyFlags, IN UINTN PressedKeyStatesCount, IN OUT APPLE_KEY_CODE *PressedKeyStates, IN BOOLEAN ExactMatch); struct _APPLE_KEY_STATE_PROTOCOL { diff --git a/Include/Protocol/AppleRamDisk.h b/Include/Protocol/AppleRamDisk.h deleted file mode 100644 index b91774488..000000000 --- a/Include/Protocol/AppleRamDisk.h +++ /dev/null @@ -1,386 +0,0 @@ -/** @file - Apple RAM Disk protocol. - -Copyright (C) 2019, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_RAM_DISK_PROTOCOL_H -#define APPLE_RAM_DISK_PROTOCOL_H - -#include -#include -#include - -/** - Apple RAM Disk protocol GUID. - 957932CC-7E8E-433B-8F41-D391EA3C10F8 -**/ -#define APPLE_RAM_DISK_PROTOCOL_GUID \ - { 0x957932CC, 0x7E8E, 0x433B, \ - { 0x8F, 0x41, 0xD3, 0x91, 0xEA, 0x3C, 0x10, 0xF8 } } - -/** - Apple RAM Disk protocol revision. -**/ -#define APPLE_DMG_BOOT_PROTOCOL_REVISION 3 - -/** - RAM Disk extent signature, "RAMDXTNT". -**/ -#define APPLE_RAM_DISK_EXTENT_SIGNATURE 0x544E5458444D4152ULL - -/** - RAM Disk extent version. -**/ -#define APPLE_RAM_DISK_EXTENT_VERSION 0x10000U - -/** - RAM Disk maximum extent count. -**/ -#define APPLE_RAM_DISK_MAX_EXTENTS 0xFE - -#pragma pack(push, 1) - -/** - RAM Disk extent. - When automatically allocating at RAM disk creation, extents are created - on demand as long as contiguous memory is found in the firmware. - - Please note, that this must match IOAddressRange type in XNU, - which can be found in iokit/IOKit/IOTypes.h. -**/ -typedef PACKED struct { - /// - /// Extentent address pointing to a sequence of allocated pages from - /// EfiACPIMemoryNVS or EfiBootServicesData depending on RamDisk init. - /// - UINT64 Start; - /// - /// Actual size of the extent. Allocated area size may be >= Length. - /// - UINT64 Length; -} APPLE_RAM_DISK_EXTENT; - -/** - RAM Disk externally accessible header containing references to extents. -**/ -typedef PACKED struct { - /// - /// Set to APPLE_RAM_DISK_EXTENT_SIGNATURE. - /// - UINT64 Signature; - /// - /// Set to APPLE_RAM_DISK_EXTENT_VERSION. - /// - UINT32 Version; - /// - /// Externally visible amount of extents. - /// - UINT32 ExtentCount; - /// - /// Externally visible extent array. - /// - APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS]; - /// - /// Currently reserved or rather unknown. - /// - UINT64 Reserved; - /// - /// Set to APPLE_RAM_DISK_EXTENT_SIGNATURE. - /// - UINT64 Signature2; -} APPLE_RAM_DISK_EXTENT_TABLE; - -/** - RAM Disk protocol context. This might be called scatter pool. -**/ -typedef PACKED struct { - /// - /// Internally visible amount of extents. - /// - UINT64 ExtentCount; - /// - /// Currently reserved or rather unknown. Padding? - /// - UINT64 Reserved1; - /// - /// Total addressible disk size specified at creation. - /// - UINT64 DiskSize; - /// - /// Internally visible extent array. - /// - APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS]; - /// - /// Currently reserved or rather unknown. Padding? - /// - UINT64 Reserved2; - /// - /// Normal extent table. - /// - APPLE_RAM_DISK_EXTENT_TABLE ExtentTable; - /// - /// More data may follow, for Apple implementation it will be 0x9FD000 bytes. - /// (This struct and 1 page for internal header.) - /// -} APPLE_RAM_DISK_CONTEXT; - -/** - RAM Disk vendor device path, 24 bytes in total. -**/ -typedef PACKED struct { - /// - /// Vendor device path. - /// Type = HARDWARE_DEVICE_PATH. - /// Subtype = HW_VENDOR_DP. - /// Length = sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32). - /// Guid = APPLE_RAM_DISK_PROTOCOL_GUID. - /// - VENDOR_DEVICE_PATH Vendor; - /// - /// Globally incremented counter to make every path unique. - /// - UINT32 Counter; -} APPLE_RAM_DISK_DP_VENDOR; - -/** - RAM Disk device path header for endpoint devices. -**/ -typedef PACKED struct { - /// - /// Vendor device path. - /// - APPLE_RAM_DISK_DP_VENDOR Vendor; - /// - /// Memmap device path. - /// - MEMMAP_DEVICE_PATH MemMap; -} APPLE_RAM_DISK_DP_HEADER; - -/** - RAM Disk device path, 52 bytes in total. -**/ -typedef PACKED struct { - /// - /// Vendor device path with APPLE_RAM_DISK_PROTOCOL_GUID. - /// Type = HARDWARE_DEVICE_PATH. - /// Subtype = HW_MEMMAP_DP. - /// Length = sizeof (APPLE_RAM_DISK_ENTRY_DP). - /// StartingAddresss = APPLE_RAM_DISK_EXTENT_TABLE pointer. - /// EndingAddress = StartingAddresss + sizeof (APPLE_RAM_DISK_EXTENT_TABLE). - /// MemoryType = EfiACPIMemoryNVS or EfiBootServicesData as allocated. - /// - /// Note: EndingAddress, per UEFI specification and edk2 implementation, is supposed - /// to be the top usable address, not the top of the buffer. Perhaps there is a mistake here. - /// - APPLE_RAM_DISK_DP_VENDOR Vendor; - /// - /// Memmap device path. - /// - MEMMAP_DEVICE_PATH MemMap; - /// - /// Device path end. - /// - EFI_DEVICE_PATH_PROTOCOL End; -} APPLE_RAM_DISK_DP; - -#pragma pack(pop) - -/** - Create new RAM disk providing relevant protocols: - - gEfiDevicePathProtocolGuid - - gEfiBlockIoProtocolGuid - - gAppleRamDiskProtocolGuid (as NULL) - - When AllocateMemory is TRUE, a writeable RAM disk is created. - Its contents are initially zeroed, and then may be modified through normal writing - and via RAM Disk context, which is accessible through GetRamDiskContext. - - When AllocateMemory is FALSE, a read only RAM disk is created. - Its contents are not allocated but reported to be all zero. - MemMap StartingAddresss will be 0 and EndingAddress will be sizeof (APPLE_RAM_DISK_EXTENT_TABLE). - Vit: Since no context is allocated, there is no way to initialise this disk image except in an - implementatation specific way. AllocateMemory = FALSE is never used, so it may be a bug. - - @param[in] BlockCount Block amount, ignored if AllocateMemory is FALSE. - @param[in] BlockSize Block size, ignored if AllocateMemory is FALSE. - @param[in] AllocateMemory Allocate disk memory. - @param[in] ReserveMemory Mark memory as EfiACPIMemoryNVS, otherwise EfiBootServicesData. - @param[in] Handle Resulting handle. - - @retval EFI_SUCCESS RAM disk was successfully created. - @retval EFI_OUT_OF_RESOURCES Requested RAM disk of more than SIZE_16TB. - @retval EFI_OUT_OF_RESOURCES Memory allocation error happened. - @retval EFI_INVALID_PARAMETER Too many extents are needed for the allocation. - @retval EFI_BUFFER_TOO_SMALL Not enough extents to allocate context extent. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RAM_DISK_CREATE) ( - IN UINT64 BlockCount OPTIONAL, - IN UINT32 BlockSize OPTIONAL, - IN BOOLEAN AllocateMemory, - IN BOOLEAN ReserveMemory, - OUT EFI_HANDLE *Handle - ); - -/** - Destroy RAM disk freeing resources and uninstalling relevant protocols: - - gEfiDevicePathProtocolGuid - - gEfiBlockIoProtocolGuid - - gAppleRamDiskProtocolGuid - - gTDMApprovedGuid - - @param[in] Handle RAM disk handle. - - @retval EFI_INVALID_PARAMETER Not a RAM disk handle. - @retval EFI_NOT_FOUND Missing Block I/O protocol. - @retval EFI_SUCCESS Destroyed successfully. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RAM_DISK_DESTROY) ( - IN EFI_HANDLE Handle - ); - -/** - Obtain RAM disk context. Context exists only for "allocated" RAM disks, - i.e. disks created with AllocateMemory = TRUE. When an unallocated - RAM disk is created, NULL Context will be returned. - - @param[in] Handle RAM disk handle. - @param[out] Context RAM disk context. - - @retval EFI_INVALID_PARAMETER Not a RAM disk handle. - @retval EFI_NOT_FOUND Missing Block I/O protocol. - @retval EFI_SUCCESS Obtained NULL or non-NULL context successfully. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RAM_DISK_GET_CONTEXT) ( - IN EFI_HANDLE Handle, - OUT APPLE_RAM_DISK_CONTEXT *Context - ); - -/** - Apple RAM Disk protocol. -**/ -typedef struct { - UINT64 Revision; - APPLE_RAM_DISK_CREATE CreateRamDisk; - APPLE_RAM_DISK_DESTROY DestroyRamDisk; - APPLE_RAM_DISK_GET_CONTEXT GetRamDiskContext; -} APPLE_RAM_DISK_PROTOCOL; -/* -STATIC_ASSERT (sizeof (APPLE_RAM_DISK_DP_VENDOR) == 24, "Invalid APPLE_RAM_DISK_DP_VENDOR size"); -STATIC_ASSERT (sizeof (APPLE_RAM_DISK_DP) == 52, "Invalid APPLE_RAM_DISK_DP size"); -STATIC_ASSERT (sizeof (APPLE_RAM_DISK_EXTENT) == 16, "Invalid APPLE_RAM_DISK_EXTENT size"); -STATIC_ASSERT (sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == 4096, "Invalid APPLE_RAM_DISK_EXTENT_TABLE size"); -STATIC_ASSERT (sizeof (APPLE_RAM_DISK_CONTEXT) == 8192, "Invalid APPLE_RAM_DISK_CONTEXT size"); -*/ -extern EFI_GUID gAppleRamDiskProtocolGuid; - -/** - Vit: Below come the implementation specific details, which probably do not belong here. - Since this is the only way to initialize RAM disk when it was not allocated at creation time, - I put it here for now. -**/ - -/** - RAM Disk instance signature, "RAMD". -**/ -#define APPLE_RAM_DISK_INSTANCE_SIGNATURE 0x444D4152U - -/** - RAM Disk default size. - This value is used when allocating APPLE_RAM_DISK structure. -**/ -#define APPLE_RAM_DISK_DEFAULT_SIZE 0xA00000U - -/** - RAM Disk outermost structure. Allocated in pages with matching MemoryType. -**/ -typedef struct { - /// - /// Amount of allocated extents in the RAM disk. - /// - UINT64 AllocatedExtents; - /// - /// Amount of allocated pages in APPLE_RAM_DISK structure. - /// Normally EFI_SIZE_TO_PAGES (APPLE_RAM_DISK_DEFAULT_SIZE). - /// - UINT64 PageCount; - /// - /// Total disk size allocated from memory map. - /// It is bigger by sizeof(APPLE_RAM_DISK_CONTEXT) than actual requested size, - /// when AllocateMemory = TRUE is specified. - /// - UINT64 TotalSize; - /// - /// All allocated and owned extents. - /// First extent is special, as it points to OwnExtentData, and thus - /// has APPLE_RAM_DISK_DEFAULT_SIZE - sizeof (APPLE_RAM_DISK) bytes. - /// - APPLE_RAM_DISK_EXTENT Extents[APPLE_RAM_DISK_MAX_EXTENTS]; - /// - /// Currently reserved or rather unknown. Padding? - /// - UINT64 Reserved; - /// - /// Own extent data lasting till PageCount end. - /// - UINT8 OwnExtentData[]; -} APPLE_RAM_DISK; - -/** - Apple RAM Disk instance structure. -**/ -typedef struct { - /// - /// Set to APPLE_RAM_DISK_INSTANCE_SIGNATURE. - /// - UINT32 Magic; - /// - /// Set to RAM disk handle, formerly returned with CreateRamDisk. - /// - EFI_HANDLE Handle; - /// - /// RAM disk device path. - /// - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - /// - /// RAM disk Block I/O protocol. - /// - EFI_BLOCK_IO_PROTOCOL BlockIo; - /// - /// Outer RAM disk structure, which owns all allocated extents. - /// This field is NULL when AllocateMemory = FALSE. - /// - APPLE_RAM_DISK *RamDisk; - /// - /// RAM disk context allocated within RAM disk structure memory. - /// Apple implementation puts it to the end of RamDisk structure. - /// This field is NULL when AllocateMemory = FALSE. - /// - APPLE_RAM_DISK_CONTEXT *Context; - /// - /// Extra pointer to Context->Extents. - /// This field is NULL when AllocateMemory = FALSE. - /// - APPLE_RAM_DISK_EXTENT_TABLE *Extents; - /// - /// Total addressible disk size specified at creation. - /// This field is -1 when AllocateMemory = FALSE. - /// - INT64 DiskSize; -} APPLE_RAM_DISK_INSTANCE; - -#endif // APPLE_RAM_DISK_PROTOCOL_H diff --git a/Include/Protocol/AppleRtcRam.h b/Include/Protocol/AppleRtcRam.h deleted file mode 100644 index cb2a5deba..000000000 --- a/Include/Protocol/AppleRtcRam.h +++ /dev/null @@ -1,144 +0,0 @@ -/** @file - Apple RTC RAM. - -Copyright (C) 2020, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_RTC_RAM_PROTOCOL_H -#define APPLE_RTC_RAM_PROTOCOL_H - -#include - -/** - Installed by RTC driver. - E121EC07-9C42-45EE-B0B6-FFF8EF03C521 - Found in AppleRtcRam (CC54F583-3F9E-4AB0-9F7C-D2C7ED1C87A5). - - Note, there is a sibling driver in PEI: - 13CFE225-E07B-40F3-9703-EBE99318766E - Found in AppleRtcRamPeim (1B99796D-2A26-437E-BEE0-014F0EBBECE1). -**/ - -#define APPLE_RTC_RAM_PROTOCOL_GUID \ - { 0xE121EC07, 0x9C42, 0x45EE, \ - { 0xB0, 0xB6, 0xFF, 0xF8, 0xEF, 0x03, 0xC5, 0x21 } } - -typedef struct APPLE_RTC_RAM_PROTOCOL_ APPLE_RTC_RAM_PROTOCOL; - -/** - Obtain available RTC memory in bytes. - - @param[in] This Apple RTC RAM protocol instance. - - @retval 256 under normal circumstances. -**/ -typedef -UINTN -(EFIAPI *APPLE_RTC_RAM_GET_AVAILABLE_MEMORY) ( - IN APPLE_RTC_RAM_PROTOCOL *This - ); - -/** - Read memory from RTC. - - @param[in] This Apple RTC RAM protocol instance. - @param[out] Buffer Destination buffer to read to. - @param[in] BufferSize The amount of memory to read in bytes. - @param[in] Address The starting RTC offset to read from. - - The implementation should respect data consistency: - - If APPLE_RTC_BG_COLOR_ADDR ^ APPLE_RTC_BG_COMPLEMENT_ADDR != 0xFF - APPLE_RTC_BG_COLOR_GRAY should be returned for APPLE_RTC_BG_COLOR_ADDR. - - @retval EFI_INVALID_PARAMETER when Buffer is NULL. - @retval EFI_INVALID_PARAMETER when BufferSize is 0. - @retval EFI_INVALID_PARAMETER when the requested memory is out of range. - @retval EFI_ACCESS_DENIED when an RTC I/O operating is in progress. - @retval EFI_TIMEOUT when RTC device is not ready. - @retval EFI_SUCCESS on success. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RTC_RAM_READ_MEMORY) ( - IN APPLE_RTC_RAM_PROTOCOL *This, - OUT UINT8 *Buffer, - IN UINTN BufferSize, - IN UINTN Address - ); - -/** - Write memory to RTC. - - @param[in] This Apple RTC RAM protocol instance. - @param[in] Buffer Source buffer to write to RTC. - @param[in] BufferSize The amount of memory to write in bytes. - @param[in] Address The starting RTC offset to write to. - - The implementation should maintain data consistency: - - APPLE_RTC_BG_COMPLEMENT_ADDR should be set to ~APPLE_RTC_BG_COLOR_ADDR. - - APPLE_RTC_CORE_CHECKSUM_ADDR1 / APPLE_RTC_CORE_CHECKSUM_ADDR2 should - be recalculated if necessary. - - APPLE_RTC_MAIN_CHECKSUM_ADDR1 / APPLE_RTC_MAIN_CHECKSUM_ADDR2 should - be recalculated if necessary. - - @retval EFI_INVALID_PARAMETER when Buffer is NULL. - @retval EFI_INVALID_PARAMETER when BufferSize is 0. - @retval EFI_INVALID_PARAMETER when the requested memory is out of range. - @retval EFI_INVALID_PARAMETER when trying to update system memory - before APPLE_RTC_CHECKSUM_START. - @retval EFI_OUT_OF_RESOURCES when a memory allocation error happened. - @retval EFI_ACCESS_DENIED when an RTC I/O operating is in progress. - @retval EFI_TIMEOUT when RTC device is not ready. - @retval EFI_SUCCESS on success. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RTC_RAM_WRITE_MEMORY) ( - IN APPLE_RTC_RAM_PROTOCOL *This, - IN CONST UINT8 *Buffer, - IN UINTN BufferSize, - IN UINTN Address - ); - -/** - Reset RTC memory to default values. For uses like CMD+OPT+P+R. - - The implementation should maintain data consistency: - - Core memory as defined by APPLE_RTC_CORE_SIZE should not be changed. - - Preserve APPLE_RTC_RESERVED_ADDR area. - - Preserve APPLE_RTC_FIRMWARE_57_ADDR address. - - @param[in] This Apple RTC RAM protocol instance. - - @retval EFI_OUT_OF_RESOURCES when a memory allocation error happened. - @retval EFI_ACCESS_DENIED when an RTC I/O operating is in progress. - @retval EFI_TIMEOUT when RTC device is not ready. - @retval EFI_SUCCESS on success. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_RTC_RAM_RESET_MEMORY) ( - IN APPLE_RTC_RAM_PROTOCOL *This - ); - -/** - Apple RTC protocol structure. -**/ -struct APPLE_RTC_RAM_PROTOCOL_ { - APPLE_RTC_RAM_GET_AVAILABLE_MEMORY GetAvailableMemory; - APPLE_RTC_RAM_READ_MEMORY ReadMemory; - APPLE_RTC_RAM_WRITE_MEMORY WriteMemory; - APPLE_RTC_RAM_RESET_MEMORY ResetMemory; -}; - -extern EFI_GUID gAppleRtcRamProtocolGuid; - -#endif // APPLE_RTC_RAM_PROTOCOL_H diff --git a/Include/Protocol/AppleVoiceOver.h b/Include/Protocol/AppleVoiceOver.h deleted file mode 100644 index 476024c2f..000000000 --- a/Include/Protocol/AppleVoiceOver.h +++ /dev/null @@ -1,181 +0,0 @@ -/** @file - Apple VoiceOver Audio protocol. - -Copyright (C) 2020, vit9696. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef APPLE_VO_AUDIO_H -#define APPLE_VO_AUDIO_H - -/** - Apple VoiceOver Audio protocol GUID. - This protocol is present on Gibraltar Macs (ones with T1/T2 and custom HDA). - F4CB0B78-243B-11E7-A524-B8E8562CBAFA -**/ -#define APPLE_VOICE_OVER_AUDIO_PROTOCOL_GUID \ - { 0xF4CB0B78, 0x243B, 0x11E7, \ - { 0xA5, 0x24, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } } - -typedef struct APPLE_VOICE_OVER_AUDIO_PROTOCOL_ APPLE_VOICE_OVER_AUDIO_PROTOCOL; - -/** - Apple VoiceOver Audio protocol revision. -**/ -#define APPLE_VOICE_OVER_AUDIO_PROTOCOL_REVISION 0x10000 - - -/** - These files can be found either on BridgeOS volume: - /System/Library/PrivateFrameworks/BridgeAccessibilitySupport.framework/AXEFIAudio_[ru]_[VoiceOverOn].aiff - Here language code (ru) can be both full (ru_RU) and short (ru). - For unlocalised files language code can be missing entirely, e.g. AXEFIAudio_Beep.aiff. - Or in /Volumes/Preboot/.../System/Library/Caches/com.apple.corestorage/EFILoginLocalizations/sound.efires - For preboot the file format is sound_SCREFIAudio.VoiceOverOn. - Files marked with * are only present on BridgeOS. -**/ -typedef enum { - AppleVoiceOverAudioFileVoiceOverOn = 0x01, ///< VoiceOverOn - AppleVoiceOverAudioFileVoiceOverOff = 0x02, ///< VoiceOverOff - AppleVoiceOverAudioFileUsername = 0x03, ///< Username - AppleVoiceOverAudioFilePassword = 0x04, ///< Password - AppleVoiceOverAudioFileUsernameOrPasswordIncorrect = 0x05, ///< UsernameOrPasswordIncorrect - AppleVoiceOverAudioFileAccountLockedTryLater = 0x06, ///< AccountLockedTryLater (*) - AppleVoiceOverAudioFileAccountLocked = 0x07, ///< AccountLocked (*) - AppleVoiceOverAudioFileVoiceOverBoot = 0x3B, ///< VoiceOver_Boot (*) - AppleVoiceOverAudioFileVoiceOverBoot2 = 0x3C, ///< VoiceOver_Boot (*) - AppleVoiceOverAudioFileClick = 0x3D, ///< Click (*) - AppleVoiceOverAudioFileBeep = 0x3E, ///< Beep - AppleVoiceOverAudioFileMax = 0x3F, -} APPLE_VOICE_OVER_AUDIO_FILE; - -/** - VoiceOver language codes. -**/ -typedef enum { - AppleVoiceOverLanguageAr = 0x01, ///< ar - AppleVoiceOverLanguageCa = 0x02, ///< ca - AppleVoiceOverLanguageCs = 0x03, ///< cs - AppleVoiceOverLanguageDa = 0x04, ///< da - AppleVoiceOverLanguageDe = 0x05, ///< de - AppleVoiceOverLanguageEl = 0x06, ///< el - AppleVoiceOverLanguageEn = 0x07, ///< en - AppleVoiceOverLanguageEs = 0x08, ///< es - AppleVoiceOverLanguageEs419 = 0x09, ///< es-419 - AppleVoiceOverLanguageEsMx = 0x0A, ///< es-MX - AppleVoiceOverLanguageFi = 0x0B, ///< fi - AppleVoiceOverLanguageFr = 0x0C, ///< fr - AppleVoiceOverLanguageHe = 0x0D, ///< he - AppleVoiceOverLanguageHi = 0x0E, ///< hi - AppleVoiceOverLanguageHr = 0x0F, ///< hr - AppleVoiceOverLanguageHu = 0x10, ///< hu - AppleVoiceOverLanguageId = 0x11, ///< id - AppleVoiceOverLanguageIt = 0x12, ///< it - AppleVoiceOverLanguageJa = 0x13, ///< ja - AppleVoiceOverLanguageKo = 0x14, ///< ko - AppleVoiceOverLanguageNl = 0x15, ///< nl - AppleVoiceOverLanguageNo = 0x16, ///< no - AppleVoiceOverLanguageMy = 0x17, ///< my - AppleVoiceOverLanguagePl = 0x18, ///< pl - AppleVoiceOverLanguagePt = 0x19, ///< pt - AppleVoiceOverLanguagePtPt = 0x1A, ///< pt-PT - AppleVoiceOverLanguageRo = 0x1B, ///< ro - AppleVoiceOverLanguageRu = 0x1C, ///< ru - AppleVoiceOverLanguageSk = 0x1D, ///< sk - AppleVoiceOverLanguageSv = 0x1E, ///< sv - AppleVoiceOverLanguageTh = 0x1F, ///< th - AppleVoiceOverLanguageTr = 0x20, ///< tr - AppleVoiceOverLanguageUk = 0x21, ///< uk - AppleVoiceOverLanguageVi = 0x22, ///< vi - AppleVoiceOverLanguageZhHans = 0x23, ///< zh-Hans - AppleVoiceOverLanguageZhHant = 0x24, ///< zh-Hant -} APPLE_VOICE_OVER_LANGUAGE_CODE; - -/** - Play audio file. - - @param[in] This VoiceOver protocol instance. - @param[in] File File to play. - - @retval EFI_SUCCESS on successful playback startup. - @retval EFI_NOT_FOUND when audio device is missing. - @retval EFI_INVALID_PARAMETER when audio file is not valid. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_VOICE_OVER_AUDIO_PLAY) ( - IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, - IN UINT8 File - ); - -/** - Set language for VoiceOver support via code. - - @param[in] This VoiceOver protocol instance. - @param[in] LanguageCode Language code (e.g. AppleVoiceOverLanguageEn). - - @retval EFI_SUCCESS on successful language update. - @retval EFI_INVALID_PARAMETER when the language is unsupported. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_CODE) ( - IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, - IN UINT8 LanguageCode - ); - -/** - Set language for VoiceOver support via string. - - @param[in] This VoiceOver protocol instance. - @param[in] LanguageString Language string (e.g. ru or ru-RU). - - @retval EFI_SUCCESS on successful language update. - @retval EFI_INVALID_PARAMETER when the language is unsupported. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_STRING) ( - IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, - IN CONST CHAR8 *LanguageString - ); - -/** - Get current VoiceOver language. - - @param[in] This VoiceOver protocol instance. - @param[out] LanguageCode Current language code (e.g. AppleVoiceOverLanguageRu). - @param[out] LanguageString Current language string (e.g. ru) or NULL. - - @retval EFI_SUCCESS on successful language update. - @retval EFI_INVALID_PARAMETER when the language is unsupported. -**/ -typedef -EFI_STATUS -(EFIAPI *APPLE_VOICE_OVER_AUDIO_GET_LANGUAGE) ( - IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, - OUT UINT8 *LanguageCode, - OUT CONST CHAR8 **LanguageString - ); - -/** - VoiceOver protocol. -**/ -struct APPLE_VOICE_OVER_AUDIO_PROTOCOL_ { - UINTN Revision; - APPLE_VOICE_OVER_AUDIO_PLAY Play; - APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_CODE SetLanguageCode; - APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_STRING SetLanguageString; - APPLE_VOICE_OVER_AUDIO_GET_LANGUAGE GetLanguage; -}; - -extern EFI_GUID gAppleVOAudioProtocolGuid; - -#endif // APPLE_VO_AUDIO_H diff --git a/Include/Protocol/OSInfo.h b/Include/Protocol/OSInfo.h deleted file mode 100644 index 48f59f9df..000000000 --- a/Include/Protocol/OSInfo.h +++ /dev/null @@ -1,66 +0,0 @@ -/** @file -Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef EFI_OS_INFO_H -#define EFI_OS_INFO_H - -// EFI_OS_INFO_PROTOCOL_REVISION -#define EFI_OS_INFO_PROTOCOL_REVISION3 0x00000003 - -// EFI_OS_INFO_PROTOCOL_GUID -#define EFI_OS_INFO_PROTOCOL_GUID \ - { 0xC5C5DA95, 0x7D5C, 0x45E6, \ - { 0xB2, 0xF1, 0x3F, 0xD5, 0x2B, 0xB1, 0x00, 0x77 } } - -#define EFI_OS_INFO_APPLE_VENDOR_NAME "Apple Inc." - -// OS_INFO_OS_NAME -typedef -VOID -(EFIAPI *OS_INFO_OS_NAME)( - IN CHAR8 *OSName - ); - -// OS_INFO_OS_VENDOR -typedef -VOID -(EFIAPI *OS_INFO_OS_VENDOR)( - IN CHAR8 *OSName - ); - -// OS_INFO_SET_VTD_ENABLED -typedef -VOID -(EFIAPI *OS_INFO_SET_VTD_ENABLED)( - IN UINTN *BootVTdEnabled - ); - -// OS_INFO_GET_VTD_ENABLED -typedef -VOID -(EFIAPI *OS_INFO_GET_VTD_ENABLED)( - OUT UINTN *BootVTdEnabled - ); - -// EFI_OS_INFO_PROTOCOL -typedef struct { - UINTN Revision; ///< Revision. - OS_INFO_OS_NAME OSName; ///< Present as of Revision 1. - OS_INFO_OS_VENDOR OSVendor; ///< Present as of Revision 2. - OS_INFO_SET_VTD_ENABLED SetBootVTdEnabled; ///< Present as of Revision 3. - OS_INFO_GET_VTD_ENABLED GetBootVTdEnabled; ///< Present as of Revision 3. -} EFI_OS_INFO_PROTOCOL; - -// gEfiOSInfoProtocolGuid -extern EFI_GUID gEfiOSInfoProtocolGuid; - -#endif // EFI_OS_INFO_H diff --git a/Include/Protocol/OcAfterBootCompat.h b/Include/Protocol/OcAfterBootCompat.h deleted file mode 100644 index 21f8adedb..000000000 --- a/Include/Protocol/OcAfterBootCompat.h +++ /dev/null @@ -1,37 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_AFTER_BOOT_COMPAT_PROTOCOL_H -#define OC_AFTER_BOOT_COMPAT_PROTOCOL_H - -#define OC_AFTER_BOOT_COMPAT_PROTOCOL_REVISION 0x010000 - -// -// OC_AFTER_BOOT_COMPAT_PROTOCOL_GUID -// C7CBA84E-CC77-461D-9E3C-6BE0CB79A7C1 -// -#define OC_AFTER_BOOT_COMPAT_PROTOCOL_GUID \ - { 0xC7CBA84E, 0xCC77, 0x461D, \ - { 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } } - -// -// Includes a revision for debugging reasons -// -typedef struct { - UINTN Revision; -} OC_AFTER_BOOT_COMPAT_PROTOCOL; - -extern EFI_GUID gOcAfterBootCompatProtocolGuid; - -#endif // OC_AFTER_BOOT_COMPAT_PROTOCOL_H diff --git a/Include/Protocol/OcAudio.h b/Include/Protocol/OcAudio.h deleted file mode 100644 index c896ec01c..000000000 --- a/Include/Protocol/OcAudio.h +++ /dev/null @@ -1,234 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_AUDIO_PROTOCOL_H -#define OC_AUDIO_PROTOCOL_H - -#include -#include - -#define OC_AUDIO_PROTOCOL_REVISION 0x010000 - -// -// OC_AUDIO_PROTOCOL_GUID -// 4B228577-6274-4A48-82AE-0713A1171987 -// -#define OC_AUDIO_PROTOCOL_GUID \ - { 0x4B228577, 0x6274, 0x4A48, \ - { 0x82, 0xAE, 0x07, 0x13, 0xA1, 0x17, 0x19, 0x87 } } - -typedef struct OC_AUDIO_PROTOCOL_ OC_AUDIO_PROTOCOL; - -/** - Custom OpenCore audio files. -**/ -typedef enum { - OcVoiceOverAudioFileBase = 0x1000, - - OcVoiceOverAudioFileIndexBase = 0x1000, - OcVoiceOverAudioFile1 = 0x1001, - OcVoiceOverAudioFile2 = 0x1002, - OcVoiceOverAudioFile3 = 0x1003, - OcVoiceOverAudioFile4 = 0x1004, - OcVoiceOverAudioFile5 = 0x1005, - OcVoiceOverAudioFile6 = 0x1006, - OcVoiceOverAudioFile7 = 0x1007, - OcVoiceOverAudioFile8 = 0x1008, - OcVoiceOverAudioFile9 = 0x1009, - OcVoiceOverAudioFileIndexAlphabetical = 0x100A, - OcVoiceOverAudioFileLetterA = 0x100A, - OcVoiceOverAudioFileLetterB = 0x100B, - OcVoiceOverAudioFileLetterC = 0x100C, - OcVoiceOverAudioFileLetterD = 0x100D, - OcVoiceOverAudioFileLetterE = 0x100E, - OcVoiceOverAudioFileLetterF = 0x100F, - OcVoiceOverAudioFileLetterG = 0x1010, - OcVoiceOverAudioFileLetterH = 0x1011, - OcVoiceOverAudioFileLetterI = 0x1012, - OcVoiceOverAudioFileLetterJ = 0x1013, - OcVoiceOverAudioFileLetterK = 0x1014, - OcVoiceOverAudioFileLetterL = 0x1015, - OcVoiceOverAudioFileLetterM = 0x1016, - OcVoiceOverAudioFileLetterN = 0x1017, - OcVoiceOverAudioFileLetterO = 0x1018, - OcVoiceOverAudioFileLetterP = 0x1019, - OcVoiceOverAudioFileLetterQ = 0x101A, - OcVoiceOverAudioFileLetterR = 0x101B, - OcVoiceOverAudioFileLetterS = 0x101C, - OcVoiceOverAudioFileLetterT = 0x101D, - OcVoiceOverAudioFileLetterU = 0x101E, - OcVoiceOverAudioFileLetterV = 0x101F, - OcVoiceOverAudioFileLetterW = 0x1020, - OcVoiceOverAudioFileLetterX = 0x1021, - OcVoiceOverAudioFileLetterY = 0x1022, - OcVoiceOverAudioFileLetterZ = 0x1023, - OcVoiceOverAudioFileIndexMax = 0x1023, - - OcVoiceOverAudioFileAbortTimeout = 0x1030, - OcVoiceOverAudioFileChooseOS = 0x1031, - OcVoiceOverAudioFileDefault = 0x1032, - OcVoiceOverAudioFileDiskImage = 0x1033, - OcVoiceOverAudioFileEnterPassword = 0x1034, - OcVoiceOverAudioFileExecutionFailure = 0x1035, - OcVoiceOverAudioFileExecutionSuccessful = 0x1036, - OcVoiceOverAudioFileExternal = 0x1037, - OcVoiceOverAudioFileExternalOS = 0x1038, - OcVoiceOverAudioFileExternalTool = 0x1039, - OcVoiceOverAudioFileLoading = 0x103A, - OcVoiceOverAudioFilemacOS = 0x103B, - OcVoiceOverAudioFilemacOS_Recovery = 0x103C, - OcVoiceOverAudioFilemacOS_TimeMachine = 0x103D, - OcVoiceOverAudioFilemacOS_UpdateFw = 0x103E, - OcVoiceOverAudioFileOtherOS = 0x103F, - OcVoiceOverAudioFilePasswordAccepted = 0x1040, - OcVoiceOverAudioFilePasswordIncorrect = 0x1041, - OcVoiceOverAudioFilePasswordRetryLimit = 0x1042, - OcVoiceOverAudioFileReloading = 0x1043, - OcVoiceOverAudioFileResetNVRAM = 0x1044, - OcVoiceOverAudioFileSelected = 0x1045, - OcVoiceOverAudioFileShowAuxiliary = 0x1046, - OcVoiceOverAudioFileTimeout = 0x1047, - OcVoiceOverAudioFileUEFI_Shell = 0x1048, - OcVoiceOverAudioFileWelcome = 0x1049, - OcVoiceOverAudioFileWindows = 0x104A, - - OcVoiceOverAudioFileMax = 0x104B, -} OC_VOICE_OVER_AUDIO_FILE; - -//STATIC_ASSERT (OcVoiceOverAudioFileIndexMax - OcVoiceOverAudioFileIndexBase == 9 + 26, "Invalid index count"); - -/** - Connect to Audio I/O. - - @param[in,out] This Audio protocol instance. - @param[in] DevicePath Controller device path, optional. - @param[in] CodecAddress Codec address, optional. - @param[in] OutputIndex Output index, optional. - @param[in] Volume Raw volume level from 0 to 100. - - @retval EFI_SUCESS on success. - @retval EFI_NOT_FOUND when missing. - @retval EFI_UNSUPPORTED on failure. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_CONNECT) ( - IN OUT OC_AUDIO_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, - IN UINT8 CodecAddress OPTIONAL, - IN UINT8 OutputIndex OPTIONAL, - IN UINT8 Volume - ); - -/** - Retrive file contents callback. - - @param[in,out] Context Externally specified context. - @param[in] File File identifier, see APPLE_VOICE_OVER_AUDIO_FILE. - @paran[in] LanguageCode Language code for the file. - @param[out] Buffer Pointer to buffer. - @param[out] BufferSize Pointer to buffer size. - - @retval EFI_SUCCESS on successful file lookup. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_PROVIDER_ACQUIRE) ( - IN VOID *Context, - IN UINT32 File, - IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode, - OUT UINT8 **Buffer, - OUT UINT32 *BufferSize - ); - -/** - Release file contents given by acquire callback. - - @param[in,out] Context Externally specified context. - @param[out] Buffer Pointer to buffer. - - @retval EFI_SUCCESS on successful release. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_PROVIDER_RELEASE) ( - IN VOID *Context, - IN UINT8 *Buffer - ); - -/** - Set resource provider. - - @param[in,out] This Audio protocol instance. - @param[in] Acquire Resource acquire handler. - @param[in] Release Resource release handler, optional. - @param[in] Context Resource handler context. - - @retval EFI_SUCCESS on successful provider update. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_SET_PROVIDER) ( - IN OUT OC_AUDIO_PROTOCOL *This, - IN OC_AUDIO_PROVIDER_ACQUIRE Acquire, - IN OC_AUDIO_PROVIDER_RELEASE Release OPTIONAL, - IN VOID *Context - ); - -/** - Play file. - - @param[in,out] This Audio protocol instance. - @param[in] File File to play. - @param[in] Wait Wait for completion of the previous track. - - @retval EFI_SUCCESS on successful playback startup. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_PLAY_FILE) ( - IN OUT OC_AUDIO_PROTOCOL *This, - IN UINT32 File, - IN BOOLEAN Wait - ); - -/** - Stop playback. - - @param[in,out] This Audio protocol instance. - @param[in] Wait Wait for audio completion. - - @retval EFI_SUCCESS on successful playback stop. -**/ -typedef -EFI_STATUS -(EFIAPI* OC_AUDIO_STOP_PLAYBACK) ( - IN OUT OC_AUDIO_PROTOCOL *This, - IN BOOLEAN Wait - ); - -// -// Includes a revision for debugging reasons. -// -struct OC_AUDIO_PROTOCOL_ { - UINTN Revision; - OC_AUDIO_CONNECT Connect; - OC_AUDIO_SET_PROVIDER SetProvider; - OC_AUDIO_PLAY_FILE PlayFile; - OC_AUDIO_STOP_PLAYBACK StopPlayback; -}; - -extern EFI_GUID gOcAudioProtocolGuid; - -#endif // OC_AUDIO_PROTOCOL_H diff --git a/Include/Protocol/OcFirmwareRuntime.h b/Include/Protocol/OcFirmwareRuntime.h deleted file mode 100644 index f66fbab6c..000000000 --- a/Include/Protocol/OcFirmwareRuntime.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_FIRMWARE_RUNTIME_PROTOCOL_H -#define OC_FIRMWARE_RUNTIME_PROTOCOL_H - -#include - -#define OC_FIRMWARE_RUNTIME_REVISION 11 - -/** - OC_FIRMWARE_RUNTIME_PROTOCOL_GUID - 570332E4-FC50-4B21-ABE8-AE72F05B4FF7 -**/ -#define OC_FIRMWARE_RUNTIME_PROTOCOL_GUID \ - { 0x570332E4, 0xFC50, 0x4B21, \ - { 0xAB, 0xE8, 0xAE, 0x72, 0xF0, 0x5B, 0x4F, 0xF7 } } -/** - Configuration request to change firmware runtime behaviour. -**/ -typedef struct OC_FWRT_CONFIG_ { - /// - /// Enforce restricted access to OpenCore read-only and write-only GUIDs. - /// - BOOLEAN RestrictedVariables; - /// - /// Enforce BootXXXX variable redirection to OpenCore vendor GUID. - /// - BOOLEAN BootVariableRedirect; - /// - /// Make SetVariable do nothing and always return EFI_SECURITY_VIOLATION. - /// When we do not want variables to be stored in NVRAM or NVRAM implementation - /// is buggy we can disable variable writing. - /// - BOOLEAN WriteProtection; - /// - /// Make UEFI runtime services drop CR0 WP bit on calls to allow writing - /// to read only memory. This workarounds a bug in many APTIO firmwares - /// that do not survive W^X. - /// Latest Windows brings Virtualization-based security and monitors - /// CR0 by launching itself under a hypevisor. Since we need WP disable - /// on macOS to let NVRAM work, and for the time being no other OS - /// requires it, here we decide to use it for macOS exclusively. - /// - BOOLEAN WriteUnprotector; - /// - /// Secure boot variable protection. - /// - BOOLEAN ProtectSecureBoot; -} OC_FWRT_CONFIG; - -/** - Get current used configuration data. - - @param[out] Config Current configuration to store. -**/ -typedef -VOID -(EFIAPI *OC_FWRT_GET_CURRENT_CONFIG) ( - OUT OC_FWRT_CONFIG *Config - ); - -/** - Set main configuration. - - @param[in] Config Runtime services configuration to apply. -**/ -typedef -VOID -(EFIAPI *OC_FWRT_SET_MAIN_CONFIG) ( - IN CONST OC_FWRT_CONFIG *Config - ); - -/** - Perform configuration override, NULL Config implies disable override. - - @param[in] Config Runtime services configuration to apply, optional. -**/ -typedef -VOID -(EFIAPI *OC_FWRT_SET_OVERRIDE_CONFIG) ( - IN CONST OC_FWRT_CONFIG *Config OPTIONAL - ); - -/** - Set GetVariable override for customising values. - - @param[in] GetVariable GetVariable to call on each call. - @param[out] OrgGetVariable Original GetVariable to call from GetVariable. - - @retval EFI_SUCCESS on successful override. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_FWRT_ON_GET_VARIABLE) ( - IN EFI_GET_VARIABLE GetVariable, - OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL - ); - -/** - Obtain area that needs to be executable in OS runtime. - - @param[out] BaseAddress Executable area start. - @param[out] Pages Number of executable pages. - - @retval EFI_SUCCESS on success. - @retval EFI_UNSUPPORTED not required. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_FWRT_GET_EXEC_AREA) ( - OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - OUT UINTN *Pages - ); - -/** - Firmware runtime protocol instance. - Check for revision to ensure binary compatibility. -**/ -typedef struct { - UINTN Revision; - OC_FWRT_GET_CURRENT_CONFIG GetCurrent; - OC_FWRT_SET_MAIN_CONFIG SetMain; - OC_FWRT_SET_OVERRIDE_CONFIG SetOverride; - OC_FWRT_ON_GET_VARIABLE OnGetVariable; - OC_FWRT_GET_EXEC_AREA GetExecArea; -} OC_FIRMWARE_RUNTIME_PROTOCOL; - -/** - Firmware runtime protocol GUID. -**/ -extern EFI_GUID gOcFirmwareRuntimeProtocolGuid; - -#endif // OC_FIRMWARE_RUNTIME_PROTOCOL_H diff --git a/Include/Protocol/OcLog.h b/Include/Protocol/OcLog.h deleted file mode 100755 index 0a0897433..000000000 --- a/Include/Protocol/OcLog.h +++ /dev/null @@ -1,136 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_LOG_PROTOCOL_H -#define OC_LOG_PROTOCOL_H - -#include -#include - -/// -/// Current supported log protocol revision. -/// -#define OC_LOG_REVISION 0x01000A - -/// -/// The defines for the log flags. -/// -#define OC_LOG_ENABLE BIT0 -#define OC_LOG_CONSOLE BIT1 -#define OC_LOG_DATA_HUB BIT2 -#define OC_LOG_SERIAL BIT3 -#define OC_LOG_VARIABLE BIT4 -#define OC_LOG_NONVOLATILE BIT5 -#define OC_LOG_FILE BIT6 - -typedef UINT32 OC_LOG_OPTIONS; - -/** - The GUID of the OC_LOG_PROTOCOL. -**/ -#define OC_LOG_PROTOCOL_GUID \ - { 0xDBB6008F, 0x89E4, 0x4272, \ - { 0x98, 0x81, 0xCE, 0x3A, 0xFD, 0x97, 0x24, 0xD0 } } - -/** - The forward declaration for the protocol for the OC_LOG_PROTOCOL. -**/ -typedef struct OC_LOG_PROTOCOL_ OC_LOG_PROTOCOL; - -/** - Add an entry to the log buffer - - @param[in] This This protocol. - @param[in] ErrorLevel Debug level. - @param[in] FormatString String containing the output format. - @param[in] Marker Address of the VA_ARGS marker. - - @retval EFI_SUCCESS The entry was successfully added. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_LOG_ADD_ENTRY) ( - IN OC_LOG_PROTOCOL *This, - IN UINTN ErrorLevel, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ); - -/** - Reset the internal timers - - @param[in] This This protocol. - - @retval EFI_SUCCESS The timers were reset successfully. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_LOG_RESET_TIMERS) ( - IN OC_LOG_PROTOCOL *This - ); - -/** - Retrieve pointer to the log buffer - - @param[in] This This protocol. - @param[in] OcLogBuffer Address to store the buffer pointer. - - @retval EFI_SUCCESS The timers were reset successfully. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_LOG_GET_LOG) ( - IN OC_LOG_PROTOCOL *This, - OUT CHAR8 **OcLogBuffer - ); - -/** - Save the current log - - @param[in] This This protocol. - @param[in] NonVolatile Variable. - @param[in] FilePath Filepath to save the log. OPTIONAL - - @retval EFI_SUCCESS The log was saved successfully. -**/ -typedef -EFI_STATUS -(EFIAPI *OC_LOG_SAVE_LOG) ( - IN OC_LOG_PROTOCOL *This, - IN UINT32 NonVolatile OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ); - -/** - The structure exposed by the OC_LOG_PROTOCOL. -**/ -struct OC_LOG_PROTOCOL_ { - UINT32 Revision; ///< The revision of the installed protocol. - UINTN Reserved; ///< Reserved for future extension. - OC_LOG_ADD_ENTRY AddEntry; ///< A pointer to the AddEntry function. - OC_LOG_GET_LOG GetLog; ///< A pointer to the GetLog function. - OC_LOG_SAVE_LOG SaveLog; ///< A pointer to the SaveLog function. - OC_LOG_RESET_TIMERS ResetTimers; ///< A pointer to the ResetTimers function. - OC_LOG_OPTIONS Options; ///< The current options of the installed protocol. - UINT32 DisplayDelay; ///< The delay after visible onscreen message in microseconds. - UINTN DisplayLevel; ///< The error level visible onscreen. - UINTN HaltLevel; ///< The error level causing CPU dead loop. - EFI_FILE_PROTOCOL *FileSystem; ///< Log file system root, not owned. - CHAR16 *FilePath; ///< Log file path. -}; - -/// A global variable storing the GUID of the OC_LOG_PROTOCOL. -extern EFI_GUID gOcLogProtocolGuid; - -#endif // OC_LOG_PROTOCOL_H diff --git a/Include/Protocol/OcQuirksProtocol.h b/Include/Protocol/OcQuirksProtocol4Clover.h similarity index 92% rename from Include/Protocol/OcQuirksProtocol.h rename to Include/Protocol/OcQuirksProtocol4Clover.h index c2c8d6eb0..80405c053 100644 --- a/Include/Protocol/OcQuirksProtocol.h +++ b/Include/Protocol/OcQuirksProtocol4Clover.h @@ -6,11 +6,14 @@ // Copyright © 2020 Slice. All rights reserved. // -#ifndef OcQuirksProtocol_h -#define OcQuirksProtocol_h +#ifndef OcQuirksProtocol4Clover_h +#define OcQuirksProtocol4Clover_h +extern "C" { #include -#include +#include +} + #define OCQUIRKS_PROTOCOL_REVISION 23 /* @@ -62,7 +65,7 @@ typedef EFI_STATUS (EFIAPI *OCQUIRKS_GET_CONFIG) ( IN OCQUIRKS_PROTOCOL *This, - OUT OC_ABC_SETTINGS *Buffer, + OUT OC_ABC_SETTINGS_4CLOVER *Buffer, OUT BOOLEAN *GopEnable ); diff --git a/LegacyBios/KeyboardDxe/BiosKeyboard.c b/LegacyBios/KeyboardDxe/BiosKeyboard.c index 3ed910f32..dde72dfa3 100644 --- a/LegacyBios/KeyboardDxe/BiosKeyboard.c +++ b/LegacyBios/KeyboardDxe/BiosKeyboard.c @@ -1737,7 +1737,7 @@ BiosKeyboardTimerHandler ( BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; //for AppleDb //UINTN NumberOfKeys; - //APPLE_KEY Keys[8]; + //APPLE_KEY_CODE Keys[8]; BiosKeyboardPrivate = Context; diff --git a/Library/DeviceTreeLib/DeviceTreeLib.c b/Library/DeviceTreeLib/DeviceTreeLib.c deleted file mode 100755 index a60c9e747..000000000 --- a/Library/DeviceTreeLib/DeviceTreeLib.c +++ /dev/null @@ -1,715 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Obtain next property by address. -// -#define DEVICE_TREE_GET_NEXT_PROPERTY(Prop) \ - (DTProperty *)(((UINT8 *)(UINTN)(Prop)) \ - + sizeof (*Prop) + ALIGN_VALUE (Prop->Length, sizeof (UINT32))) - -// -// Location of the Device Tree. -// -STATIC DTEntry mDTRootNode; - -// -// Pointer to location that contains the length of the Device Tree. -// -STATIC UINT32 *mDTLength; - -STATIC UINT32 mDTNodeDepth; - -STATIC OpaqueDTPropertyIterator mOpaquePropIter; - -// -// Support Routines. -// - -STATIC -DTEntry -DTSkipProperties ( - IN DTEntry Entry - ) -{ - DTProperty *Prop; - UINT32 Count; - - if (Entry == NULL || Entry->NumProperties == 0) { - return NULL; - } else { - Prop = (DTProperty *) (Entry + 1); - for (Count = 0; Count < Entry->NumProperties; ++Count) { - Prop = DEVICE_TREE_GET_NEXT_PROPERTY (Prop); - } - } - - return (DTEntry) Prop; -} - -STATIC -DTEntry -DTSkipTree ( - IN DTEntry Root - ) -{ - DTEntry Entry; - UINT32 Count; - - Entry = DTSkipProperties (Root); - - if (Entry == NULL) { - return NULL; - } - - for (Count = 0; Count < Root->NumChildren; ++Count) { - Entry = DTSkipTree (Entry); - } - return Entry; -} - -STATIC -DTEntry -GetFirstChild ( - IN DTEntry Parent - ) -{ - return DTSkipProperties (Parent); -} - -STATIC -DTEntry -GetNextChild ( - IN DTEntry Sibling - ) -{ - return DTSkipTree (Sibling); -} - -STATIC -CONST CHAR8 * -GetNextComponent ( - IN CONST CHAR8 *Cp, - IN CHAR8 *Bp - ) -{ - while (*Cp != 0) { - if (*Cp == DT_PATH_NAME_SEPARATOR) { - Cp++; - break; - } - *Bp++ = *Cp++; - } - - *Bp = 0; - return Cp; -} - -STATIC -DTEntry -FindChild ( - IN DTEntry Cur, - IN CHAR8 *Buf - ) -{ - DTEntry Child; - UINTN Index; - CHAR8 *Str; - UINT32 Dummy; - - if (Cur->NumChildren == 0) { - return NULL; - } - - Index = 1; - Child = GetFirstChild (Cur); - while (1) { - if (EFI_ERROR(DTGetProperty(Child, "name", (VOID **)&Str, &Dummy))) { - break; - } - - if (AsciiStrCmp(Str, Buf) == 0) { - return Child; - } - - if (Index >= Cur->NumChildren) { - break; - } - - Child = GetNextChild (Child); - ++Index; - } - - return NULL; -} - -// -// External Routines. -// - -EFI_STATUS -DTLookupEntry ( - IN CONST DTEntry SearchPoint, - IN CONST CHAR8 *PathName, - IN DTEntry *FoundEntry - ) -{ - DTEntryNameBuf Buf; - DTEntry Cur; - CONST CHAR8 *Cp; - - if (mDTRootNode == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (SearchPoint == NULL) { - Cur = mDTRootNode; - } else { - Cur = SearchPoint; - } - - Cp = PathName; - if (*Cp == DT_PATH_NAME_SEPARATOR) { - Cp++; - if (*Cp == '\0') { - *FoundEntry = Cur; - return EFI_SUCCESS; - } - } - - do { - Cp = GetNextComponent (Cp, Buf); - - // - // Check for done. - // - if (*Buf == '\0') { - if (*Cp == '\0') { - *FoundEntry = Cur; - return EFI_SUCCESS; - } - break; - } - - Cur = FindChild (Cur, Buf); - } while (Cur != NULL); - - return EFI_INVALID_PARAMETER; -} - -EFI_STATUS -DTCreateEntryIterator ( - IN CONST DTEntry StartEntry, - IN DTEntryIterator *Iterator - ) -{ - DTEntryIterator Iter; - - if (mDTRootNode == NULL) { - return EFI_INVALID_PARAMETER; - } - - Iter = AllocatePool (sizeof (OpaqueDTEntryIterator)); - - if (Iter == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (StartEntry != NULL) { - Iter->OuterScope = (DTEntry) StartEntry; - Iter->CurrentScope = (DTEntry) StartEntry; - } else { - Iter->OuterScope = mDTRootNode; - Iter->CurrentScope = mDTRootNode; - } - - Iter->CurrentEntry = NULL; - Iter->SavedScope = NULL; - Iter->CurrentIndex = 0; - - *Iterator = Iter; - return EFI_SUCCESS; -} - -EFI_STATUS -DTDisposeEntryIterator ( - IN DTEntryIterator Iterator - ) -{ - DTSavedScopePtr Scope; - - while ((Scope = Iterator->SavedScope) != NULL) { - Iterator->SavedScope = Scope->NextScope; - FreePool(Scope); - } - - FreePool(Iterator); - return EFI_SUCCESS; -} - -EFI_STATUS -DTEnterEntry ( - IN DTEntryIterator Iterator, - IN DTEntry ChildEntry - ) -{ - DTSavedScopePtr NewScope; - - if (ChildEntry == NULL) { - return EFI_INVALID_PARAMETER; - } - - NewScope = AllocatePool (sizeof (DTSavedScope)); - - if (NewScope == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - NewScope->NextScope = Iterator->SavedScope; - NewScope->Scope = Iterator->CurrentScope; - NewScope->Entry = Iterator->CurrentEntry; - NewScope->Index = Iterator->CurrentIndex; - - Iterator->CurrentScope = ChildEntry; - Iterator->CurrentEntry = NULL; - Iterator->SavedScope = NewScope; - Iterator->CurrentIndex = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -DTExitEntry ( - IN DTEntryIterator Iterator, - IN DTEntry *CurrentPosition - ) -{ - DTSavedScopePtr NewScope; - - NewScope = Iterator->SavedScope; - - if (NewScope == NULL) { - return EFI_INVALID_PARAMETER; - } - - Iterator->SavedScope = NewScope->NextScope; - Iterator->CurrentScope = NewScope->Scope; - Iterator->CurrentEntry = NewScope->Entry; - Iterator->CurrentIndex = NewScope->Index; - - *CurrentPosition = Iterator->CurrentEntry; - - FreePool(NewScope); - - return EFI_SUCCESS; -} - -EFI_STATUS -DTIterateEntries ( - IN DTEntryIterator Iterator, - IN DTEntry *NextEntry - ) -{ - if (Iterator->CurrentIndex >= Iterator->CurrentScope->NumChildren) { - *NextEntry = NULL; - return EFI_END_OF_MEDIA; - } - - ++Iterator->CurrentIndex; - if (Iterator->CurrentIndex == 1) { - Iterator->CurrentEntry = GetFirstChild (Iterator->CurrentScope); - } else { - Iterator->CurrentEntry = GetNextChild (Iterator->CurrentEntry); - } - *NextEntry = Iterator->CurrentEntry; - return EFI_SUCCESS; -} - -EFI_STATUS -DTRestartEntryIteration ( - IN DTEntryIterator Iterator - ) -{ - Iterator->CurrentEntry = NULL; - Iterator->CurrentIndex = 0; - return EFI_SUCCESS; -} - -EFI_STATUS -DTGetProperty( - IN CONST DTEntry Entry, - IN CHAR8 *PropertyName, - IN VOID **PropertyValue, - IN UINT32 *PropertySize - ) -{ - DTProperty *Prop; - UINT32 Count; - - if (Entry == NULL || Entry->NumProperties == 0) { - return EFI_INVALID_PARAMETER; - } - - Prop = (DTProperty *) (Entry + 1); - for (Count = 0; Count < Entry->NumProperties; Count++) { - if (AsciiStrCmp(Prop->Name, PropertyName) == 0) { - *PropertyValue = (VOID *) (((UINT8 *)Prop) + sizeof (DTProperty)); - *PropertySize = Prop->Length; - return EFI_SUCCESS; - } - Prop = DEVICE_TREE_GET_NEXT_PROPERTY (Prop); - } - - return EFI_INVALID_PARAMETER; -} - -EFI_STATUS -DTCreatePropertyIterator ( - IN CONST DTEntry Entry, - IN DTPropertyIterator Iterator - ) -{ - Iterator->Entry = Entry; - Iterator->CurrentProperty = NULL; - Iterator->CurrentIndex = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -DTIterateProperties ( - IN DTPropertyIterator Iterator, - IN CHAR8 **FoundProperty - ) -{ - if (Iterator->CurrentIndex >= Iterator->Entry->NumProperties) { - *FoundProperty = NULL; - return EFI_END_OF_MEDIA; - } - - Iterator->CurrentIndex++; - if (Iterator->CurrentIndex == 1) { - Iterator->CurrentProperty = (DTProperty *) (Iterator->Entry + 1); - } else { - Iterator->CurrentProperty = DEVICE_TREE_GET_NEXT_PROPERTY (Iterator->CurrentProperty); - } - *FoundProperty = Iterator->CurrentProperty->Name; - - return EFI_SUCCESS; -} - -EFI_STATUS -DTRestartPropertyIteration ( - IN DTPropertyIterator Iterator - ) -{ - Iterator->CurrentProperty = NULL; - Iterator->CurrentIndex = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -DumpDeviceTreeNodeRecusively ( - IN DTEntry Entry - ) -{ - EFI_STATUS Status; - DTEntry Root; - UINTN Spacer; - - DTEntryIterator EntryIterator; - DTPropertyIterator PropIter; - DTMemMapEntry *MemMap; - DTBooterKextFileInfo *Kext; - UINT8 *Address; - - CHAR8 *PropertyParent = NULL; - CHAR8 *PropertyName = NULL; - CHAR8 *PropertyValue = NULL; - - UINT32 PropertySize = 0; - - PropIter = &mOpaquePropIter; - - if (Entry == NULL) { - return EFI_INVALID_PARAMETER; - } - - Root = Entry; - Spacer = 1; - - Status = DTCreatePropertyIterator (Entry, PropIter); - - if (!EFI_ERROR(Status)) { - PropertyParent = "/"; - - while (!EFI_ERROR(DTIterateProperties (PropIter, &PropertyName))) { - if ((Status = DTGetProperty(Entry, (CHAR8 *)PropertyName, (void *)&PropertyValue, &PropertySize)) != EFI_SUCCESS) { - DEBUG ((DEBUG_WARN, "DeviceTree is probably invalid - %r\n", Status)); - break; - } - - if (AsciiStrnCmp(PropertyName, "name", 4) == 0) { - DEBUG ((DEBUG_INFO, "+%*ao %a\n", mDTNodeDepth * Spacer, "-", PropertyValue, mDTNodeDepth)); - DEBUG ((DEBUG_INFO, "|%*a\n", mDTNodeDepth * Spacer, " {" , mDTNodeDepth)); - PropertyParent = PropertyValue; - mDTNodeDepth++; - } else if (AsciiStrnCmp(PropertyName, "guid", 4) == 0) { - // - // Show Guid. - // - DEBUG ((DEBUG_INFO, "|%*a \"%a\" = < %g >\n", mDTNodeDepth * Spacer, " ", PropertyName, PropertyValue, PropertySize)); - } else if (AsciiStrnCmp(PropertyParent, "memory-map", 10) == 0) { - MemMap = (DTMemMapEntry *)PropertyValue; - - if (AsciiStrnCmp(PropertyName, "Driver-", 7) == 0) { - Kext = (DTBooterKextFileInfo *)(UINTN)MemMap->Address; - - if (Kext != NULL && Kext->ExecutablePhysAddr != 0) { - DEBUG (( - DEBUG_INFO, - "|%*a \"%a\" = < Dict 0x%0X Binary 0x%0X \"%a\" >\n", mDTNodeDepth * Spacer, " ", - PropertyName, - Kext->InfoDictPhysAddr, - Kext->ExecutablePhysAddr, - Kext->BundlePathPhysAddr - )); - } - } else { - Address = (UINT8 *)(UINTN)MemMap->Address; - if (Address != NULL) { - DEBUG ((DEBUG_INFO, "|%*a \"%a\" = < 0x%0X %02X %02X %02X %02X Length %X >\n", mDTNodeDepth * Spacer, " ", - PropertyName, - MemMap->Address, - Address[0], Address[1], Address[2], Address[3], - MemMap->Length - )); - } - } - - } else { - // - // TODO: Print data here. - // - DEBUG ((DEBUG_INFO, "|%*a \"%a\" = < ... > (%d)\n", mDTNodeDepth * Spacer, " ", - PropertyName, - PropertySize)); - } - } - - DEBUG ((DEBUG_INFO, "|%*a\n", (mDTNodeDepth - 1 ) * Spacer, " }" , mDTNodeDepth)); - } - - Status = DTCreateEntryIterator (Root, &EntryIterator); - - if (!EFI_ERROR(Status)) { - while (!EFI_ERROR(DTIterateEntries (EntryIterator, &Root))) { - DumpDeviceTreeNodeRecusively (Root); - mDTNodeDepth--; - } - } - - return !EFI_ERROR(Status) ? EFI_SUCCESS : EFI_NOT_FOUND; -} - -VOID -DumpDeviceTree ( - VOID - ) -{ - DTEntry DTRoot = NULL; - - if (!EFI_ERROR(DTLookupEntry (NULL, "/", &DTRoot))) { - DumpDeviceTreeNodeRecusively (DTRoot); - } -} - -// DTInit -/// -/// -/// @param[in] Base Pointer to the Device Tree -/// @param[in] Length Pointer to location containing the Device Tree length -/// - -VOID -DTInit ( - IN VOID *Base, - IN UINT32 *Length - ) -{ - if (Base != NULL && Length != NULL) { - mDTRootNode = (DTEntry) Base; - mDTLength = Length; - } -} - -// DTDeleteProperty -/// -/// -/// @param[in] NodeName -/// @param[in] DeletePropertyName -/// - -UINT32 -DTDeleteProperty ( - IN CHAR8 *NodeName, - IN CHAR8 *DeletePropertyName - ) -{ - DTEntry Node; - DTPropertyIterator PropIter; - DTProperty *Property; - CHAR8 *DeletePosition; - CHAR8 *DeviceTreeEnd; - UINT32 DeleteLength; - - PropIter = &mOpaquePropIter; - DeletePosition = NULL; - DeviceTreeEnd = (CHAR8 *) mDTRootNode + *mDTLength; - DeleteLength = 0; - - if (!EFI_ERROR(DTLookupEntry (NULL, NodeName, &Node))) { - if (!EFI_ERROR(DTCreatePropertyIterator (Node, PropIter))) { - while (!EFI_ERROR(DTIterateProperties (PropIter, &DeletePosition))) { - if (AsciiStrStr (DeletePosition, DeletePropertyName) != NULL) { - Property = (DTProperty *)DeletePosition; - DeleteLength = sizeof (DTProperty) + ALIGN_VALUE (Property->Length, sizeof (UINT32)); - - // - // Adjust Device Tree Length. - // - if (mDTLength != NULL) { - *mDTLength -= DeleteLength; - } - - // - // Delete Property. - // - CopyMem(DeletePosition, DeletePosition + DeleteLength, DeviceTreeEnd - DeletePosition); - ZeroMem (DeviceTreeEnd - DeleteLength, DeleteLength); - - // - // Decrement Nodes Properties Count. - // - Node->NumProperties--; - - break; - } - } - } - } - - return DeleteLength; -} - -// DTInsertProperty -/// -/// -/// @param[in] NodeName -/// @param[in] InsertPropertyName -/// @param[in] AddPropertyName -/// @param[in] AddPropertyValue -/// @param[in] ValueLength -/// @param[in] InsertAfter -/// - -VOID -DTInsertProperty ( - IN CHAR8 *NodeName, - IN CHAR8 *InsertPropertyName, - IN CHAR8 *AddPropertyName, - IN VOID *AddPropertyValue, - IN UINT32 ValueLength, - IN BOOLEAN InsertAfter - ) -{ - DTEntry Node; - DTPropertyIterator PropIter; - DTProperty *Property; - UINT32 EntryLength; - CHAR8 *DeviceTree; - CHAR8 *DeviceTreeEnd; - CHAR8 *InsertPosition; - - PropIter = &mOpaquePropIter; - EntryLength = ALIGN_VALUE (ValueLength, sizeof (UINT32)); - DeviceTree = NULL; - DeviceTreeEnd = (CHAR8 *)mDTRootNode + *mDTLength; - InsertPosition = NULL; - - if (!EFI_ERROR(DTLookupEntry (NULL, NodeName, &Node))) { - if (!EFI_ERROR(DTCreatePropertyIterator (Node, PropIter))) { - while (!EFI_ERROR(DTIterateProperties (PropIter, &DeviceTree))) { - InsertPosition = DeviceTree; - if (AsciiStrStr (InsertPosition, InsertPropertyName) != NULL) { - break; - } - } - - if (InsertAfter) { - Property = (DTProperty *) InsertPosition; - InsertPosition += sizeof (DTProperty) + ALIGN_VALUE (Property->Length, sizeof (UINT32)); - } - - Property = (DTProperty *)InsertPosition; - - // - // Make space. - // - CopyMem(InsertPosition + sizeof (DTProperty) + EntryLength, InsertPosition, DeviceTreeEnd - InsertPosition); - ZeroMem (InsertPosition, sizeof (DTProperty) + EntryLength); - - // - // Insert Property Name. - // - CopyMem(Property->Name, AddPropertyName, AsciiStrLen(AddPropertyName)); - - // - // Insert Property Value Length. - // - Property->Length = ValueLength; - - // - // Insert Property Value. - // - CopyMem(InsertPosition + sizeof (DTProperty), AddPropertyValue, ValueLength); - - // - // Increment Nodes Properties Count. - // - Node->NumProperties++; - - // - // Adjust Length. - // - if (mDTLength != NULL) { - *mDTLength += sizeof (DTProperty) + EntryLength; - } - } - } -} diff --git a/Library/DeviceTreeLib/DeviceTreeLib.inf b/Library/DeviceTreeLib/DeviceTreeLib.inf deleted file mode 100755 index e59471736..000000000 --- a/Library/DeviceTreeLib/DeviceTreeLib.inf +++ /dev/null @@ -1,44 +0,0 @@ -## @file -# -# Component description file for OcDeviceTreeLib. -# -# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DeviceTreeLib - FILE_GUID = 1B5DD808-FBE6-4792-B285-7520A27AD8AB - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = DeviceTreeLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - DeviceTreeLib.c - -[Packages] - MdePkg/MdePkg.dec - CloverPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryAllocationLib diff --git a/Library/MachoLib/CxxSymbols.c b/Library/MachoLib/CxxSymbols.c deleted file mode 100644 index f180376ac..000000000 --- a/Library/MachoLib/CxxSymbols.c +++ /dev/null @@ -1,620 +0,0 @@ -/** @file - Provides services for C++ symbols. - -Copyright (c) 2018, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#define CXX_PREFIX "__Z" -#define VTABLE_PREFIX CXX_PREFIX "TV" -#define OSOBJ_PREFIX CXX_PREFIX "N" -#define RESERVED_TOKEN "_RESERVED" -#define METACLASS_TOKEN "10gMetaClassE" -#define SMCP_TOKEN "10superClassE" -#define METACLASS_VTABLE_PREFIX VTABLE_PREFIX "N" -#define METACLASS_VTABLE_SUFFIX "9MetaClassE" -#define CXX_PURE_VIRTUAL "___cxa_pure_virtual" -#define FINAL_CLASS_TOKEN "14__OSFinalClassEv" - -#define VTABLE_ENTRY_SIZE_64 8U -#define VTABLE_HEADER_LEN_64 2U -#define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64) - -#define SYM_MAX_NAME_LEN 256U - -/** - Returns whether Name is pure virtual. - - @param[in] Name The name to evaluate. - -**/ -BOOLEAN -MachoSymbolNameIsPureVirtual ( - IN CONST CHAR8 *Name - ) -{ - ASSERT (Name != NULL); - return (AsciiStrCmp(Name, CXX_PURE_VIRTUAL) == 0); -} - -/** - Returns whether Name is a Padslot. - - @param[in] Name The name to evaluate. - -**/ -BOOLEAN -MachoSymbolNameIsPadslot ( - IN CONST CHAR8 *Name - ) -{ - ASSERT (Name != NULL); - return (AsciiStrStr (Name, RESERVED_TOKEN) != NULL); -} - -/** - Returns whether SymbolName defines a Super Metaclass Pointer. - - @param[in,out] Context Context of the Mach-O. - @param[in] SymbolName The symbol name to check. - -**/ -BOOLEAN -MachoSymbolNameIsSmcp64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SymbolName - ) -{ - CONST CHAR8 *Suffix; - - ASSERT (Context != NULL); - ASSERT (SymbolName != NULL); - // - // Verify the symbol has... - // 1) The C++ prefix. - // 2) The SMCP suffix. - // 3) At least one character between the prefix and the suffix. - // - Suffix = AsciiStrStr (SymbolName, SMCP_TOKEN); - - if ((Suffix == NULL) - || (AsciiStrnCmp (SymbolName, OSOBJ_PREFIX, L_STR_LEN (OSOBJ_PREFIX)) != 0) - || ((UINTN)(Suffix - SymbolName) <= L_STR_LEN (OSOBJ_PREFIX))) { - return FALSE; - } - - return TRUE; -} - -/** - Returns whether SymbolName defines a Super Metaclass Pointer. - - @param[in,out] Context Context of the Mach-O. - @param[in] SymbolName The symbol name to check. - -**/ -BOOLEAN -MachoSymbolNameIsMetaclassPointer64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SymbolName - ) -{ - CONST CHAR8 *Suffix; - - ASSERT (Context != NULL); - ASSERT (SymbolName != NULL); - // - // Verify the symbol has... - // 1) The C++ prefix. - // 2) The MetaClass suffix. - // 3) At least one character between the prefix and the suffix. - // - Suffix = AsciiStrStr (SymbolName, METACLASS_TOKEN); - - if ((Suffix == NULL) - || (AsciiStrnCmp (SymbolName, OSOBJ_PREFIX, L_STR_LEN (OSOBJ_PREFIX)) != 0) - || ((UINTN)(Suffix - SymbolName) <= L_STR_LEN (OSOBJ_PREFIX))) { - return FALSE; - } - - return TRUE; -} - -/** - Retrieves the class name of a Super Meta Class Pointer. - - @param[in,out] Context Context of the Mach-O. - @param[in] SmcpName SMCP Symbol name to get the class name of. - @param[in] ClassNameSize The size of ClassName. - @param[out] ClassName The output buffer for the class name. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetClassNameFromSuperMetaClassPointer ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SmcpName, - IN UINTN ClassNameSize, - OUT CHAR8 *ClassName - ) -{ - UINTN PrefixSize; - UINTN SuffixSize; - UINTN OutputSize; - - ASSERT (Context != NULL); - ASSERT (SmcpName != NULL); - ASSERT (ClassNameSize > 0); - ASSERT (ClassName != NULL); - - ASSERT (Context->StringTable != NULL); - - ASSERT (MachoSymbolNameIsSmcp64 (Context, SmcpName)); - - PrefixSize = L_STR_LEN (OSOBJ_PREFIX); - SuffixSize = L_STR_LEN (SMCP_TOKEN); - - OutputSize = (AsciiStrLen(SmcpName) - PrefixSize - SuffixSize); - - if ((OutputSize + 1) > ClassNameSize) { - return FALSE; - } - - CopyMem(ClassName, &SmcpName[PrefixSize], OutputSize); - ClassName[OutputSize] = '\0'; - - return TRUE; -} - -/** - Retrieves the class name of a VTable. - - @param[out] VtableName The VTable's name. - -**/ -CONST CHAR8 * -MachoGetClassNameFromVtableName ( - IN CONST CHAR8 *VtableName - ) -{ - ASSERT (VtableName != NULL); - ASSERT (MachoSymbolNameIsVtable64 (VtableName)); - // - // As there is no suffix, just return a pointer from within VtableName. - // - return &VtableName[L_STR_LEN (VTABLE_PREFIX)]; -} - -/** - Retrieves the function prefix of a class name. - - @param[in] ClassName The class name to evaluate. - @param[in] FunctionPrefixSize The size of FunctionPrefix. - @param[out] FunctionPrefix The output buffer for the function prefix. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetFunctionPrefixFromClassName ( - IN CONST CHAR8 *ClassName, - IN UINTN FunctionPrefixSize, - OUT CHAR8 *FunctionPrefix - ) -{ - UINTN Index; - UINTN BodySize; - BOOLEAN Result; - UINTN TotalSize; - - ASSERT (ClassName != NULL); - ASSERT (FunctionPrefixSize > 0); - ASSERT (FunctionPrefix != NULL); - - BodySize = AsciiStrSize (ClassName); - Result = OcOverflowAddUN (L_STR_LEN (OSOBJ_PREFIX), BodySize, &TotalSize); - if (Result || (FunctionPrefixSize < TotalSize)) { - return FALSE; - } - - Index = 0; - CopyMem( - &FunctionPrefix[Index], - OSOBJ_PREFIX, - L_STR_LEN (OSOBJ_PREFIX) - ); - - Index += L_STR_LEN (OSOBJ_PREFIX); - CopyMem( - &FunctionPrefix[Index], - ClassName, - BodySize - ); - - return TRUE; -} - -/** - Retrieves the class name of a Meta Class Pointer. - - @param[in,out] Context Context of the Mach-O. - @param[in] MetaClassName MCP Symbol name to get the class name of. - @param[in] ClassNameSize The size of ClassName. - @param[out] ClassName The output buffer for the class name. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetClassNameFromMetaClassPointer ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *MetaClassName, - IN UINTN ClassNameSize, - OUT CHAR8 *ClassName - ) -{ - UINTN PrefixSize; - UINTN SuffixSize; - UINTN ClassNameLength; - - ASSERT (Context != NULL); - ASSERT (MetaClassName != NULL); - ASSERT (ClassNameSize > 0); - ASSERT (ClassName != NULL); - - ASSERT (Context->StringTable != NULL); - - ASSERT (MachoSymbolNameIsMetaclassPointer64 (Context, MetaClassName)); - - PrefixSize = L_STR_LEN (OSOBJ_PREFIX); - SuffixSize = L_STR_LEN (METACLASS_TOKEN); - - ClassNameLength = (AsciiStrLen(MetaClassName) - PrefixSize - SuffixSize); - if ((ClassNameLength + 1) > ClassNameSize) { - return FALSE; - } - - CopyMem(ClassName, &MetaClassName[PrefixSize], ClassNameLength); - ClassName[ClassNameLength] = '\0'; - - return TRUE; -} - -/** - Retrieves the VTable name of a class name. - - @param[in] ClassName Class name to get the VTable name of. - @param[in] VtableNameSize The size of VtableName. - @param[out] VtableName The output buffer for the VTable name. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetVtableNameFromClassName ( - IN CONST CHAR8 *ClassName, - IN UINTN VtableNameSize, - OUT CHAR8 *VtableName - ) -{ - UINTN Index; - UINTN BodySize; - BOOLEAN Result; - UINTN TotalSize; - - ASSERT (ClassName != NULL); - ASSERT (VtableNameSize > 0); - ASSERT (VtableName != NULL); - - BodySize = AsciiStrSize (ClassName); - - Result = OcOverflowAddUN ( - L_STR_LEN (VTABLE_PREFIX), - BodySize, - &TotalSize - ); - if (Result || (VtableNameSize < TotalSize)) { - return FALSE; - } - - Index = 0; - CopyMem( - &VtableName[Index], - VTABLE_PREFIX, - L_STR_LEN (VTABLE_PREFIX) - ); - - Index += L_STR_LEN (VTABLE_PREFIX); - CopyMem(&VtableName[Index], ClassName, BodySize); - - return TRUE; -} - -/** - Retrieves the Meta VTable name of a class name. - - @param[in] ClassName Class name to get the Meta VTable name of. - @param[in] VtableNameSize The size of VtableName. - @param[out] VtableName The output buffer for the VTable name. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetMetaVtableNameFromClassName ( - IN CONST CHAR8 *ClassName, - IN UINTN VtableNameSize, - OUT CHAR8 *VtableName - ) -{ - UINTN BodyLength; - BOOLEAN Result; - UINTN TotalSize; - UINTN Index; - - ASSERT (ClassName != NULL); - ASSERT (VtableNameSize > 0); - ASSERT (VtableName != NULL); - - BodyLength = AsciiStrLen(ClassName); - - Result = OcOverflowTriAddUN ( - L_STR_LEN (METACLASS_VTABLE_PREFIX), - BodyLength, - L_STR_SIZE (METACLASS_VTABLE_SUFFIX), - &TotalSize - ); - if (Result || (VtableNameSize < TotalSize)) { - return FALSE; - } - - Index = 0; - CopyMem( - &VtableName[Index], - METACLASS_VTABLE_PREFIX, - L_STR_LEN (METACLASS_VTABLE_PREFIX) - ); - - Index += L_STR_LEN (METACLASS_VTABLE_PREFIX); - CopyMem(&VtableName[Index], ClassName, BodyLength); - - Index += BodyLength; - CopyMem( - &VtableName[Index], - METACLASS_VTABLE_SUFFIX, - L_STR_SIZE (METACLASS_VTABLE_SUFFIX) - ); - - return TRUE; -} - -/** - Retrieves the final symbol name of a class name. - - @param[in] ClassName Class name to get the final symbol name of. - @param[in] FinalSymbolNameSize The size of FinalSymbolName. - @param[out] FinalSymbolName The output buffer for the final symbol name. - - @returns Whether the name has been retrieved successfully. - -**/ -BOOLEAN -MachoGetFinalSymbolNameFromClassName ( - IN CONST CHAR8 *ClassName, - IN UINTN FinalSymbolNameSize, - OUT CHAR8 *FinalSymbolName - ) -{ - UINTN BodyLength; - BOOLEAN Result; - UINTN TotalSize; - UINTN Index; - - ASSERT (ClassName != NULL); - ASSERT (FinalSymbolNameSize > 0); - ASSERT (FinalSymbolName != NULL); - - BodyLength = AsciiStrLen(ClassName); - - Result = OcOverflowTriAddUN ( - L_STR_LEN (OSOBJ_PREFIX), - BodyLength, - L_STR_SIZE (FINAL_CLASS_TOKEN), - &TotalSize - ); - if (Result || (FinalSymbolNameSize < TotalSize)) { - return FALSE; - } - - Index = 0; - CopyMem( - &FinalSymbolName[Index], - OSOBJ_PREFIX, - L_STR_LEN (OSOBJ_PREFIX) - ); - - Index += L_STR_LEN (OSOBJ_PREFIX); - CopyMem( - &FinalSymbolName[Index], - ClassName, - BodyLength - ); - - Index += BodyLength; - CopyMem( - &FinalSymbolName[Index], - FINAL_CLASS_TOKEN, - L_STR_SIZE (FINAL_CLASS_TOKEN) - ); - - return TRUE; -} - -/** - Returns whether SymbolName defines a VTable. - - @param[in,out] Context Context of the Mach-O. - @param[in] SymbolName The symbol name to check. - -**/ -BOOLEAN -MachoSymbolNameIsVtable64 ( - IN CONST CHAR8 *SymbolName - ) -{ - ASSERT (SymbolName != NULL); - // - // Implicitely checks for METACLASS_VTABLE_PREFIX. - // - return AsciiStrnCmp (SymbolName, VTABLE_PREFIX, L_STR_LEN (VTABLE_PREFIX)) == 0; -} - -/** - Returns whether the symbol name describes a C++ symbol. - - @param[in] Name The name to evaluate. - -**/ -BOOLEAN -MachoSymbolNameIsCxx ( - IN CONST CHAR8 *Name - ) -{ - ASSERT (Name != NULL); - return AsciiStrnCmp (Name, CXX_PREFIX, L_STR_LEN (CXX_PREFIX)) == 0; -} - -/** - Retrieves Metaclass symbol of a SMCP. - - @param[in,out] Context Context of the Mach-O. - @param[in] Smcp The SMCP to evaluate. - - @retval NULL NULL is returned on failure. - -**/ -MACH_NLIST_64 * -MachoGetMetaclassSymbolFromSmcpSymbol64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Smcp - ) -{ - MACH_NLIST_64 *Symbol; - BOOLEAN Result; - - ASSERT (Context != NULL); - ASSERT (Smcp != NULL); - - Result = MachoGetSymbolByRelocationOffset64 ( - Context, - Smcp->Value, - &Symbol - ); - if (Result && (Symbol != NULL)) { - Result = MachoSymbolNameIsMetaclassPointer64 ( - Context, - MachoGetSymbolName64 (Context, Symbol) - ); - if (Result) { - return Symbol; - } - } - - return NULL; -} - -/** - Retrieves VTable and Meta VTable of a SMCP. - Logically matches XNU's get_vtable_syms_from_smcp. - - @param[in,out] Context Context of the Mach-O. - @param[in] SmcpName SMCP Symbol mame to retrieve the VTables from. - @param[out] Vtable Output buffer for the VTable symbol pointer. - @param[out] MetaVtable Output buffer for the Meta VTable symbol pointer. - -**/ -BOOLEAN -MachoGetVtableSymbolsFromSmcp64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SmcpName, - OUT CONST MACH_NLIST_64 **Vtable, - OUT CONST MACH_NLIST_64 **MetaVtable - ) -{ - CHAR8 ClassName[SYM_MAX_NAME_LEN]; - CHAR8 VtableName[SYM_MAX_NAME_LEN]; - CHAR8 MetaVtableName[SYM_MAX_NAME_LEN]; - BOOLEAN Result; - MACH_NLIST_64 *VtableSymbol; - MACH_NLIST_64 *MetaVtableSymbol; - - ASSERT (Context != NULL); - ASSERT (SmcpName != NULL); - ASSERT (Vtable != NULL); - ASSERT (MetaVtable != NULL); - - Result = MachoGetClassNameFromSuperMetaClassPointer ( - Context, - SmcpName, - sizeof (ClassName), - ClassName - ); - if (!Result) { - return FALSE; - } - - Result = MachoGetVtableNameFromClassName ( - ClassName, - sizeof (VtableName), - VtableName - ); - if (!Result) { - return FALSE; - } - - VtableSymbol = MachoGetLocalDefinedSymbolByName (Context, VtableName); - if (VtableSymbol == NULL) { - return FALSE; - } - - Result = MachoGetMetaVtableNameFromClassName ( - ClassName, - sizeof (MetaVtableName), - MetaVtableName - ); - if (!Result) { - return FALSE; - } - - MetaVtableSymbol = MachoGetLocalDefinedSymbolByName ( - Context, - MetaVtableName - ); - if (MetaVtableSymbol == NULL) { - return FALSE; - } - - *Vtable = VtableSymbol; - *MetaVtable = MetaVtableSymbol; - - return TRUE; -} diff --git a/Library/MachoLib/Header.c b/Library/MachoLib/Header.c deleted file mode 100644 index 5cf2795ce..000000000 --- a/Library/MachoLib/Header.c +++ /dev/null @@ -1,1694 +0,0 @@ -/** - Provides services for Mach-O headers. - -Copyright (C) 2016 - 2018, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "MachoLibInternal.h" - -/** - Returns the Mach-O Header structure. - - @param[in,out] Context Context of the Mach-O. - -**/ -MACH_HEADER_64 * -MachoGetMachHeader64 ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - ASSERT (Context != NULL); - ASSERT (Context->MachHeader != NULL); - - return Context->MachHeader; -} - -/** - Returns the Mach-O's file size. - - @param[in,out] Context Context of the Mach-O. - -**/ -UINT32 -MachoGetFileSize ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - ASSERT (Context != NULL); - ASSERT (Context->FileSize != 0); - - return Context->FileSize; -} - -/** - Returns the Mach-O's virtual address space size. - - @param[out] Context Context of the Mach-O. - -**/ -UINT32 -MachoGetVmSize64 ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - UINT64 VmSize; - MACH_SEGMENT_COMMAND_64 *Segment; - - ASSERT (Context != NULL); - ASSERT (Context->FileSize != 0); - - VmSize = 0; - - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - if (OcOverflowAddU64 (VmSize, Segment->Size, &VmSize)) { - return 0; - } - VmSize = MACHO_ALIGN (VmSize); - } - - if (VmSize > MAX_UINT32) { - return 0; - } - - return (UINT32) VmSize; -} - -/** - Moves file pointer and size to point to x86_64 slice in case - FAT Mach-O is used. - - @param[in,out] FileData Pointer to pointer of the file's data. - @param[in,out] FileSize Pointer to file size of FileData. - - @return FALSE is not valid FAT image. -**/ -STATIC -BOOLEAN -MachoFilterFatArchitecture64 ( - IN OUT UINT8 **FileData, - IN OUT UINT32 *FileSize - ) -{ - BOOLEAN SwapBytes; - MACH_FAT_HEADER *FatHeader; - UINT32 NumberOfFatArch; - UINT32 Offset; - MACH_CPU_TYPE CpuType; - UINT32 TmpSize; - UINT32 Index; - UINT32 Size; - - FatHeader = (MACH_FAT_HEADER *) *FileData; - - if (!OC_ALIGNED (FatHeader) - || *FileSize < sizeof (MACH_FAT_HEADER) - || (FatHeader->Signature != MACH_FAT_BINARY_INVERT_SIGNATURE - && FatHeader->Signature != MACH_FAT_BINARY_SIGNATURE)) - { - return FALSE; - } - - SwapBytes = FatHeader->Signature == MACH_FAT_BINARY_INVERT_SIGNATURE; - NumberOfFatArch = FatHeader->NumberOfFatArch; - if (SwapBytes) { - NumberOfFatArch = SwapBytes32 (NumberOfFatArch); - } - - if (OcOverflowMulAddU32 (NumberOfFatArch, sizeof (MACH_FAT_ARCH), sizeof (MACH_FAT_HEADER), &TmpSize) - || TmpSize > *FileSize) { - return FALSE; - } - - // - // TODO: extend the interface to support MachCpuSubtypeX8664H some day. - // - for (Index = 0; Index < NumberOfFatArch; ++Index) { - CpuType = FatHeader->FatArch[Index].CpuType; - if (SwapBytes) { - CpuType = SwapBytes32 (CpuType); - } - if (CpuType == MachCpuTypeX8664) { - Offset = FatHeader->FatArch[Index].Offset; - Size = FatHeader->FatArch[Index].Size; - if (SwapBytes) { - Offset = SwapBytes32 (Offset); - Size = SwapBytes32 (Size); - } - - if (Offset == 0 - || OcOverflowAddU32 (Offset, Size, &TmpSize) - || TmpSize > *FileSize) { - return FALSE; - } - - *FileData = *FileData + Offset; - *FileSize = Size; - - return TRUE; - } - } - - return FALSE; -} - -/** - Initializes a Mach-O Context. - - @param[out] Context Mach-O Context to initialize. - @param[in] FileData Pointer to the file's data. - @param[in] FileSize File size of FileData. - - @return Whether Context has been initialized successfully. -**/ -BOOLEAN -MachoInitializeContext ( - OUT OC_MACHO_CONTEXT *Context, - IN VOID *FileData, - IN UINT32 FileSize, - IN UINT32 ContainerOffset - ) -{ - MACH_HEADER_64 *MachHeader; - UINTN TopOfFile; - UINTN TopOfCommands; - UINT32 Index; - CONST MACH_LOAD_COMMAND *Command; - UINTN TopOfCommand; - UINT32 CommandsSize; - BOOLEAN Result; - - ASSERT (FileData != NULL); - ASSERT (FileSize > 0); - ASSERT (Context != NULL); - - MachoFilterFatArchitecture64 ((UINT8 **) &FileData, &FileSize); - - MachHeader = (MACH_HEADER_64 *) FileData; - TopOfFile = ((UINTN)MachHeader + FileSize); - - ASSERT (TopOfFile > (UINTN)MachHeader); - - if (FileSize < sizeof (*MachHeader) - || !OC_ALIGNED (MachHeader) - || MachHeader->Signature != MACH_HEADER_64_SIGNATURE) { - return FALSE; - } - - Result = OcOverflowAddUN ( - (UINTN)MachHeader->Commands, - MachHeader->CommandsSize, - &TopOfCommands - ); - if (Result || (TopOfCommands > TopOfFile)) { - return FALSE; - } - - CommandsSize = 0; - - for ( - Index = 0, Command = MachHeader->Commands; - Index < MachHeader->NumCommands; - ++Index, Command = NEXT_MACH_LOAD_COMMAND (Command) - ) { - Result = OcOverflowAddUN ( - (UINTN)Command, - sizeof (*Command), - &TopOfCommand - ); - if (Result - || (TopOfCommand > TopOfCommands) - || (Command->CommandSize < sizeof (*Command)) - || ((Command->CommandSize % sizeof (UINT64)) != 0) // Assumption: 64-bit, see below. - ) { - return FALSE; - } - - Result = OcOverflowAddU32 ( - CommandsSize, - Command->CommandSize, - &CommandsSize - ); - if (Result) { - return FALSE; - } - } - - if (MachHeader->CommandsSize != CommandsSize) { - return FALSE; - } - // - // Verify assumptions made by this library. - // Carefully audit all "Assumption:" remarks before modifying these checks. - // - if ((MachHeader->CpuType != MachCpuTypeX8664) - || ((MachHeader->FileType != MachHeaderFileTypeKextBundle) - && (MachHeader->FileType != MachHeaderFileTypeExecute) - && (MachHeader->FileType != MachHeaderFileTypeFileSet))) { - return FALSE; - } - - ZeroMem (Context, sizeof (*Context)); - - Context->MachHeader = MachHeader; - Context->FileSize = FileSize; - Context->ContainerOffset = ContainerOffset; - - return TRUE; -} - -/** - Returns the last virtual address of a Mach-O. - - @param[in,out] Context Context of the Mach-O. - - @retval 0 The binary is malformed. - -**/ -UINT64 -MachoGetLastAddress64 ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - UINT64 LastAddress; - - CONST MACH_SEGMENT_COMMAND_64 *Segment; - UINT64 Address; - - ASSERT (Context != NULL); - - LastAddress = 0; - - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - Address = (Segment->VirtualAddress + Segment->Size); - - if (Address > LastAddress) { - LastAddress = Address; - } - } - - return LastAddress; -} - -MACH_LOAD_COMMAND * -MachoGetNextCommand64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN MACH_LOAD_COMMAND_TYPE LoadCommandType, - IN CONST MACH_LOAD_COMMAND *LoadCommand OPTIONAL - ) -{ - MACH_LOAD_COMMAND *Command; - MACH_HEADER_64 *MachHeader; - UINTN TopOfCommands; - - ASSERT (Context != NULL); - - MachHeader = Context->MachHeader; - ASSERT (MachHeader != NULL); - - TopOfCommands = ((UINTN)MachHeader->Commands + MachHeader->CommandsSize); - - if (LoadCommand != NULL) { - ASSERT ( - (LoadCommand >= &MachHeader->Commands[0]) - && ((UINTN)LoadCommand <= TopOfCommands) - ); - Command = NEXT_MACH_LOAD_COMMAND (LoadCommand); - } else { - Command = &MachHeader->Commands[0]; - } - - for ( - ; - (UINTN)Command < TopOfCommands; - Command = NEXT_MACH_LOAD_COMMAND (Command) - ) { - if (Command->CommandType == LoadCommandType) { - return Command; - } - } - - return NULL; -} - -/** - Retrieves the first UUID Load Command. - - @param[in,out] Context Context of the Mach-O. - - @retval NULL NULL is returned on failure. - -**/ -MACH_UUID_COMMAND * -MachoGetUuid64 ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - MACH_UUID_COMMAND *UuidCommand; - - ASSERT (Context != NULL); - // - // Context initialisation guarantees the command size is a multiple of 8. - // -// STATIC_ASSERT ( -// OC_ALIGNOF (MACH_UUID_COMMAND) <= sizeof (UINT64), -// "Alignment is not guaranteed." -// ); - - UuidCommand = (MACH_UUID_COMMAND *) (VOID *) MachoGetNextCommand64 ( - Context, - MACH_LOAD_COMMAND_UUID, - NULL - ); - if (UuidCommand == NULL || UuidCommand->CommandSize != sizeof (*UuidCommand)) { - return NULL; - } - return UuidCommand; -} - -/** - Retrieves the first segment by the name of SegmentName. - - @param[in,out] Context Context of the Mach-O. - @param[in] SegmentName Segment name to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_SEGMENT_COMMAND_64 * -MachoGetSegmentByName64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SegmentName - ) -{ - MACH_SEGMENT_COMMAND_64 *Segment; - INTN Result; - - ASSERT (Context != NULL); - ASSERT (SegmentName != NULL); - - Result = 0; - - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - Result = AsciiStrnCmp ( - Segment->SegmentName, - SegmentName, - ARRAY_SIZE (Segment->SegmentName) - ); - if (Result == 0) { - return Segment; - } - } - - return NULL; -} - -/** - Returns whether Section is sane. - - @param[in,out] Context Context of the Mach-O. - @param[in] Section Section to verify. - @param[in] Segment Segment the section is part of. - -**/ -STATIC -BOOLEAN -InternalSectionIsSane ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_SECTION_64 *Section, - IN CONST MACH_SEGMENT_COMMAND_64 *Segment - ) -{ - UINT64 TopOffset64; - UINT32 TopOffset32; - UINT64 TopOfSegment; - BOOLEAN Result; - UINT64 TopOfSection; - - ASSERT (Context != NULL); - ASSERT (Section != NULL); - ASSERT (Segment != NULL); - // - // Section->Alignment is stored as a power of 2. - // - if ((Section->Alignment > 31) - || ((Section->Offset != 0) && (Section->Offset < Segment->FileOffset))) { - return FALSE; - } - - TopOfSegment = (Segment->VirtualAddress + Segment->Size); - Result = OcOverflowAddU64 ( - Section->Address, - Section->Size, - &TopOfSection - ); - if (Result || (TopOfSection > TopOfSegment)) { - return FALSE; - } - - Result = OcOverflowAddU64 ( - Section->Offset, - Section->Size, - &TopOffset64 - ); - if (Result || (TopOffset64 > (Segment->FileOffset + Segment->FileSize))) { - return FALSE; - } - - if (Section->NumRelocations != 0) { - Result = OcOverflowSubU32 ( - Section->RelocationsOffset, - Context->ContainerOffset, - &TopOffset32 - ); - Result |= OcOverflowMulAddU32 ( - Section->NumRelocations, - sizeof (MACH_RELOCATION_INFO), - TopOffset32, - &TopOffset32 - ); - if (Result || (TopOffset32 > Context->FileSize)) { - return FALSE; - } - } - - return TRUE; -} - -/** - Retrieves the first section by the name of SectionName. - - @param[in,out] Context Context of the Mach-O. - @param[in] Segment Segment to search in. - @param[in] SectionName Section name to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_SECTION_64 * -MachoGetSectionByName64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN MACH_SEGMENT_COMMAND_64 *Segment, - IN CONST CHAR8 *SectionName - ) -{ - MACH_SECTION_64 *Section; - INTN Result; - - ASSERT (Context != NULL); - ASSERT (Segment != NULL); - ASSERT (SectionName != NULL); - - for ( - Section = MachoGetNextSection64 (Context, Segment, NULL); - Section != NULL; - Section = MachoGetNextSection64 (Context, Segment, Section) - ) { - // - // Assumption: Mach-O is not of type MH_OBJECT. - // MH_OBJECT might have sections in segments they do not belong in for - // performance reasons. This library does not support intermediate - // objects. - // - Result = AsciiStrnCmp ( - Section->SectionName, - SectionName, - ARRAY_SIZE (Section->SectionName) - ); - if (Result == 0) { - return Section; - } - } - - return NULL; -} - -/** - Retrieves a section within a segment by the name of SegmentName. - - @param[in,out] Context Context of the Mach-O. - @param[in] SegmentName The name of the segment to search in. - @param[in] SectionName The name of the section to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_SECTION_64 * -MachoGetSegmentSectionByName64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *SegmentName, - IN CONST CHAR8 *SectionName - ) -{ - MACH_SEGMENT_COMMAND_64 *Segment; - - ASSERT (Context != NULL); - ASSERT (SegmentName != NULL); - ASSERT (SectionName != NULL); - - Segment = MachoGetSegmentByName64 (Context, SegmentName); - - if (Segment != NULL) { - return MachoGetSectionByName64 (Context, Segment, SectionName); - } - - return NULL; -} - -/** - Retrieves the next segment. - - @param[in,out] Context Context of the Mach-O. - @param[in] Segment Segment to retrieve the successor of. - if NULL, the first segment is returned. - - @retal NULL NULL is returned on failure. - -**/ -MACH_SEGMENT_COMMAND_64 * -MachoGetNextSegment64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_SEGMENT_COMMAND_64 *Segment OPTIONAL - ) -{ - MACH_SEGMENT_COMMAND_64 *NextSegment; - - CONST MACH_HEADER_64 *MachHeader; - UINTN TopOfCommands; - BOOLEAN Result; - UINT64 TopOfSegment; - UINTN TopOfSections; - - ASSERT (Context != NULL); - - ASSERT (Context->MachHeader != NULL); - ASSERT (Context->FileSize > 0); - - if (Segment != NULL) { - MachHeader = Context->MachHeader; - TopOfCommands = ((UINTN) MachHeader->Commands + MachHeader->CommandsSize); - ASSERT ( - ((UINTN) Segment >= (UINTN) &MachHeader->Commands[0]) - && ((UINTN) Segment < TopOfCommands) - ); - } - // - // Context initialisation guarantees the command size is a multiple of 8. - // -// STATIC_ASSERT ( -// OC_ALIGNOF (MACH_SEGMENT_COMMAND_64) <= sizeof (UINT64), -// "Alignment is not guaranteed." -// ); - NextSegment = (MACH_SEGMENT_COMMAND_64 *) (VOID *) MachoGetNextCommand64 ( - Context, - MACH_LOAD_COMMAND_SEGMENT_64, - (CONST MACH_LOAD_COMMAND *) Segment - ); - if (NextSegment == NULL || NextSegment->CommandSize < sizeof (*NextSegment)) { - return NULL; - } - - Result = OcOverflowMulAddUN ( - NextSegment->NumSections, - sizeof (*NextSegment->Sections), - (UINTN) NextSegment->Sections, - &TopOfSections - ); - if (Result || (((UINTN) NextSegment + NextSegment->CommandSize) < TopOfSections)) { - return NULL; - } - - Result = OcOverflowSubU64 ( - NextSegment->FileOffset, - Context->ContainerOffset, - &TopOfSegment - ); - Result |= OcOverflowAddU64 ( - TopOfSegment, - NextSegment->FileSize, - &TopOfSegment - ); - if (Result || (TopOfSegment > Context->FileSize)) { - return NULL; - } - - if (NextSegment->VirtualAddress + NextSegment->Size < NextSegment->VirtualAddress) { - return NULL; - } - - return NextSegment; -} - -/** - Retrieves the next section of a segment. - - - @param[in,out] Context Context of the Mach-O. - @param[in] Segment The segment to get the section of. - @param[in] Section The section to get the successor of. - If NULL, the first section is returned. - @retval NULL NULL is returned on failure. - -**/ -MACH_SECTION_64 * -MachoGetNextSection64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN MACH_SEGMENT_COMMAND_64 *Segment, - IN MACH_SECTION_64 *Section OPTIONAL - ) -{ - ASSERT (Context != NULL); - ASSERT (Segment != NULL); - - if (Section != NULL) { - ASSERT (Section >= Segment->Sections); - - ++Section; - - if (Section >= &Segment->Sections[Segment->NumSections]) { - return NULL; - } - } else if (Segment->NumSections > 0) { - Section = &Segment->Sections[0]; - } else { - return NULL; - } - - if (!InternalSectionIsSane (Context, Section, Segment)) { - return NULL; - } - - return Section; -} - -/** - Retrieves a section by its index. - - @param[in,out] Context Context of the Mach-O. - @param[in] Index Index of the section to retrieve. - - @retval NULL NULL is returned on failure. - -**/ -MACH_SECTION_64 * -MachoGetSectionByIndex64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT32 Index - ) -{ - MACH_SECTION_64 *Section; - - MACH_SEGMENT_COMMAND_64 *Segment; - UINT32 SectionIndex; - UINT32 NextSectionIndex; - BOOLEAN Result; - - ASSERT (Context != NULL); - - SectionIndex = 0; - - Segment = NULL; - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - Result = OcOverflowAddU32 ( - SectionIndex, - Segment->NumSections, - &NextSectionIndex - ); - // - // If NextSectionIndex is wrapping around, Index must be contained. - // - if (Result || (Index < NextSectionIndex)) { - Section = &Segment->Sections[Index - SectionIndex]; - if (!InternalSectionIsSane (Context, Section, Segment)) { - return NULL; - } - - return Section; - } - - SectionIndex = NextSectionIndex; - } - - return NULL; -} - -/** - Retrieves a section by its address. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address Address of the section to retrieve. - - @retval NULL NULL is returned on failure. - -**/ -MACH_SECTION_64 * -MachoGetSectionByAddress64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address - ) -{ - MACH_SEGMENT_COMMAND_64 *Segment; - MACH_SECTION_64 *Section; - UINT64 TopOfSegment; - UINT64 TopOfSection; - - ASSERT (Context != NULL); - - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - TopOfSegment = (Segment->VirtualAddress + Segment->Size); - if ((Address >= Segment->VirtualAddress) && (Address < TopOfSegment)) { - for ( - Section = MachoGetNextSection64 (Context, Segment, NULL); - Section != NULL; - Section = MachoGetNextSection64 (Context, Segment, Section) - ) { - TopOfSection = (Section->Address + Section->Size); - if ((Address >= Section->Address) && (Address < TopOfSection)) { - return Section; - } - } - } - } - - return NULL; -} - -/** - Initialises the symbol information of Context. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symtab The SYMTAB command to initialise with. - @param[in] DySymtab The DYSYMTAB command to initialise with. - - @returns Whether the operation was successful. - -**/ -STATIC -BOOLEAN -InternalInitialiseSymtabs64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN MACH_SYMTAB_COMMAND *Symtab, - IN MACH_DYSYMTAB_COMMAND *DySymtab - ) -{ - UINTN MachoAddress; - CHAR8 *StringTable; - UINT32 FileSize; - UINT32 SymbolsOffset; - UINT32 StringsOffset; - UINT32 OffsetTop; - BOOLEAN Result; - - UINT32 IndirectSymbolsOffset; - UINT32 LocalRelocationsOffset; - UINT32 ExternalRelocationsOffset; - MACH_NLIST_64 *SymbolTable; - MACH_NLIST_64 *IndirectSymtab; - MACH_RELOCATION_INFO *LocalRelocations; - MACH_RELOCATION_INFO *ExternRelocations; - - VOID *Tmp; - - ASSERT (Context != NULL); - ASSERT (Context->MachHeader != NULL); - ASSERT (Context->FileSize > 0); - ASSERT (Context->SymbolTable == NULL); - - FileSize = Context->FileSize; - - Result = OcOverflowSubU32 ( - Symtab->SymbolsOffset, - Context->ContainerOffset, - &SymbolsOffset - ); - Result |= OcOverflowMulAddU32 ( - Symtab->NumSymbols, - sizeof (MACH_NLIST_64), - SymbolsOffset, - &OffsetTop - ); - if (Result || (OffsetTop > FileSize)) { - return FALSE; - } - - Result = OcOverflowSubU32 ( - Symtab->StringsOffset, - Context->ContainerOffset, - &StringsOffset - ); - Result |= OcOverflowAddU32 ( - StringsOffset, - Symtab->StringsSize, - &OffsetTop - ); - if (Result || (OffsetTop > FileSize)) { - return FALSE; - } - - MachoAddress = (UINTN)Context->MachHeader; - StringTable = (CHAR8 *)(MachoAddress + StringsOffset); - - if (Symtab->StringsSize == 0 || StringTable[Symtab->StringsSize - 1] != '\0') { - return FALSE; - } - - Tmp = (VOID *)(MachoAddress + SymbolsOffset); - if (!OC_TYPE_ALIGNED (MACH_NLIST_64, Tmp)) { - return FALSE; - } - SymbolTable = (MACH_NLIST_64 *)Tmp; - - IndirectSymtab = NULL; - LocalRelocations = NULL; - ExternRelocations = NULL; - - if (DySymtab != NULL) { - Result = OcOverflowAddU32 ( - DySymtab->LocalSymbolsIndex, - DySymtab->NumLocalSymbols, - &OffsetTop - ); - if (Result || (OffsetTop > Symtab->NumSymbols)) { - return FALSE; - } - - Result = OcOverflowAddU32 ( - DySymtab->ExternalSymbolsIndex, - DySymtab->NumExternalSymbols, - &OffsetTop - ); - if (Result || (OffsetTop > Symtab->NumSymbols)) { - return FALSE; - } - - Result = OcOverflowAddU32 ( - DySymtab->UndefinedSymbolsIndex, - DySymtab->NumUndefinedSymbols, - &OffsetTop - ); - if (Result || (OffsetTop > Symtab->NumSymbols)) { - return FALSE; - } - - // - // We additionally check for offset validity here, as KC kexts have some garbage - // in their DySymtab, but it is "valid" for symbols. - // - if (DySymtab->NumIndirectSymbols > 0 && DySymtab->IndirectSymbolsOffset != 0) { - Result = OcOverflowSubU32 ( - DySymtab->IndirectSymbolsOffset, - Context->ContainerOffset, - &IndirectSymbolsOffset - ); - Result |= OcOverflowMulAddU32 ( - DySymtab->NumIndirectSymbols, - sizeof (MACH_NLIST_64), - IndirectSymbolsOffset, - &OffsetTop - ); - if (Result || (OffsetTop > FileSize)) { - return FALSE; - } - - Tmp = (VOID *)(MachoAddress + IndirectSymbolsOffset); - if (!OC_TYPE_ALIGNED (MACH_NLIST_64, Tmp)) { - return FALSE; - } - IndirectSymtab = (MACH_NLIST_64 *)Tmp; - } - - if (DySymtab->NumOfLocalRelocations > 0 && DySymtab->LocalRelocationsOffset != 0) { - Result = OcOverflowSubU32 ( - DySymtab->LocalRelocationsOffset, - Context->ContainerOffset, - &LocalRelocationsOffset - ); - Result |= OcOverflowMulAddU32 ( - DySymtab->NumOfLocalRelocations, - sizeof (MACH_RELOCATION_INFO), - LocalRelocationsOffset, - &OffsetTop - ); - if (Result || (OffsetTop > FileSize)) { - return FALSE; - } - - Tmp = (VOID *)(MachoAddress + LocalRelocationsOffset); - if (!OC_TYPE_ALIGNED (MACH_RELOCATION_INFO, Tmp)) { - return FALSE; - } - LocalRelocations = (MACH_RELOCATION_INFO *)Tmp; - } - - if (DySymtab->NumExternalRelocations > 0 && DySymtab->ExternalRelocationsOffset != 0) { - Result = OcOverflowSubU32 ( - DySymtab->ExternalRelocationsOffset, - Context->ContainerOffset, - &ExternalRelocationsOffset - ); - Result |= OcOverflowMulAddU32 ( - DySymtab->NumExternalRelocations, - sizeof (MACH_RELOCATION_INFO), - ExternalRelocationsOffset, - &OffsetTop - ); - if (Result || (OffsetTop > FileSize)) { - return FALSE; - } - - Tmp = (VOID *)(MachoAddress + ExternalRelocationsOffset); - if (!OC_TYPE_ALIGNED (MACH_RELOCATION_INFO, Tmp)) { - return FALSE; - } - ExternRelocations = (MACH_RELOCATION_INFO *)Tmp; - } - } - - // - // Store the symbol information. - // - Context->Symtab = Symtab; - Context->SymbolTable = SymbolTable; - Context->StringTable = StringTable; - Context->DySymtab = DySymtab; - - Context->IndirectSymbolTable = IndirectSymtab; - Context->LocalRelocations = LocalRelocations; - Context->ExternRelocations = ExternRelocations; - - return TRUE; -} - -BOOLEAN -MachoInitialiseSymtabsExternal64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN OC_MACHO_CONTEXT *SymsContext - ) -{ - MACH_SYMTAB_COMMAND *Symtab; - MACH_DYSYMTAB_COMMAND *DySymtab; - BOOLEAN IsDyld; - - if (Context->SymbolTable != NULL) { - return TRUE; - } - // - // We cannot use SymsContext's symbol tables if Context is flagged for DYLD - // and SymsContext is not. - // - IsDyld = (Context->MachHeader->Flags & MACH_HEADER_FLAG_DYNAMIC_LINKER_LINK) != 0; - if (IsDyld - && (SymsContext->MachHeader->Flags & MACH_HEADER_FLAG_DYNAMIC_LINKER_LINK) == 0) { - return FALSE; - } - - // - // Context initialisation guarantees the command size is a multiple of 8. - // -// STATIC_ASSERT ( -// OC_ALIGNOF (MACH_SYMTAB_COMMAND) <= sizeof (UINT64), -// "Alignment is not guaranteed." -// ); - // - // Retrieve SYMTAB. - // - Symtab = (MACH_SYMTAB_COMMAND *) (VOID *) MachoGetNextCommand64 ( - SymsContext, - MACH_LOAD_COMMAND_SYMTAB, - NULL - ); - if (Symtab == NULL || Symtab->CommandSize != sizeof (*Symtab)) { - return FALSE; - } - - DySymtab = NULL; - - if (IsDyld) { - // - // Context initialisation guarantees the command size is a multiple of 8. - // -// STATIC_ASSERT ( -// OC_ALIGNOF (MACH_DYSYMTAB_COMMAND) <= sizeof (UINT64), -// "Alignment is not guaranteed." -// ); - // - // Retrieve DYSYMTAB. - // - DySymtab = (MACH_DYSYMTAB_COMMAND *) (VOID *) MachoGetNextCommand64 ( - SymsContext, - MACH_LOAD_COMMAND_DYSYMTAB, - NULL - ); - if (DySymtab == NULL || DySymtab->CommandSize != sizeof (*DySymtab)) { - return FALSE; - } - } - - return InternalInitialiseSymtabs64 (Context, Symtab, DySymtab); -} - -BOOLEAN -InternalRetrieveSymtabs64 ( - IN OUT OC_MACHO_CONTEXT *Context - ) -{ - // - // Retrieve the symbol information for Context from itself. - // - return MachoInitialiseSymtabsExternal64 (Context, Context); -} - -UINT32 -MachoGetSymbolTable ( - IN OUT OC_MACHO_CONTEXT *Context, - OUT CONST MACH_NLIST_64 **SymbolTable, - OUT CONST CHAR8 **StringTable OPTIONAL, - OUT CONST MACH_NLIST_64 **LocalSymbols, OPTIONAL - OUT UINT32 *NumLocalSymbols, OPTIONAL - OUT CONST MACH_NLIST_64 **ExternalSymbols, OPTIONAL - OUT UINT32 *NumExternalSymbols, OPTIONAL - OUT CONST MACH_NLIST_64 **UndefinedSymbols, OPTIONAL - OUT UINT32 *NumUndefinedSymbols OPTIONAL - ) -{ - UINT32 Index; - CONST MACH_NLIST_64 *SymTab; - UINT32 NoLocalSymbols; - UINT32 NoExternalSymbols; - UINT32 NoUndefinedSymbols; - - ASSERT (Context != NULL); - - if (!InternalRetrieveSymtabs64 (Context)) { - return 0; - } - - if (Context->Symtab->NumSymbols == 0) { - return 0; - } - - SymTab = Context->SymbolTable; - - for (Index = 0; Index < Context->Symtab->NumSymbols; ++Index) { - if (!InternalSymbolIsSane (Context, &SymTab[Index])) { - return 0; - } - } - - *SymbolTable = Context->SymbolTable; - - if (StringTable != NULL) { - *StringTable = Context->StringTable; - } - - NoLocalSymbols = 0; - NoExternalSymbols = 0; - NoUndefinedSymbols = 0; - - if (Context->DySymtab != NULL) { - NoLocalSymbols = Context->DySymtab->NumLocalSymbols; - NoExternalSymbols = Context->DySymtab->NumExternalSymbols; - NoUndefinedSymbols = Context->DySymtab->NumUndefinedSymbols; - } - - if (NumLocalSymbols != NULL) { - ASSERT (LocalSymbols != NULL); - *NumLocalSymbols = NoLocalSymbols; - if (NoLocalSymbols != 0) { - *LocalSymbols = &SymTab[Context->DySymtab->LocalSymbolsIndex]; - } - } - - if (NumExternalSymbols != NULL) { - ASSERT (ExternalSymbols != NULL); - *NumExternalSymbols = NoExternalSymbols; - if (NoExternalSymbols != 0) { - *ExternalSymbols = &SymTab[Context->DySymtab->ExternalSymbolsIndex]; - } - } - - if (NumUndefinedSymbols != NULL) { - ASSERT (UndefinedSymbols != NULL); - *NumUndefinedSymbols = NoUndefinedSymbols; - if (NoUndefinedSymbols != 0) { - *UndefinedSymbols = &SymTab[Context->DySymtab->UndefinedSymbolsIndex]; - } - } - - return Context->Symtab->NumSymbols; -} - -UINT32 -MachoGetIndirectSymbolTable ( - IN OUT OC_MACHO_CONTEXT *Context, - OUT CONST MACH_NLIST_64 **SymbolTable - ) -{ - UINT32 Index; - - if (!InternalRetrieveSymtabs64 (Context)) { - return 0; - } - - for (Index = 0; Index < Context->DySymtab->NumIndirectSymbols; ++Index) { - if ( - !InternalSymbolIsSane (Context, &Context->IndirectSymbolTable[Index]) - ) { - return 0; - } - } - - *SymbolTable = Context->IndirectSymbolTable; - - return Context->DySymtab->NumIndirectSymbols; -} - -/** - Returns a pointer to the Mach-O file at the specified virtual address. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address Virtual address to look up. - @param[out] MaxSize Maximum data safely available from FileOffset. - If NULL is returned, the output is undefined. - -**/ -VOID * -MachoGetFilePointerByAddress64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address, - OUT UINT32 *MaxSize OPTIONAL - ) -{ - CONST MACH_SEGMENT_COMMAND_64 *Segment; - UINT64 Offset; - - Segment = NULL; - while ((Segment = MachoGetNextSegment64 (Context, Segment)) != NULL) { - if ((Address >= Segment->VirtualAddress) - && (Address < Segment->VirtualAddress + Segment->Size)) { - Offset = (Address - Segment->VirtualAddress); - - if (MaxSize != NULL) { - *MaxSize = (UINT32)(Segment->Size - Offset); - } - - Offset += Segment->FileOffset - Context->ContainerOffset; - return (VOID *)((UINTN)Context->MachHeader + (UINTN)Offset); - } - } - - return NULL; -} - -/** - Strip superfluous Load Commands from the Mach-O header. This includes the - Code Signature Load Command which must be removed for the binary has been - modified by the prelinking routines. - - @param[in,out] MachHeader Mach-O header to strip the Load Commands from. - -**/ -STATIC -VOID -InternalStripLoadCommands64 ( - IN OUT MACH_HEADER_64 *MachHeader - ) -{ - STATIC CONST MACH_LOAD_COMMAND_TYPE LoadCommandsToStrip[] = { - MACH_LOAD_COMMAND_CODE_SIGNATURE, - MACH_LOAD_COMMAND_DYLD_INFO, - MACH_LOAD_COMMAND_DYLD_INFO_ONLY, - MACH_LOAD_COMMAND_FUNCTION_STARTS, - MACH_LOAD_COMMAND_DATA_IN_CODE, - MACH_LOAD_COMMAND_DYLIB_CODE_SIGN_DRS - }; - - UINT32 Index; - UINT32 Index2; - MACH_LOAD_COMMAND *LoadCommand; - UINT32 SizeOfLeftCommands; - UINT32 OriginalCommandSize; - // - // Delete the Code Signature Load Command if existent as we modified the - // binary, as well as linker metadata not needed for runtime operation. - // - LoadCommand = MachHeader->Commands; - SizeOfLeftCommands = MachHeader->CommandsSize; - OriginalCommandSize = SizeOfLeftCommands; - - for (Index = 0; Index < MachHeader->NumCommands; ++Index) { - // - // Assertion: LC_UNIXTHREAD and LC_MAIN are technically stripped in KXLD, - // but they are not supposed to be present in the first place. - // - if ((LoadCommand->CommandType == MACH_LOAD_COMMAND_UNIX_THREAD) - || (LoadCommand->CommandType == MACH_LOAD_COMMAND_MAIN)) { - DEBUG ((DEBUG_WARN, "OCMCO: UNIX Thread and Main LCs are unsupported\n")); - } - - SizeOfLeftCommands -= LoadCommand->CommandSize; - - for (Index2 = 0; Index2 < ARRAY_SIZE (LoadCommandsToStrip); ++Index2) { - if (LoadCommand->CommandType == LoadCommandsToStrip[Index2]) { - if (Index != (MachHeader->NumCommands - 1)) { - // - // If the current Load Command is not the last one, relocate the - // subsequent ones. - // - CopyMem ( - LoadCommand, - NEXT_MACH_LOAD_COMMAND (LoadCommand), - SizeOfLeftCommands - ); - } - - --MachHeader->NumCommands; - MachHeader->CommandsSize -= LoadCommand->CommandSize; - - break; - } - } - - LoadCommand = NEXT_MACH_LOAD_COMMAND (LoadCommand); - } - - ZeroMem (LoadCommand, OriginalCommandSize - MachHeader->CommandsSize); -} - -UINT32 -MachoExpandImage64 ( - IN OC_MACHO_CONTEXT *Context, - OUT UINT8 *Destination, - IN UINT32 DestinationSize, - IN BOOLEAN Strip - ) -{ - MACH_HEADER_64 *Header; - UINT8 *Source; - UINT32 HeaderSize; - UINT64 CopyFileOffset; - UINT64 CopyFileSize; - UINT64 CopyVmSize; - UINT32 CurrentDelta; - UINT32 OriginalDelta; - UINT64 CurrentSize; - UINT32 FileSize; - MACH_SEGMENT_COMMAND_64 *Segment; - MACH_SEGMENT_COMMAND_64 *FirstSegment; - MACH_SEGMENT_COMMAND_64 *DstSegment; - MACH_SYMTAB_COMMAND *Symtab; - MACH_DYSYMTAB_COMMAND *DySymtab; - UINT32 Index; - - ASSERT (Context != NULL); - ASSERT (Context->FileSize != 0); - - // - // Header is valid, copy it first. - // - Header = MachoGetMachHeader64 (Context); - Source = (UINT8 *) Header; - HeaderSize = sizeof (*Header) + Header->CommandsSize; - if (HeaderSize > DestinationSize) { - return 0; - } - CopyMem (Destination, Header, HeaderSize); - - CurrentDelta = 0; - FirstSegment = NULL; - CurrentSize = 0; - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - // - // Align delta by x86 page size, this is what our lib expects. - // - OriginalDelta = CurrentDelta; - CurrentDelta = MACHO_ALIGN (CurrentDelta); - if (Segment->FileSize > Segment->Size) { - return 0; - } - - if (FirstSegment == NULL) { - FirstSegment = Segment; - } - - // - // Do not overwrite header. - // - CopyFileOffset = Segment->FileOffset - Context->ContainerOffset; - CopyFileSize = Segment->FileSize; - CopyVmSize = Segment->Size; - if (CopyFileOffset <= HeaderSize) { - CopyFileOffset = HeaderSize; - CopyFileSize = Segment->FileSize - CopyFileOffset; - CopyVmSize = Segment->Size - CopyFileOffset; - if (CopyFileSize > Segment->FileSize || CopyVmSize > Segment->Size) { - // - // Header must fit in 1 segment. - // - return 0; - } - } - // - // Ensure that it still fits. In legit files segments are ordered. - // We do not care for other (the file will be truncated). - // - if (OcOverflowTriAddU64 (CopyFileOffset, CurrentDelta, CopyVmSize, &CurrentSize) - || CurrentSize > DestinationSize) { - return 0; - } - - // - // Copy and zero fill file data. We can do this because only last sections can have 0 file size. - // - ASSERT (CopyFileSize <= MAX_UINTN && CopyVmSize <= MAX_UINTN); - ZeroMem(&Destination[CopyFileOffset + OriginalDelta], CurrentDelta - OriginalDelta); - CopyMem(&Destination[CopyFileOffset + CurrentDelta], &Source[CopyFileOffset], (UINTN)CopyFileSize); - ZeroMem(&Destination[CopyFileOffset + CurrentDelta + CopyFileSize], (UINTN)(CopyVmSize - CopyFileSize)); - // - // Refresh destination segment size and offsets. - // - DstSegment = (MACH_SEGMENT_COMMAND_64 *) ((UINT8 *) Segment - Source + Destination); - DstSegment->FileOffset += CurrentDelta; - DstSegment->FileSize = DstSegment->Size; - - if (DstSegment->VirtualAddress - (DstSegment->FileOffset - Context->ContainerOffset) != FirstSegment->VirtualAddress) { - return 0; - } - - // - // We need to update fields in SYMTAB and DYSYMTAB. Tables have to be present before 0 FileSize - // sections as they have data, so we update them before parsing sections. - // Note: There is an assumption they are in __LINKEDIT segment, another option is to check addresses. - // - if (AsciiStrnCmp (DstSegment->SegmentName, "__LINKEDIT", ARRAY_SIZE (DstSegment->SegmentName)) == 0) { - Symtab = (MACH_SYMTAB_COMMAND *)( - MachoGetNextCommand64 ( - Context, - MACH_LOAD_COMMAND_SYMTAB, - NULL - ) - ); - - if (Symtab != NULL) { - Symtab = (MACH_SYMTAB_COMMAND *) ((UINT8 *) Symtab - Source + Destination); - if (Symtab->SymbolsOffset != 0) { - Symtab->SymbolsOffset += CurrentDelta; - } - if (Symtab->StringsOffset != 0) { - Symtab->StringsOffset += CurrentDelta; - } - } - - DySymtab = (MACH_DYSYMTAB_COMMAND *)( - MachoGetNextCommand64 ( - Context, - MACH_LOAD_COMMAND_DYSYMTAB, - NULL - ) - ); - - if (DySymtab != NULL) { - DySymtab = (MACH_DYSYMTAB_COMMAND *) ((UINT8 *) DySymtab - Source + Destination); - if (DySymtab->TableOfContentsNumEntries != 0) { - DySymtab->TableOfContentsNumEntries += CurrentDelta; - } - if (DySymtab->ModuleTableFileOffset != 0) { - DySymtab->ModuleTableFileOffset += CurrentDelta; - } - if (DySymtab->ReferencedSymbolTableFileOffset != 0) { - DySymtab->ReferencedSymbolTableFileOffset += CurrentDelta; - } - if (DySymtab->IndirectSymbolsOffset != 0) { - DySymtab->IndirectSymbolsOffset += CurrentDelta; - } - if (DySymtab->ExternalRelocationsOffset != 0) { - DySymtab->ExternalRelocationsOffset += CurrentDelta; - } - if (DySymtab->LocalRelocationsOffset != 0) { - DySymtab->LocalRelocationsOffset += CurrentDelta; - } - } - } - // - // These may well wrap around with invalid data. - // But we do not care, as we do not access these fields ourselves, - // and later on the section values are checked by MachoLib. - // Note: There is an assumption that 'CopyFileOffset + CurrentDelta' is aligned. - // - OriginalDelta = CurrentDelta; - CopyFileOffset = Segment->FileOffset; - for (Index = 0; Index < DstSegment->NumSections; ++Index) { - if (DstSegment->Sections[Index].Offset == 0) { - DstSegment->Sections[Index].Offset = (UINT32) CopyFileOffset + CurrentDelta; - CurrentDelta += (UINT32) DstSegment->Sections[Index].Size; - } else { - DstSegment->Sections[Index].Offset += CurrentDelta; - CopyFileOffset = DstSegment->Sections[Index].Offset + DstSegment->Sections[Index].Size; - } - } - - CurrentDelta = OriginalDelta + (UINT32)(Segment->Size - Segment->FileSize); - } - // - // CurrentSize will only be 0 if there are no valid segments, which is the - // case for Kernel Resource KEXTs. In this case, try to use the raw file. - // - if (CurrentSize == 0) { - FileSize = MachoGetFileSize (Context); - // - // HeaderSize must be at most as big as the file size by OcMachoLib - // guarantees. It's sanity-checked to ensure the safety of the subtraction. - // - ASSERT (FileSize >= HeaderSize); - - if (FileSize > DestinationSize) { - return 0; - } - - CopyMem ( - Destination + HeaderSize, - (UINT8 *)Header + HeaderSize, - FileSize - HeaderSize - ); - - CurrentSize = FileSize; - } - - if (Strip) { - InternalStripLoadCommands64 ((MACH_HEADER_64 *) Destination); - } - // - // This cast is safe because CurrentSize is verified against DestinationSize. - // - return (UINT32) CurrentSize; -} - -UINT64 -MachoRuntimeGetEntryAddress ( - IN VOID *Image - ) -{ - MACH_HEADER_ANY *Header; - BOOLEAN Is64Bit; - UINT32 NumCmds; - MACH_LOAD_COMMAND *Cmd; - UINTN Index; - MACH_THREAD_COMMAND *ThreadCmd; - MACH_X86_THREAD_STATE *ThreadState; - UINT64 Address; - - Address = 0; - Header = (MACH_HEADER_ANY *) Image; - - if (Header->Signature == MACH_HEADER_SIGNATURE) { - // - // 32-bit header. - // - Is64Bit = FALSE; - NumCmds = Header->Header32.NumCommands; - Cmd = &Header->Header32.Commands[0]; - } else if (Header->Signature == MACH_HEADER_64_SIGNATURE) { - // - // 64-bit header. - // - Is64Bit = TRUE; - NumCmds = Header->Header64.NumCommands; - Cmd = &Header->Header64.Commands[0]; - } else { - // - // Invalid Mach-O image. - // - return Address; - } - - // - // Iterate over load commands. - // - for (Index = 0; Index < NumCmds; ++Index) { - if (Cmd->CommandType == MACH_LOAD_COMMAND_UNIX_THREAD) { - ThreadCmd = (MACH_THREAD_COMMAND *) Cmd; - ThreadState = (MACH_X86_THREAD_STATE *) &ThreadCmd->ThreadState[0]; - Address = Is64Bit ? ThreadState->State64.rip : ThreadState->State32.eip; - break; - } - - Cmd = NEXT_MACH_LOAD_COMMAND (Cmd); - } - - return Address; -} - -BOOLEAN -MachoMergeSegments64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *Prefix - ) -{ - UINT32 LcIndex; - MACH_LOAD_COMMAND *LoadCommand; - MACH_SEGMENT_COMMAND_64 *Segment; - MACH_SEGMENT_COMMAND_64 *FirstSegment; - MACH_HEADER_64 *Header; - UINTN PrefixLength; - UINTN RemainingArea; - UINT32 SkipCount; - - ASSERT (Context != NULL); - ASSERT (Context->FileSize != 0); - ASSERT (Prefix != NULL); - - Header = MachoGetMachHeader64 (Context); - PrefixLength = AsciiStrLen (Prefix); - FirstSegment = NULL; - - SkipCount = 0; - - LoadCommand = &Header->Commands[0]; - - for (LcIndex = 0; LcIndex < Header->NumCommands; ++LcIndex) { - // - // Either skip or stop at unrelated commands. - // - Segment = (MACH_SEGMENT_COMMAND_64 *) (VOID *) LoadCommand; - - if (LoadCommand->CommandType != MACH_LOAD_COMMAND_SEGMENT_64 - || AsciiStrnCmp (Segment->SegmentName, Prefix, PrefixLength) != 0) { - if (FirstSegment != NULL) { - break; - } - - LoadCommand = NEXT_MACH_LOAD_COMMAND (LoadCommand); - continue; - } - - // - // We have a segment starting with the prefix. - // - - // - // Do not support this for now as it will require changes in the file. - // - if (Segment->Size != Segment->FileSize) { - return FALSE; - } - - // - // Remember the first segment or assume it is a skip. - // - if (FirstSegment == NULL) { - FirstSegment = Segment; - } else { - ++SkipCount; - - // - // Expand the first segment. - // TODO: Do we need to check these for overflow for our own purposes? - // - FirstSegment->Size = Segment->VirtualAddress - FirstSegment->VirtualAddress + Segment->Size; - FirstSegment->FileSize = Segment->FileOffset - FirstSegment->FileOffset + Segment->FileSize; - - // - // Add new segment protection to the first segment. - // - FirstSegment->InitialProtection |= Segment->InitialProtection; - FirstSegment->MaximumProtection |= Segment->MaximumProtection; - } - - LoadCommand = NEXT_MACH_LOAD_COMMAND (LoadCommand); - } - - // - // The segment does not exist. - // - if (FirstSegment == NULL) { - return FALSE; - } - - // - // The segment is only one. - // - if (SkipCount == 0) { - return FALSE; - } - - // - // Move back remaining commands ontop of the skipped ones and zero this area. - // - RemainingArea = Header->CommandsSize - ((UINTN) LoadCommand - (UINTN) &Header->Commands[0]); - CopyMem ( - (UINT8 *) FirstSegment + FirstSegment->CommandSize, - LoadCommand, - RemainingArea - ); - ZeroMem (LoadCommand, RemainingArea); - - // - // Account for dropped commands in the header. - // - Header->NumCommands -= SkipCount; - Header->CommandsSize -= (UINT32) (sizeof (MACH_SEGMENT_COMMAND_64) * SkipCount); - - return TRUE; -} diff --git a/Library/MachoLib/MachoLib.inf b/Library/MachoLib/MachoLib.inf deleted file mode 100644 index bce497ebc..000000000 --- a/Library/MachoLib/MachoLib.inf +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# Copyright (C) 2016 - 2017, Download-Fritz. All rights reserved.
-# This program and the accompanying materials are licensed and made available -# under the terms and conditions of the BSD License which accompanies this -# distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - BASE_NAME = MachoLib - LIBRARY_CLASS = MachoLib - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - INF_VERSION = 0x00010005 - -[Packages] - MdePkg/MdePkg.dec - CloverPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - OcGuardLib - -[Sources] - CxxSymbols.c - Header.c - MachoLibInternal.h - Relocations.c - Symbols.c diff --git a/Library/MachoLib/MachoLibInternal.h b/Library/MachoLib/MachoLibInternal.h deleted file mode 100644 index 82b5c2db3..000000000 --- a/Library/MachoLib/MachoLibInternal.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - Private data of OcMachoLib. - -Copyright (C) 2018, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_MACHO_LIB_INTERNAL_H_ -#define OC_MACHO_LIB_INTERNAL_H_ - -#include - -#include - -/** - Retrieves the SYMTAB command. - - @param[in] Context Context of the Mach-O. - - @retval NULL NULL is returned on failure. -**/ -BOOLEAN -InternalRetrieveSymtabs64 ( - IN OUT OC_MACHO_CONTEXT *Context - ); - -/** - Retrieves an extern Relocation by the address it targets. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address The address to search for. - - @retval NULL NULL is returned on failure. -**/ -MACH_RELOCATION_INFO * -InternalGetExternRelocationByOffset ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address - ); - -/** - Retrieves a Relocation by the address it targets. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address The address to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_RELOCATION_INFO * -InternalGetLocalRelocationByOffset ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address - ); - -/** - Check symbol validity. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symbol Symbol from some table. - - @retval TRUE on success. -**/ -BOOLEAN -InternalSymbolIsSane ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ); - -#endif // OC_MACHO_LIB_INTERNAL_H_ diff --git a/Library/MachoLib/Relocations.c b/Library/MachoLib/Relocations.c deleted file mode 100644 index 6a17db494..000000000 --- a/Library/MachoLib/Relocations.c +++ /dev/null @@ -1,158 +0,0 @@ -/** @file - Provides services for Relocations. - -Copyright (c) 2018, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include - -#include -#include - -#include "MachoLibInternal.h" - -/** - Returns whether the Relocation's type indicates a Pair for the Intel 64 - platform. - - @param[in] Type The Relocation's type to verify. - -**/ -BOOLEAN -MachoRelocationIsPairIntel64 ( - IN UINT8 Type - ) -{ - return (Type == MachX8664RelocSubtractor); -} - -/** - Returns whether the Relocation's type matches a Pair's for the Intel 64 - platform. - - @param[in] Type The Relocation's type to verify. - -**/ -BOOLEAN -MachoIsRelocationPairTypeIntel64 ( - IN UINT8 Type - ) -{ - return (Type == MachX8664RelocUnsigned); -} - -/** - Returns whether the Relocation shall be preserved for the Intel 64 platform. - - @param[in] Type The Relocation's type to verify. - -**/ -BOOLEAN -MachoPreserveRelocationIntel64 ( - IN UINT8 Type - ) -{ - return (Type == MachX8664RelocUnsigned); -} - -/** - Retrieves an extern Relocation by the address it targets. - - @param[in] Address The address to search for. - - @retval NULL NULL is returned on failure. - -**/ -STATIC -MACH_RELOCATION_INFO * -InternalLookupRelocationByOffset ( - IN UINT64 Address, - IN UINT32 NumRelocs, - IN MACH_RELOCATION_INFO *Relocs - ) -{ - UINT32 Index; - MACH_RELOCATION_INFO *Relocation; - - for (Index = 0; Index < NumRelocs; ++Index) { - Relocation = &Relocs[Index]; - // - // A section-based relocation entry can be skipped for absolute symbols. - // - if ((Relocation->Extern == 0) - && (Relocation->SymbolNumber == MACH_RELOC_ABSOLUTE)) { - continue; - } - - if ((UINT64)Relocation->Address == Address) { - return Relocation; - } - // - // Relocation Pairs can be skipped. - // Assumption: Intel X64. Currently verified by the Context - // initialization. - // - if (MachoRelocationIsPairIntel64 ((UINT8)Relocation->Type)) { - if (Index == (MAX_UINT32 - 1)) { - break; - } - ++Index; - } - } - - return NULL; -} - -/** - Retrieves an extern Relocation by the address it targets. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address The address to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_RELOCATION_INFO * -InternalGetExternRelocationByOffset ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address - ) -{ - return InternalLookupRelocationByOffset ( - Address, - Context->DySymtab->NumExternalRelocations, - Context->ExternRelocations - ); -} - -/** - Retrieves an extern Relocation by the address it targets. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address The address to search for. - - @retval NULL NULL is returned on failure. - -**/ -MACH_RELOCATION_INFO * -InternalGetLocalRelocationByOffset ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address - ) -{ - return InternalLookupRelocationByOffset ( - Address, - Context->DySymtab->NumOfLocalRelocations, - Context->LocalRelocations - ); -} diff --git a/Library/MachoLib/Symbols.c b/Library/MachoLib/Symbols.c deleted file mode 100644 index e208383a3..000000000 --- a/Library/MachoLib/Symbols.c +++ /dev/null @@ -1,698 +0,0 @@ -/** @file - Provides services for symbols. - -Copyright (c) 2018, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include - -#include -#include -#include -#include - -#include "MachoLibInternal.h" - -BOOLEAN -InternalSymbolIsSane ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - - ASSERT (Context->SymbolTable != NULL); - ASSERT (Context->Symtab->NumSymbols > 0); - - ASSERT (((Symbol >= &Context->SymbolTable[0]) - && (Symbol < &Context->SymbolTable[Context->Symtab->NumSymbols])) - || ((Context->DySymtab != NULL) - && (Symbol >= &Context->IndirectSymbolTable[0]) - && (Symbol < &Context->IndirectSymbolTable[Context->DySymtab->NumIndirectSymbols]))); - // - // Symbol->Section is implicitly verified by MachoGetSectionByIndex64() when - // passed to it. - // - if (Symbol->UnifiedName.StringIndex >= Context->Symtab->StringsSize) { - return FALSE; - } - - return TRUE; -} - -/** - Returns whether the symbol's value is a valid address within the Mach-O - referenced to by Context. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symbol Symbol to verify the value of. - -**/ -BOOLEAN -MachoIsSymbolValueInRange64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ) -{ - CONST MACH_SEGMENT_COMMAND_64 *Segment; - - if (MachoSymbolIsLocalDefined (Context, Symbol)) { - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - if ((Symbol->Value >= Segment->VirtualAddress) - && (Symbol->Value < (Segment->VirtualAddress + Segment->Size))) { - return TRUE; - } - } - - return FALSE; - } - - return TRUE; -} - -/** - Returns whether Symbol describes a section type. - - @param[in] Symbol Symbol to evaluate. - -**/ -STATIC -BOOLEAN -InternalSymbolIsSectionType ( - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Symbol != NULL); - - if ((Symbol->Type & MACH_N_TYPE_STAB) != 0) { - switch (Symbol->Type) { - // - // Labeled as MACH_N_sect in stab.h - // - case MACH_N_FUN: - case MACH_N_STSYM: - case MACH_N_LCSYM: - case MACH_N_BNSYM: - case MACH_N_SLINE: - case MACH_N_ENSYM: - case MACH_N_SO: - case MACH_N_SOL: - case MACH_N_ENTRY: - case MACH_N_ECOMM: - case MACH_N_ECOML: - // - // These are labeled as NO_SECT in stab.h, but they are actually - // section-based on OS X. We must mark them as such so they get - // relocated. - // - case MACH_N_RBRAC: - case MACH_N_LBRAC: - { - return TRUE; - } - - default: - { - break; - } - } - } else if ((Symbol->Type & MACH_N_TYPE_TYPE) == MACH_N_TYPE_SECT) { - return TRUE; - } - - return FALSE; -} - -/** - Returns whether Symbol describes a section. - - @param[in] Symbol Symbol to evaluate. - -**/ -BOOLEAN -MachoSymbolIsSection ( - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Symbol != NULL); - return (InternalSymbolIsSectionType (Symbol) && (Symbol->Section != NO_SECT)); -} - -/** - Returns whether Symbol is defined. - - @param[in] Symbol Symbol to evaluate. - -**/ -BOOLEAN -MachoSymbolIsDefined ( - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Symbol != NULL); - - return (((Symbol->Type & MACH_N_TYPE_STAB) == 0) - && (((Symbol->Type & MACH_N_TYPE_TYPE) == MACH_N_TYPE_ABS) - || InternalSymbolIsSectionType (Symbol))); -} - -/** - Returns whether Symbol is defined locally. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symbol Symbol to evaluate. - -**/ -BOOLEAN -MachoSymbolIsLocalDefined ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ) -{ - CONST MACH_DYSYMTAB_COMMAND *DySymtab; - CONST MACH_NLIST_64 *UndefinedSymbols; - CONST MACH_NLIST_64 *UndefinedSymbolsTop; - CONST MACH_NLIST_64 *IndirectSymbols; - CONST MACH_NLIST_64 *IndirectSymbolsTop; - - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - - DySymtab = Context->DySymtab; - ASSERT (Context->SymbolTable != NULL); - - if ((DySymtab == NULL) || (DySymtab->NumUndefinedSymbols == 0)) { - return TRUE; - } - // - // The symbol must have been declared locally prior to solving. As there is - // no information on whether the symbol has been solved explicitely, check - // its storage location for Undefined or Indirect. - // - UndefinedSymbols = &Context->SymbolTable[DySymtab->UndefinedSymbolsIndex]; - UndefinedSymbolsTop = &UndefinedSymbols[DySymtab->NumUndefinedSymbols]; - - if ((Symbol >= UndefinedSymbols) && (Symbol < UndefinedSymbolsTop)) { - return FALSE; - } - - IndirectSymbols = Context->IndirectSymbolTable; - IndirectSymbolsTop = &IndirectSymbols[DySymtab->NumIndirectSymbols]; - - if ((Symbol >= IndirectSymbols) && (Symbol < IndirectSymbolsTop)) { - return FALSE; - } - - return MachoSymbolIsDefined (Symbol); -} - -/** - Retrieves a symbol by its index. - - @param[in] Context Context of the Mach-O. - @param[in] Index Index of the symbol to locate. - - @retval NULL NULL is returned on failure. - -**/ -MACH_NLIST_64 * -MachoGetSymbolByIndex64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT32 Index - ) -{ - MACH_NLIST_64 *Symbol; - - ASSERT (Context != NULL); - - if (!InternalRetrieveSymtabs64 (Context)) { - return NULL; - } - - ASSERT (Context->SymbolTable != NULL); - - if (Index < Context->Symtab->NumSymbols) { - Symbol = &Context->SymbolTable[Index]; - if (InternalSymbolIsSane (Context, Symbol)) { - return Symbol; - } - } - - return NULL; -} - -/** - Retrieves Symbol's name. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symbol Symbol to retrieve the name of. - - @retval NULL NULL is returned on failure. - -**/ -CONST CHAR8 * -MachoGetSymbolName64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - - ASSERT (Context->SymbolTable != NULL); - ASSERT (Context->Symtab->StringsSize > Symbol->UnifiedName.StringIndex); - - return (Context->StringTable + Symbol->UnifiedName.StringIndex); -} - -/** - Retrieves Symbol's name. - - @param[in,out] Context Context of the Mach-O. - @param[in] Symbol Indirect symbol to retrieve the name of. - - @retval NULL NULL is returned on failure. - -**/ -CONST CHAR8 * -MachoGetIndirectSymbolName64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol - ) -{ - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - - ASSERT (Context->SymbolTable != NULL); - - if ((Symbol->Type & MACH_N_TYPE_STAB) != 0 - || (Symbol->Type & MACH_N_TYPE_TYPE) != MACH_N_TYPE_INDR) { - return NULL; - } - - if (Context->Symtab->StringsSize <= Symbol->Value) { - return NULL; - } - - return (Context->StringTable + Symbol->Value); -} - -/** - Retrieves a symbol by its value. - - @param[in] Context Context of the Mach-O. - @param[in] Value Value of the symbol to locate. - - @retval NULL NULL is returned on failure. - -**/ -STATIC -MACH_NLIST_64 * -InternalGetSymbolByValue ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Value - ) -{ - UINT32 Index; - - ASSERT (Context->SymbolTable != NULL); - ASSERT (Context->Symtab != NULL); - - for (Index = 0; Index < Context->Symtab->NumSymbols; ++Index) { - if (Context->SymbolTable[Index].Value == Value) { - return &Context->SymbolTable[Index]; - } - } - - return NULL; -} - -BOOLEAN -InternalGetSymbolByExternRelocationOffset64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address, - OUT MACH_NLIST_64 **Symbol - ) -{ - CONST MACH_RELOCATION_INFO *Relocation; - - ASSERT (Context != NULL); - - Relocation = InternalGetExternRelocationByOffset (Context, Address); - if (Relocation != NULL) { - *Symbol = MachoGetSymbolByIndex64 (Context, Relocation->SymbolNumber); - return TRUE; - } - - return FALSE; -} - -/** - Retrieves the symbol referenced by the extern Relocation targeting Address. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address Address to search for. - @param[out] Symbol Buffer to output the symbol referenced by the - Relocation into. The output is undefined when FALSE - is returned. May be NULL. - - @returns Whether the Relocation exists. - -**/ -BOOLEAN -MachoGetSymbolByExternRelocationOffset64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address, - OUT MACH_NLIST_64 **Symbol - ) -{ - if (Address >= MachoGetFileSize (Context)) { - return FALSE; - } - - return InternalGetSymbolByExternRelocationOffset64 ( - Context, - Address, - Symbol - ); -} - -/** - Retrieves the symbol referenced by the Relocation targeting Address. - - @param[in,out] Context Context of the Mach-O. - @param[in] Address Address to search for. - @param[out] Symbol Buffer to output the symbol referenced by the - Relocation into. The output is undefined when FALSE - is returned. May be NULL. - - @returns Whether the Relocation exists. - -**/ -BOOLEAN -MachoGetSymbolByRelocationOffset64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 Address, - OUT MACH_NLIST_64 **Symbol - ) -{ - BOOLEAN Result; - CONST MACH_RELOCATION_INFO *Relocation; - CONST UINT64 *Data; - MACH_NLIST_64 *Sym; - UINT64 AddressTop; - - VOID *Tmp; - - ASSERT (Context != NULL); - - Result = OcOverflowAddU64 (Address, sizeof (UINT64), &AddressTop); - if (Result || AddressTop > MachoGetFileSize (Context)) { - return FALSE; - } - - Result = InternalGetSymbolByExternRelocationOffset64 ( - Context, - Address, - Symbol - ); - if (Result) { - return TRUE; - } - - Relocation = InternalGetLocalRelocationByOffset (Context, Address); - if (Relocation != NULL) { - Sym = NULL; - - Tmp = (VOID *)((UINTN)Context->MachHeader + (UINTN)Address); - - if (OC_TYPE_ALIGNED (UINT64, Tmp)) { - Data = (UINT64 *)Tmp; - - // FIXME: Only C++ symbols. - Sym = InternalGetSymbolByValue (Context, *Data); - if ((Sym != NULL) && !InternalSymbolIsSane (Context, Sym)) { - Sym = NULL; - } - } - - *Symbol = Sym; - return TRUE; - } - - return FALSE; -} - -/** - Retrieves a symbol by its name. - - @param[in] Context Context of the Mach-O. - @param[in] SymbolTable Symbol Table of the Mach-O. - @param[in] NumberOfSymbols Number of symbols in SymbolTable. - @param[in] Name Name of the symbol to locate. - - @retval NULL NULL is returned on failure. - -**/ -STATIC -MACH_NLIST_64 * -InternalGetLocalDefinedSymbolByNameWorker ( - IN OUT OC_MACHO_CONTEXT *Context, - IN MACH_NLIST_64 *SymbolTable, - IN UINT32 NumberOfSymbols, - IN CONST CHAR8 *Name - ) -{ - UINT32 Index; - CONST CHAR8 *TmpName; - - ASSERT (SymbolTable != NULL); - ASSERT (Name != NULL); - - for (Index = 0; Index < NumberOfSymbols; ++Index) { - if (!InternalSymbolIsSane (Context, &SymbolTable[Index])) { - break; - } - - if (!MachoSymbolIsDefined (&SymbolTable[Index])) { - continue; - } - - TmpName = MachoGetSymbolName64 (Context, &SymbolTable[Index]); - if (AsciiStrCmp(Name, TmpName) == 0) { - return &SymbolTable[Index]; - } - } - - return NULL; -} - -/** - Retrieves a locally defined symbol by its name. - - @param[in,out] Context Context of the Mach-O. - @param[in] Name Name of the symbol to locate. - -**/ -MACH_NLIST_64 * -MachoGetLocalDefinedSymbolByName ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST CHAR8 *Name - ) -{ - MACH_NLIST_64 *SymbolTable; - CONST MACH_DYSYMTAB_COMMAND *DySymtab; - MACH_NLIST_64 *Symbol; - - ASSERT (Context != NULL); - ASSERT (Name != NULL); - - if (!InternalRetrieveSymtabs64 (Context)) { - return NULL; - } - - SymbolTable = Context->SymbolTable; - ASSERT (SymbolTable != NULL); - - DySymtab = Context->DySymtab; - - if (DySymtab != NULL) { - Symbol = InternalGetLocalDefinedSymbolByNameWorker ( - Context, - &SymbolTable[DySymtab->LocalSymbolsIndex], - DySymtab->NumLocalSymbols, - Name - ); - if (Symbol == NULL) { - Symbol = InternalGetLocalDefinedSymbolByNameWorker ( - Context, - &SymbolTable[DySymtab->ExternalSymbolsIndex], - DySymtab->NumExternalSymbols, - Name - ); - } - } else { - ASSERT (Context->Symtab != NULL); - Symbol = InternalGetLocalDefinedSymbolByNameWorker ( - Context, - SymbolTable, - Context->Symtab->NumSymbols, - Name - ); - } - - return Symbol; -} - -/** - Relocate Symbol to be against LinkAddress. - - @param[in,out] Context Context of the Mach-O. - @param[in] LinkAddress The address to be linked against. - @param[in,out] Symbol The symbol to be relocated. - - @returns Whether the operation has been completed successfully. - -**/ -BOOLEAN -MachoRelocateSymbol64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN UINT64 LinkAddress, - IN OUT MACH_NLIST_64 *Symbol - ) -{ - CONST MACH_SECTION_64 *Section; - UINT64 Value; - BOOLEAN Result; - - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - - // - // Symbols are relocated when they describe sections. - // - if (MachoSymbolIsSection (Symbol)) { - Section = MachoGetSectionByIndex64 (Context, (Symbol->Section - 1)); - if (Section == NULL) { - return FALSE; - } - - Value = ALIGN_VALUE ( - (Section->Address + LinkAddress), - (1ULL << Section->Alignment) - ); - Value -= Section->Address; - // - // The overflow arithmetic functions are not used as an overflow within the - // ALIGN_VALUE addition and a subsequent "underflow" of the section address - // subtraction is valid, hence just verify whether the final result - // overflew. - // - if (Value < LinkAddress) { - return FALSE; - } - - Result = OcOverflowAddU64 (Symbol->Value, Value, &Value); - if (Result) { - return FALSE; - } - - Symbol->Value = Value; - } - - return TRUE; -} - -/** - Retrieves the Mach-O file offset of the address pointed to by Symbol. - - @param[in,ouz] Context Context of the Mach-O. - @param[in] Symbol Symbol to retrieve the offset of. - @param[out] FileOffset Pointer the file offset is returned into. - If FALSE is returned, the output is undefined. - @param[out] MaxSize Maximum data safely available from FileOffset. - - @retval 0 0 is returned on failure. - -**/ -BOOLEAN -MachoSymbolGetFileOffset64 ( - IN OUT OC_MACHO_CONTEXT *Context, - IN CONST MACH_NLIST_64 *Symbol, - OUT UINT32 *FileOffset, - OUT UINT32 *MaxSize OPTIONAL - ) -{ - UINT64 Offset; - UINT64 Base; - UINT64 Size; - MACH_SEGMENT_COMMAND_64 *Segment; - MACH_SECTION_64 *Section; - - ASSERT (Context != NULL); - ASSERT (Symbol != NULL); - ASSERT (FileOffset != NULL); - - if (Symbol->Section == NO_SECT) { - return FALSE; - } - - Section = MachoGetSectionByIndex64 ( - Context, - (Symbol->Section - 1) - ); - if (Section == NULL || Section->Size == 0) { - for ( - Segment = MachoGetNextSegment64 (Context, NULL); - Segment != NULL; - Segment = MachoGetNextSegment64 (Context, Segment) - ) { - if ((Symbol->Value >= Segment->VirtualAddress) - && (Symbol->Value < (Segment->VirtualAddress + Segment->Size))) { - break; - } - } - - if (Segment == NULL) { - return FALSE; - } - - Offset = Symbol->Value - Segment->VirtualAddress; - Base = Segment->FileOffset; - Size = Segment->Size; - } else { - if (Symbol->Value < Section->Address) { - return FALSE; - } - - Offset = Symbol->Value - Section->Address; - Base = Section->Offset; - Size = Section->Size; - if (Offset > Section->Size) { - return FALSE; - } - } - - *FileOffset = (UINT32) (Base - Context->ContainerOffset + Offset); - - if (MaxSize != NULL) { - *MaxSize = (UINT32) (Size - Offset); - } - - return TRUE; -} diff --git a/Library/OcAfterBootCompatLib/BootCompatInternal.h b/Library/OcAfterBootCompatLib/BootCompatInternal.h deleted file mode 100644 index a87e209d1..000000000 --- a/Library/OcAfterBootCompatLib/BootCompatInternal.h +++ /dev/null @@ -1,526 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef BOOT_COMPAT_INTERNAL_H -#define BOOT_COMPAT_INTERNAL_H - -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#if defined(MDE_CPU_X64) -#include "X64/ContextSwitch.h" -#elif defined(MDE_CPU_IA32) -#include -#else -#error "Unsupported architecture!" -#endif - -// -// The kernel is normally allocated at base 0x100000 + slide address. -// -// For slide=0x1~0x7F the kernel is allocated from -// 0x100000 + 0x200000 till 0x100000 + 0xFE00000. -// -// For slide = 0x80~0xFF on Sandy Bridge or Ivy Bridge CPUs from -// 0x100000 + 0x20200000 till 0x100000? + 0x30000000??. -// -// For slide = 0x80~0xFF on Other CPUs from -// 0x100000 + 0x10000000 till 0x100000 + 0x1FE00000. -// - -/** - Maximum number of supported runtime reloc protection areas. - Currently hardocded for simplicity. -**/ -#define RT_RELOC_PROTECT_MAX_NUM ((UINTN) 64) - -/** - Runtime descriptor number to virtualise. - Currently hardocded for simplicity. -**/ -#define RT_DESC_ENTRY_NUM ((UINTN) 64) - -/** - Kernel __HIB segment virtual address. -**/ -#define KERNEL_HIB_VADDR ((UINTN) (0xFFFFFF8000100000ULL & MAX_UINTN)) - -/** - Kernel __TEXT segment virtual address. -**/ -#define KERNEL_TEXT_VADDR ((UINTN) (0xFFFFFF8000200000ULL & MAX_UINTN)) - -/** - Kernel physical base address. -**/ -#define KERNEL_BASE_PADDR (KERNEL_TEXT_VADDR - KERNEL_HIB_VADDR) - -/** - Slide offset per slide entry -**/ -#define SLIDE_GRANULARITY ((UINTN) SIZE_2MB) - -/** - Total possible number of KASLR slide offsets. -**/ -#define TOTAL_SLIDE_NUM ((UINTN) 0x100) - -/** - Slide errate number to skip range from. -**/ -#define SLIDE_ERRATA_NUM ((UINTN) 0x80) - -/** - Sandy/Ivy skip slide range for Intel HD graphics. -**/ -#define SLIDE_ERRATA_SKIP_RANGE ((UINTN) 0x10200000) - -/** - Assume the kernel is roughly 128 MBs. -**/ -#define ESTIMATED_KERNEL_SIZE ((UINTN) SIZE_128MB) - -/** - Preserved relocation entry. -**/ -typedef struct RT_RELOC_PROTECT_INFO_ { - /// - /// Physical address of descriptor start. - /// - EFI_PHYSICAL_ADDRESS PhysicalStart; - /// - /// Physical address of descriptor end. - /// - EFI_PHYSICAL_ADDRESS PhysicalEnd; - /// - /// Descriptor original memory type. - /// - EFI_MEMORY_TYPE Type; -} RT_RELOC_PROTECT_INFO; - -/** - Preserved relocation entry list. -**/ -typedef struct RT_RELOC_PROTECT_DATA_ { - /// - /// Number of currently used methods in the table. - /// - UINTN NumEntries; - /// - /// Reloc entries fitted. - /// - RT_RELOC_PROTECT_INFO RelocInfo[RT_RELOC_PROTECT_MAX_NUM]; -} RT_RELOC_PROTECT_DATA; - -/** - UEFI Boot & Runtime Services original pointers. -**/ -typedef struct UEFI_SERVICES_POINTERS_ { - /// - /// Original page allocator. We override it to obtain - /// the location macOS kernel and hibernation images. - /// - EFI_ALLOCATE_PAGES AllocatePages; - /// - /// Original page deallocator. We override it to fix memory - /// attributes table as it is updated after page dealloc. - /// - EFI_FREE_PAGES FreePages; - /// - /// Original memory map function. We override it to make - /// memory map shrinking and CSM region protection. - /// - EFI_GET_MEMORY_MAP GetMemoryMap; - /// - /// Original pool allocator. We override it to fix memory - /// attributes table as it is updated after pool alloc. - /// - EFI_ALLOCATE_POOL AllocatePool; - /// - /// Original pool deallocator. We override it to fix memory - /// attributes table as it is updated after pool dealloc. - /// - EFI_FREE_POOL FreePool; - /// - /// Original exit boot services function. We override it - /// to ensure we always succeed exiting boot services. - /// - EFI_EXIT_BOOT_SERVICES ExitBootServices; - /// - /// Image starting routine. We override to catch boot.efi - /// loading and enable the rest of functions. - /// - EFI_IMAGE_START StartImage; - /// - /// Original get variable function. We override it to alter - /// boot.efi boot arguments for custom KASLR slide. - /// - EFI_GET_VARIABLE GetVariable; - /// - /// Original virtual address mapping function. We override - /// it to perform runtime area protection to prevent boot.efi - /// defragmentation and setup virtual memory for firmwares - /// accessing it after exit boot services. - /// - EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; -} UEFI_SERVICES_POINTERS; - -/** - UEFI services override internal state. -**/ -typedef struct SERVICES_OVERRIDE_STATE_ { - /// - /// GetVariable arrival event. - /// - EFI_EVENT GetVariableEvent; - /// - /// Firmware runtime protocol instance. - /// - OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; - /// - /// Minimum address allocated by AlocatePages. - /// - EFI_PHYSICAL_ADDRESS MinAllocatedAddr; - /// - /// Apple hibernate image address allocated by AlocatePages. - /// - EFI_PHYSICAL_ADDRESS HibernateImageAddress; - /// - /// Last descriptor size obtained from GetMemoryMap. - /// - UINTN MemoryMapDescriptorSize; - /// - /// Amount of nested boot.efi detected. - /// - UINTN AppleBootNestedCount; - /// - /// TRUE if we are doing boot.efi hibernate wake. - /// - BOOLEAN AppleHibernateWake; - /// - /// TRUE if we are using custom KASLR slide (via boot arg). - /// - BOOLEAN AppleCustomSlide; - /// - /// TRUE if we are done reporting MMIO cleanup. - /// - BOOLEAN ReportedMmio; - /// - /// TRUE if we are waiting for performance memory allocation. - /// - BOOLEAN AwaitingPerfAlloc; -} SERVICES_OVERRIDE_STATE; - -/** - Apple kernel support internal state.. -**/ -typedef struct KERNEL_SUPPORT_STATE_ { - /// - /// Assembly support internal state. - /// - ASM_SUPPORT_STATE AsmState; - /// - /// Kernel jump trampoline. - /// - ASM_KERNEL_JUMP KernelJump; - /// - /// Original kernel memory. - /// - UINT8 KernelOrg[sizeof (ASM_KERNEL_JUMP)]; - /// - /// Custom kernel UEFI System Table. - /// - EFI_PHYSICAL_ADDRESS SysTableRtArea; - /// - /// Custom kernel UEFI System Table size in bytes. - /// - UINTN SysTableRtAreaSize; - /// - /// Physical configuration table location. - /// - EFI_CONFIGURATION_TABLE *ConfigurationTable; - /// - /// Virtual memory mapper context. - /// - OC_VMEM_CONTEXT VmContext; - /// - /// Virtual memory map containing partial memory map with runtime areas only. - /// Actual number of entries may be less than RT_DESC_ENTRY_NUM due to DescriptorSize - /// being potentially bigger than sizeof (EFI_MEMORY_DESCRIPTOR). - /// - EFI_MEMORY_DESCRIPTOR VmMap[RT_DESC_ENTRY_NUM]; - /// - /// Virtual memory map size in bytes. - /// - UINTN VmMapSize; - /// - /// Virtual memory map descriptor size in bytes. - /// - UINTN VmMapDescSize; -} KERNEL_SUPPORT_STATE; - -/** - Apple booter KASLR slide support internal state. -**/ -typedef struct SLIDE_SUPPORT_STATE_ { - /// - /// Memory map analysis status determining slide usage. - /// - BOOLEAN HasMemoryMapAnalysis; - /// - /// TRUE if we are running on Intel Sandy or Ivy bridge. - /// - BOOLEAN HasSandyOrIvy; - /// - /// TRUE if CsrActiveConfig was set. - /// - BOOLEAN HasCsrActiveConfig; - /// - /// TRUE if BootArgs was set. - /// - BOOLEAN HasBootArgs; - /// - /// Read or assumed csr-arctive-config variable value. - /// - UINT32 CsrActiveConfig; - /// - /// Max slide value provided. - /// - UINT8 ProvideMaxSlide; - /// - /// Valid slides to choose from when using custom slide. - /// - UINT8 ValidSlides[TOTAL_SLIDE_NUM]; - /// - /// Number of entries in ValidSlides. - /// - UINT32 ValidSlideCount; - /// - /// Apple kernel boot arguments read from boot-args variable and then - /// modified with an additional slide parameter in case custom slide is used. - /// - CHAR8 BootArgs[BOOT_LINE_LENGTH]; - /// - /// BootArgs data size. - /// - UINTN BootArgsSize; - /// - /// Estimated size for kernel itself, device tree, memory map, and rt pages. - /// - UINTN EstimatedKernelArea; -} SLIDE_SUPPORT_STATE; - -/** - Apple Boot Compatibility context. -**/ -typedef struct BOOT_COMPAT_CONTEXT_ { - /// - /// Apple Coot Compatibility settings. - /// - OC_ABC_SETTINGS Settings; - /// - /// Runtime relocations. - /// - RT_RELOC_PROTECT_DATA RtReloc; - /// - /// UEFI Boot & Runtime Services original pointers. - /// - UEFI_SERVICES_POINTERS ServicePtrs; - /// - /// UEFI services override internal state. - /// - SERVICES_OVERRIDE_STATE ServiceState; - /// - /// Apple kernel support internal state. - /// - KERNEL_SUPPORT_STATE KernelState; - /// - /// Apple booter KASLR slide support internal state. - /// - SLIDE_SUPPORT_STATE SlideSupport; -} BOOT_COMPAT_CONTEXT; - -/** - Obtain Apple Boot Compatibility context. This function must only - be called from wrapped services, where passing context arguments - is not possible. - - @retval Apple Boot Compatibility context (not null). -**/ -BOOT_COMPAT_CONTEXT * -GetBootCompatContext ( - VOID - ); - -/** - Install UEFI services overrides as necessary. - - @param[in,out] BootCompat Boot compatibility context. -**/ -VOID -InstallServiceOverrides ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat - ); - -/** - Prepare virtual memory management environment for later usage. - - @param[in,out] BootCompat Boot compatibility context. -**/ -VOID -AppleMapPrepareMemoryPool ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat - ); - -/** - Prepare environment for Apple UEFI bootloader. See more details inside. - - @param[in,out] BootCompat Boot compatibility context. - @param[in,out] LoadedImage UEFI loaded image protocol instance. - @param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional. -**/ -VOID -AppleMapPrepareBooterState ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN OUT EFI_LOADED_IMAGE *LoadedImage, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ); - -/** - Save UEFI environment state in implementation specific way. - - @param[in,out] AsmState Assembly state to update, can be preserved. - @param[out] KernelJump Kernel jump trampoline to fill. -**/ -VOID -AppleMapPlatformSaveState ( - IN OUT ASM_SUPPORT_STATE *AsmState, - OUT ASM_KERNEL_JUMP *KernelJump - ); - -/** - Patch kernel entry point with KernelJump to later land in AppleMapPrepareKernelState. - - @param[in,out] BootCompat Boot compatibility context. - @param[in] ImageAddress Kernel or hibernation image address. - @param[in] AppleHibernateWake TRUE when ImageAddress points to hibernation image. -**/ -VOID -AppleMapPrepareKernelJump ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN UINTN ImageAddress, - IN BOOLEAN AppleHibernateWake - ); - -/** - Prepare memory state and perform virtual address translation. - - @param[in,out] BootCompat Boot compatibility context. - @param[in] MemoryMapSize SetVirtualAddresses memory map size argument. - @param[in] DescriptorSize SetVirtualAddresses descriptor size argument. - @param[in] DescriptorVersion SetVirtualAddresses descriptor version argument. - @param[in] MemoryMap SetVirtualAddresses memory map argument. -**/ -EFI_STATUS -AppleMapPrepareMemState ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap - ); - -/** - Prepare environment for Apple kernel bootloader in boot or wake cases. - This callback arrives when boot.efi jumps to kernel. - - @param[in] Args Case-specific kernel argument handle. - @param[in] ModeX64 Debug flag about kernel context type, TRUE when X64. - - @retval Args must be returned with the necessary modifications if any. -**/ -UINTN -EFIAPI -AppleMapPrepareKernelState ( - IN UINTN Args, - IN BOOLEAN ModeX64 - ); - -/** - Patch boot.efi to support random and passed slide values in safe mode. - - @param[in,out] ImageBase Apple booter image base. - @param[in] ImageSize Apple booter image size. -**/ -VOID -AppleSlideUnlockForSafeMode ( - IN OUT UINT8 *ImageBase, - IN UINTN ImageSize - ); - -/** - Primary custom KASLR support handler. This gets called on every - UEFI RuntimeServices GetVariable call and thus is useful to - perform KASLR slide injection through boot-args. - - @param[in,out] BootCompat Boot compatibility context. - @param[in] GetVariable Original UEFI GetVariable service. - @param[in] GetMemoryMap Unmodified GetMemoryMap pointer, optional. - @param[in] FilterMap GetMemoryMap result filter, optional. - @param[in] FilterMapContext FilterMap context, optional. - @param[in] VariableName GetVariable variable name argument. - @param[in] VendorGuid GetVariable vendor GUID argument. - @param[out] Attributes GetVariable attributes argument. - @param[in,out] DataSize GetVariable data size argument. - @param[out] Data GetVariable data argument. - - @retval GetVariable status code. -**/ -EFI_STATUS -AppleSlideGetVariable ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN EFI_GET_VARIABLE GetVariable, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN OC_MEMORY_FILTER FilterMap OPTIONAL, - IN VOID *FilterMapContext OPTIONAL, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data - ); - -/** - Ensures that the original csr-active-config is passed to the kernel, - and removes customised slide value for security reasons. - - @param[in,out] BootCompat Boot compatibility context. - @param[in,out] BootArgs Apple kernel boot arguments. -**/ -VOID -AppleSlideRestore ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN OUT OC_BOOT_ARGUMENTS *BootArgs - ); - -#endif // BOOT_COMPAT_INTERNAL_H diff --git a/Library/OcAfterBootCompatLib/CustomSlide.c b/Library/OcAfterBootCompatLib/CustomSlide.c deleted file mode 100644 index 9d20a2491..000000000 --- a/Library/OcAfterBootCompatLib/CustomSlide.c +++ /dev/null @@ -1,821 +0,0 @@ -/** @file - Copyright (C) 2018, Downlod-Fritz. All rights reserved. - Copyright (C) 2018, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootCompatInternal.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Obtain estimated kernel area start and end addresses for - specified slide number. - - @param[in] EstimatedKernelArea Estimated kernel area size. - @param[in] HasSandyOrIvy CPU type. - @param[in] Slide Slide number. - @param[out] StartAddr Starting address. - @param[out] EndAddr Ending address (not inclusive). -**/ -STATIC -VOID -GetSlideRangeForValue ( - IN UINTN EstimatedKernelArea, - IN BOOLEAN HasSandyOrIvy, - IN UINT8 Slide, - OUT UINTN *StartAddr, - OUT UINTN *EndAddr - ) -{ - *StartAddr = Slide * SLIDE_GRANULARITY + KERNEL_BASE_PADDR; - - // - // Skip ranges used by Intel HD 2000/3000. - // - if (Slide >= SLIDE_ERRATA_NUM && HasSandyOrIvy) { - *StartAddr += SLIDE_ERRATA_SKIP_RANGE; - } - - *EndAddr = *StartAddr + EstimatedKernelArea; -} - -/** - Generate more or less random slide value. - - @param[in] SlideSupport Slide support state. -**/ -STATIC -UINT8 -GenerateSlideValue ( - IN SLIDE_SUPPORT_STATE *SlideSupport - ) -{ - UINT32 Slide; - - // - // Handle 0 slide case. - // - if (SlideSupport->ValidSlideCount == 1) { - return SlideSupport->ValidSlides[0]; - } - - do { - DivU64x32Remainder (GetPseudoRandomNumber64 (), SlideSupport->ValidSlideCount, &Slide); - } while (SlideSupport->ValidSlides[Slide] == 0); - - return SlideSupport->ValidSlides[Slide]; -} - -/** - Decide on whether to use custom slide based on memory map analysis. - This additionally logs the decision through standard services. - - @param[in,out] SlideSupport Slide support state. - @param[in] FallbackSlide Fallback slide number with largest area. - @param[in] MaxAvailableSize Maximum available contiguous area. - - @retval TRUE in case custom slide is to be used. -**/ -STATIC -BOOLEAN -ShouldUseCustomSlideOffsetDecision ( - IN OUT SLIDE_SUPPORT_STATE *SlideSupport, - IN UINT8 FallbackSlide, - IN UINT64 MaxAvailableSize - ) -{ - UINTN Index; - UINTN NumEntries; - CHAR8 SlideList[256]; - CHAR8 Temp[32]; - - // - // All slides are available. - // - if (SlideSupport->ValidSlideCount == TOTAL_SLIDE_NUM) { - DEBUG (( - DEBUG_INFO, - "OCABC: All slides are usable! You can disable ProvideCustomSlide!\n" - )); - return FALSE; - } - - // - // No slides are available, fallback to largest. - // - if (SlideSupport->ValidSlideCount == 0) { - DEBUG (( - DEBUG_INFO, - "OCABC: No slide values are usable! Falling back to %u with 0x%08LX bytes!\n", - (UINT32) FallbackSlide, - MaxAvailableSize - )); - SlideSupport->ValidSlides[SlideSupport->ValidSlideCount++] = (UINT8) FallbackSlide; - return TRUE; - } - - // - // Not all slides are available and thus we have to pass a custom slide - // value through boot-args to boot reliably. - // - // Pretty-print valid slides as ranges. - // For example, 1, 2, 3, 4, 5 will become 1-5. - // - DEBUG (( - DEBUG_INFO, - "OCABC: Only %u/%u slide values are usable!\n", - (UINT32) SlideSupport->ValidSlideCount, - (UINT32) TOTAL_SLIDE_NUM - )); - - SlideList[0] = '\0'; - - NumEntries = 0; - for (Index = 0; Index <= SlideSupport->ValidSlideCount; ++Index) { - if (Index == 0) { - AsciiSPrint ( - Temp, - sizeof (Temp), - "Valid slides - %d", - SlideSupport->ValidSlides[Index] - ); - AsciiStrCatS (SlideList, sizeof (SlideList), Temp); - } else if (Index == SlideSupport->ValidSlideCount - || SlideSupport->ValidSlides[Index - 1] + 1 != SlideSupport->ValidSlides[Index]) { - - if (NumEntries == 1) { - AsciiSPrint ( - Temp, - sizeof (Temp), - ", %d", - SlideSupport->ValidSlides[Index - 1] - ); - AsciiStrCatS (SlideList, sizeof (SlideList), Temp); - } else if (NumEntries > 1) { - AsciiSPrint ( - Temp, - sizeof (Temp), - "-%d", - SlideSupport->ValidSlides[Index - 1] - ); - AsciiStrCatS (SlideList, sizeof (SlideList), Temp); - } - - if (Index != SlideSupport->ValidSlideCount) { - AsciiSPrint ( - Temp, - sizeof (Temp), - ", %d", - SlideSupport->ValidSlides[Index] - ); - AsciiStrCatS (SlideList, sizeof (SlideList), Temp); - } - - NumEntries = 0; - } else { - NumEntries++; - } - } - - DEBUG ((DEBUG_INFO, "OCABC: %a\n", SlideList)); - - return TRUE; -} - -/** - Return cached decision or perform memory map analysis to decide - whether to use custom slide for reliable kernel booting or not. - - @param[in,out] SlideSupport Slide support state. - @param[in] GetMemoryMap Function to get current memory map for analysis. optional. - @param[in] FilterMap Function to filter returned memory map, optional. - @param[in] FilterMapContext Filter map context, optional. - - @retval TRUE in case custom slide is to be used. -**/ -STATIC -BOOLEAN -ShouldUseCustomSlideOffset ( - IN OUT SLIDE_SUPPORT_STATE *SlideSupport, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN OC_MEMORY_FILTER FilterMap OPTIONAL, - IN VOID *FilterMapContext OPTIONAL - ) -{ - EFI_PHYSICAL_ADDRESS AllocatedMapPages; - UINTN MemoryMapSize = 0; - EFI_MEMORY_DESCRIPTOR *MemoryMap = NULL; - EFI_MEMORY_DESCRIPTOR *Desc; - UINTN MapKey = 0; - EFI_STATUS Status; - UINTN DescriptorSize = 0; - UINT32 DescriptorVersion = 0; - OC_CPU_GENERATION CpuGeneration; - UINTN Index; - UINTN Slide; - UINTN NumEntries; - UINT64 MaxAvailableSize; - UINT8 FallbackSlide; - BOOLEAN Supported; - UINTN StartAddr; - UINTN EndAddr; - EFI_PHYSICAL_ADDRESS DescEndAddr; - UINT64 AvailableSize; - - MaxAvailableSize = 0; - FallbackSlide = 0; - - if (SlideSupport->HasMemoryMapAnalysis) { - return SlideSupport->ValidSlideCount > 0 - && SlideSupport->ValidSlideCount < TOTAL_SLIDE_NUM; - } - - AllocatedMapPages = BASE_4GB; - Status = OcGetCurrentMemoryMapAlloc ( - &MemoryMapSize, - &MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion, - GetMemoryMap, - &AllocatedMapPages - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCABC: Failed to obtain memory map for KASLR - %r\n", Status)); - return FALSE; - } - - if (FilterMap != NULL) { - FilterMap (FilterMapContext, MemoryMapSize, MemoryMap, DescriptorSize); - } - - CpuGeneration = OcCpuGetGeneration (); - SlideSupport->HasSandyOrIvy = CpuGeneration == OcCpuGenerationSandyBridge || - CpuGeneration == OcCpuGenerationIvyBridge; - - SlideSupport->EstimatedKernelArea = (UINTN) EFI_PAGES_TO_SIZE ( - OcCountRuntimePages (MemoryMapSize, MemoryMap, DescriptorSize, NULL) - ) + ESTIMATED_KERNEL_SIZE; - - // - // At this point we have a memory map that we could use to - // determine what slide values are allowed. - // - NumEntries = MemoryMapSize / DescriptorSize; - - // - // Reset valid slides to zero and find actually working ones. - // - SlideSupport->ValidSlideCount = 0; - - for (Slide = 0; Slide < TOTAL_SLIDE_NUM; ++Slide) { - Desc = MemoryMap; - Supported = TRUE; - - GetSlideRangeForValue ( - SlideSupport->EstimatedKernelArea, - SlideSupport->HasSandyOrIvy, - (UINT8) Slide, - &StartAddr, - &EndAddr - ); - - AvailableSize = 0; - - for (Index = 0; Index < NumEntries; ++Index) { - if (Desc->NumberOfPages == 0) { - continue; - } - - DescEndAddr = LAST_DESCRIPTOR_ADDR (Desc) + 1; - - if ((Desc->PhysicalStart < EndAddr) && (DescEndAddr > StartAddr)) { - // - // The memory overlaps with the slide region. - // - if (Desc->Type != EfiConventionalMemory) { - // - // The memory is unusable atm. - // - Supported = FALSE; - break; - } else { - // - // The memory will be available for the kernel. - // - AvailableSize += EFI_PAGES_TO_SIZE (Desc->NumberOfPages); - - if (Desc->PhysicalStart < StartAddr) { - // - // The region starts before the slide region. - // Subtract the memory that is located before the slide region. - // - AvailableSize -= (StartAddr - Desc->PhysicalStart); - } - - if (DescEndAddr > EndAddr) { - // - // The region ends after the slide region. - // Subtract the memory that is located after the slide region. - // - AvailableSize -= (DescEndAddr - EndAddr); - } - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - if (AvailableSize > MaxAvailableSize) { - MaxAvailableSize = AvailableSize; - FallbackSlide = (UINT8) Slide; - } - - // - // Stop evalutating slides after exceeding ProvideMaxSlide, may break when - // no slides are available. - // - if (SlideSupport->ProvideMaxSlide > 0 && Slide > SlideSupport->ProvideMaxSlide) { - break; - } - - if ((StartAddr + AvailableSize) != EndAddr) { - // - // The slide region is not continuous. - // - Supported = FALSE; - } - - if (Supported) { - SlideSupport->ValidSlides[SlideSupport->ValidSlideCount++] = (UINT8) Slide; - } - } - - // - // Okay, we are done. - // - - SlideSupport->HasMemoryMapAnalysis = TRUE; - - gBS->FreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN) MemoryMap, - (UINTN) AllocatedMapPages - ); - - return ShouldUseCustomSlideOffsetDecision ( - SlideSupport, - FallbackSlide, - MaxAvailableSize - ); -} - -/** - UEFI GetVariable override specific to csr-active-config. - See caller for more details. - - @param[in,out] SlideSupport Slide support state. - @param[in] GetVariable Original UEFI GetVariable service. - @param[in] VariableName GetVariable variable name argument. - @param[in] VendorGuid GetVariable vendor GUID argument. - @param[out] Attributes GetVariable attributes argument. - @param[in,out] DataSize GetVariable data size argument. - @param[out] Data GetVariable data argument. - - @retval GetVariable status code. -**/ -STATIC -EFI_STATUS -GetVariableCsrActiveConfig ( - IN OUT SLIDE_SUPPORT_STATE *SlideSupport, - IN EFI_GET_VARIABLE GetVariable, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data - ) -{ - EFI_STATUS Status; - UINT32 *Config; - - // - // If we were asked for the size, just return it right away. - // - if (Data == NULL || *DataSize < sizeof (UINT32)) { - *DataSize = sizeof (UINT32); - return EFI_BUFFER_TOO_SMALL; - } - - Config = (UINT32 *) Data; - - // - // Otherwise call the original function. - // - Status = GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCABC: GetVariable csr-active-config - %r\n", Status)); - - *Config = 0; - Status = EFI_SUCCESS; - if (Attributes != NULL) { - *Attributes = - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_NON_VOLATILE; - } - } - - // - // We must unrestrict NVRAM from SIP or slide=X will not be supported. - // - SlideSupport->CsrActiveConfig = *Config; - SlideSupport->HasCsrActiveConfig = TRUE; - *Config |= CSR_ALLOW_UNRESTRICTED_NVRAM; - - return Status; -} - -/** - UEFI GetVariable override specific to boot-args. - See caller for more details. - - @param[in,out] SlideSupport Slide support state. - @param[in] GetVariable Original UEFI GetVariable service. - @param[in] VariableName GetVariable variable name argument. - @param[in] VendorGuid GetVariable vendor GUID argument. - @param[out] Attributes GetVariable attributes argument. - @param[in,out] DataSize GetVariable data size argument. - @param[out] Data GetVariable data argument. - - @retval GetVariable status code. -**/ -STATIC -EFI_STATUS -GetVariableBootArgs ( - IN OUT SLIDE_SUPPORT_STATE *SlideSupport, - IN EFI_GET_VARIABLE GetVariable, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data - ) -{ - EFI_STATUS Status; - UINTN StoredBootArgsSize; - UINT8 Slide; - CHAR8 SlideArgument[10]; - UINTN SlideArgumentLength; - - StoredBootArgsSize = BOOT_LINE_LENGTH; - SlideArgumentLength = ARRAY_SIZE (SlideArgument) - 1; - - if (!SlideSupport->HasBootArgs) { - Slide = GenerateSlideValue (SlideSupport); - - // - // boot-args normally arrives non-null terminated. - // - Status = GetVariable ( - VariableName, - VendorGuid, - Attributes, - &StoredBootArgsSize, - SlideSupport->BootArgs - ); - if (EFI_ERROR(Status)) { - SlideSupport->BootArgs[0] = '\0'; - } - - // - // Note, the point is to always pass 3 characters to avoid side attacks on value length. - // boot.efi always reads in decimal, so 008 and 8 are equivalent. - // - AsciiSPrint (SlideArgument, ARRAY_SIZE (SlideArgument), "slide=%-03d", Slide); - - if (!OcAppendArgumentToCmd (NULL, SlideSupport->BootArgs, SlideArgument, SlideArgumentLength)) { - // - // Broken boot-args, try to overwrite. - // - AsciiStrnCpyS ( - SlideSupport->BootArgs, - SlideArgumentLength + 1, - SlideArgument, - SlideArgumentLength + 1 - ); - } - - SlideSupport->BootArgsSize = AsciiStrLen (SlideSupport->BootArgs); - SlideSupport->HasBootArgs = TRUE; - } - - if (Attributes) { - *Attributes = - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_NON_VOLATILE; - } - - if (*DataSize >= SlideSupport->BootArgsSize && Data != NULL) { - CopyMem ( - Data, - SlideSupport->BootArgs, - SlideSupport->BootArgsSize - ); - Status = EFI_SUCCESS; - } else { - Status = EFI_BUFFER_TOO_SMALL; - } - - *DataSize = SlideSupport->BootArgsSize; - - return Status; -} - -/** - Erases customised slide value from everywhere accessible - for security purposes. - - @param[in,out] SlideSupport Slide support state. - @param[in,out] BootArgs Apple kernel boot arguments. -**/ -STATIC -VOID -HideSlideFromOs ( - IN OUT SLIDE_SUPPORT_STATE *SlideSupport, - IN OUT OC_BOOT_ARGUMENTS *BootArgs - ) -{ - EFI_STATUS Status; - DTEntry Chosen = 0; - CHAR8 *ArgsStr = NULL; - UINT32 ArgsSize = 0; - - // - // First, there is a BootArgs entry for XNU. - // - OcRemoveArgumentFromCmd (BootArgs->CommandLine, "slide="); - - // - // Second, there is a DT entry. - // - DTInit ((VOID *)(UINTN) (*BootArgs->DeviceTreeP), BootArgs->DeviceTreeLength); - Status = DTLookupEntry (NULL, "/chosen", &Chosen); - if (!EFI_ERROR(Status)) { - Status = DTGetProperty (Chosen, "boot-args", (VOID **)&ArgsStr, &ArgsSize); - if (!EFI_ERROR(Status) && ArgsSize > 0) { - OcRemoveArgumentFromCmd (ArgsStr, "slide="); - } - } - - // - // Third, clean the boot args just in case. - // - SlideSupport->ValidSlideCount = 0; - SlideSupport->BootArgsSize = 0; - SecureZeroMem (SlideSupport->ValidSlides, sizeof (SlideSupport->ValidSlides)); - SecureZeroMem (SlideSupport->BootArgs, sizeof (SlideSupport->BootArgs)); -} - -VOID -AppleSlideUnlockForSafeMode ( - IN OUT UINT8 *ImageBase, - IN UINTN ImageSize - ) -{ - // - // boot.efi performs the following check: - // if (State & (BOOT_MODE_SAFE | BOOT_MODE_ASLR)) == (BOOT_MODE_SAFE | BOOT_MODE_ASLR)) { - // * Disable KASLR * - // } - // We do not care about the asm it will use for it, but we could assume that the constants - // will be used twice and their location will be very close to each other. - // - // BOOT_MODE_SAFE | BOOT_MODE_ASLR constant is 0x4001 in hex. - // It has not changed since its appearance, so is most likely safe to look for. - // Furthermore, since boot.efi state mask uses higher bits, it is safe to assume that - // the comparison will be at least 32-bit. - // - // - // The new way patch is a workaround for 10.13.5 and newer, where the code got finally changed. - // if (State & BOOT_MODE_SAFE) { - // ReportFeature(FEATURE_BOOT_MODE_SAFE); - // if (State & BOOT_MODE_ASLR) { - // * Disable KASLR * - // } - // } - // - - // - // This is a reasonable maximum distance to expect between the instructions. - // - STATIC CONST UINTN MaxDist = 0x10; - STATIC CONST UINT8 SearchSeqNew[] = {0xF6, 0xC4, 0x40, 0x75}; - STATIC CONST UINT8 SearchSeqNew2[] = {0x0F, 0xBA, 0xE0, 0x0E, 0x72}; - STATIC CONST UINT8 SearchSeq[] = {0x01, 0x40, 0x00, 0x00}; - - UINT8 *StartOff; - UINT8 *EndOff; - UINTN FirstOff; - UINTN SecondOff; - UINTN SearchSeqNewSize; - BOOLEAN NewWay; - - - StartOff = ImageBase; - EndOff = StartOff + ImageSize - sizeof (SearchSeq) - MaxDist; - - FirstOff = 0; - SecondOff = 0; - NewWay = FALSE; - - do { - while (StartOff + FirstOff <= EndOff) { - if (StartOff + FirstOff <= EndOff - 1 - && CompareMem (StartOff + FirstOff, SearchSeqNew2, sizeof (SearchSeqNew2)) == 0) { - SearchSeqNewSize = sizeof (SearchSeqNew2); - NewWay = TRUE; - break; - } else if (CompareMem (StartOff + FirstOff, SearchSeqNew, sizeof (SearchSeqNew)) == 0) { - SearchSeqNewSize = sizeof (SearchSeqNew); - NewWay = TRUE; - break; - } else if (CompareMem (StartOff + FirstOff, SearchSeq, sizeof (SearchSeq)) == 0) { - break; - } - FirstOff++; - } - - DEBUG (( - DEBUG_VERBOSE, - "OCABC: Found first %d at off %X\n", - (UINT32) NewWay, - (UINT32) FirstOff - )); - - if (StartOff + FirstOff > EndOff) { - DEBUG (( - DEBUG_INFO, - "OCABC: Failed to find first BOOT_MODE_SAFE | BOOT_MODE_ASLR sequence\n" - )); - break; - } - - if (NewWay) { - // - // Here we just patch the comparison code and the check by straight nopping. - // - DEBUG ((DEBUG_VERBOSE, "OCABC: Patching new safe mode aslr check...\n")); - SetMem (StartOff + FirstOff, SearchSeqNewSize + 1, 0x90); - return; - } - - SecondOff = FirstOff + sizeof (SearchSeq); - - while ( - StartOff + SecondOff <= EndOff && FirstOff + MaxDist >= SecondOff && - CompareMem (StartOff + SecondOff, SearchSeq, sizeof (SearchSeq))) { - SecondOff++; - } - - DEBUG ((DEBUG_VERBOSE, "OCABC: Found second at off %X\n", (UINT32) SecondOff)); - - if (FirstOff + MaxDist < SecondOff) { - DEBUG ((DEBUG_VERBOSE, "OCABC: Trying next match...\n")); - SecondOff = 0; - FirstOff += sizeof (SearchSeq); - } - } while (SecondOff == 0); - - if (SecondOff != 0) { - // - // Here we use 0xFFFFFFFF constant as a replacement value. - // Since the state values are contradictive (e.g. safe & single at the same time) - // We are allowed to use this instead of to simulate if (false). - // - DEBUG ((DEBUG_VERBOSE, "OCABC: Patching safe mode aslr check...\n")); - SetMem (StartOff + FirstOff, sizeof (SearchSeq), 0xFF); - SetMem (StartOff + SecondOff, sizeof (SearchSeq), 0xFF); - } -} - -EFI_STATUS -AppleSlideGetVariable ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN EFI_GET_VARIABLE GetVariable, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN OC_MEMORY_FILTER FilterMap OPTIONAL, - IN VOID *FilterMapContext OPTIONAL, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data - ) -{ - BootCompat->SlideSupport.ProvideMaxSlide = BootCompat->Settings.ProvideMaxSlide; - - if (VariableName != NULL && VendorGuid != NULL && DataSize != NULL - && CompareGuid (VendorGuid, &gEfiAppleBootGuid)) { - - if (StrCmp (VariableName, L"csr-active-config") == 0) { - // - // We override csr-active-config with CSR_ALLOW_UNRESTRICTED_NVRAM bit set - // to allow one to pass a custom slide value even when SIP is on. - // This original value of csr-active-config is returned to OS at XNU boot. - // This allows SIP to be fully enabled in the operating system. - // - return GetVariableCsrActiveConfig ( - &BootCompat->SlideSupport, - GetVariable, - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - } else if (StrCmp (VariableName, L"boot-args") == 0 - && !BootCompat->ServiceState.AppleCustomSlide - && ShouldUseCustomSlideOffset (&BootCompat->SlideSupport, GetMemoryMap, FilterMap, FilterMapContext)) { - // - // When we cannot allow some KASLR values due to used address we generate - // a random slide value among the valid options, which we we pass via boot-args. - // See ShouldUseCustomSlideOffset for more details. - // - // We delay memory map analysis as much as we can, in case boot.efi or anything else allocates - // stuff with gBS->AllocatePool and it overlaps with the kernel area. - // Overriding AllocatePool with a custom allocator does not really improve the situation, - // because on older boards allocated memory above BASE_4GB causes instant reboots, and - // on the only (so far) problematic X99 and X299 we have no free region for our pool anyway. - // In any case, the current APTIOFIX_SPECULATED_KERNEL_SIZE value appears to work reliably. - // - return GetVariableBootArgs ( - &BootCompat->SlideSupport, - GetVariable, - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - } - } - - return GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data); -} - -VOID -AppleSlideRestore ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN OUT OC_BOOT_ARGUMENTS *BootArgs - ) -{ - SLIDE_SUPPORT_STATE *SlideSupport; - - SlideSupport = &BootCompat->SlideSupport; - - // - // Restore csr-active-config to a value it was before our slide=X alteration. - // - if (BootArgs->CsrActiveConfig != NULL && SlideSupport->HasCsrActiveConfig) { - *BootArgs->CsrActiveConfig = SlideSupport->CsrActiveConfig; - } - - // - // Having slide=X values visible in the operating system defeats the purpose of KASLR. - // Since our custom implementation works by passing random KASLR slide via boot-args, - // this is especially important. - // - HideSlideFromOs (SlideSupport, BootArgs); -} diff --git a/Library/OcAfterBootCompatLib/Ia32/ContextSwitch.h b/Library/OcAfterBootCompatLib/Ia32/ContextSwitch.h deleted file mode 100644 index 486bbba1b..000000000 --- a/Library/OcAfterBootCompatLib/Ia32/ContextSwitch.h +++ /dev/null @@ -1,49 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef CONTEXT_SWITCH_H -#define CONTEXT_SWITCH_H - -// -// Structure definitions shared with ASM code. -// Keep these definitions in sync with ContextSwitch.nasm! -// - -#pragma pack(push, 1) - -/** - Assembly support state. - This state is used as an intermediate structure to hold UEFI environment - context and kernel environment context for switching between 32-bit - and 64-bit modes during booting as normal XNU boot still happens in 32-bit. -**/ -typedef PACKED struct ASM_SUPPORT_STATE_ { - VOID *KernelEntry; -} ASM_SUPPORT_STATE; - -/** - Assembly kernel trampoline. - This structure contains encoded assembly to jump from kernel - code to UEFI code through AsmAppleMapPlatformPrepareKernelState - intermediate handler. -**/ -typedef PACKED struct ASM_KERNEL_JUMP_ { - UINT8 MovInst; - UINT32 Addr; - UINT16 CallInst; -} ASM_KERNEL_JUMP; - -#pragma pack(pop) - -#endif // CONTEXT_SWITCH_H diff --git a/Library/OcAfterBootCompatLib/Ia32/ContextSwitchSupport.c b/Library/OcAfterBootCompatLib/Ia32/ContextSwitchSupport.c deleted file mode 100644 index d2d68f4f5..000000000 --- a/Library/OcAfterBootCompatLib/Ia32/ContextSwitchSupport.c +++ /dev/null @@ -1,27 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "../BootCompatInternal.h" - -#include -#include - -VOID -AppleMapPlatformSaveState ( - IN OUT ASM_SUPPORT_STATE *AsmState, - OUT ASM_KERNEL_JUMP *KernelJump - ) -{ - CpuDeadLoop (); -} diff --git a/Library/OcAfterBootCompatLib/KernelSupport.c b/Library/OcAfterBootCompatLib/KernelSupport.c deleted file mode 100644 index 46a2c035d..000000000 --- a/Library/OcAfterBootCompatLib/KernelSupport.c +++ /dev/null @@ -1,753 +0,0 @@ -/** @file - Copyright (C) 2013, dmazar. All rights reserved. - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootCompatInternal.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Protect RT data from boot.efi relocation by marking them MemMapIO. - See more details in the function definition. - - @param[in,out] RtReloc Relocation entry list to store entry types. - @param[in] MemoryMapSize Memory map size. - @param[in] DescriptorSize Memory map descriptor size. - @param[in,out] MemoryMap MemoryMap to protect entries in. - @param[in] SysTableArea Special address that should not be protected. -**/ -STATIC -VOID -ProtectRtMemoryFromRelocation ( - IN OUT RT_RELOC_PROTECT_DATA *RtReloc, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN EFI_PHYSICAL_ADDRESS SysTableArea, - IN UINTN SysTableAreaSize - ) -{ - // - // We protect RT data & code from relocation by marking them MemMapIO except EFI_SYSTEM_TABLE area. - // - // This fixes NVRAM issues on some boards where access to NVRAM after boot services is possible - // only in SMM mode. RT driver passes data to SMM handler through previously negotiated buffer - // and this buffer must not be relocated. - // Explained and examined in detail by CodeRush and night199uk: - // https://web.archive.org/web/20141025080709/http://www.projectosx.com/forum/lofiversion/index.php/t3298.html - // - // Starting with APTIO V for NVRAM to work not only RT data but RT code too can no longer be moved - // due to the use of commbuffers. This, however, creates a memory protection issue, because - // XNU maps RT data as RW and code as RX, and AMI appears use global variables in some RT drivers. - // For this reason we shim (most?) affected RT services via wrapers that unset the WP bit during - // the UEFI call and set it back on return in a separate driver. - // Explained in detail by Download-Fritz and vit9696: - // http://www.insanelymac.com/forum/topic/331381-aptiomemoryfix (first 2 links in particular). - // - // EFI_SYSTEM_TABLE is passed directly through kernel boot arguments, and thus goes through static - // mapping (ml_static_ptovirt) in efi_set_tables_64 call. This mapping works as PHYS | CONST = VIRT. - // To avoid kernel accessing unmapped virtual address we let boot.efi relocate the page with - // EFI_SYSTEM_TABLE area. While technically it is possible to let the original page to be relocated, - // we pick a safer root by using a private copy. - // - // The primary downside of this approach is that boot.efi will still reserve the contiguous memory - // for runtime services after the kernel: efiRuntimeServicesPageCount pages starting from - // efiRuntimeServicesPageStart within kaddr ~ ksize range. However, unlike Macs, which have reserved - // gaps only for ACPI NVS, MemMapIO and similar regions, with this approach almost no physical memory - // in efiRuntimeServicesPageStart area is used at all. This memory is never reclaimed by XNU, which - // marks it as allocated in i386_vm_init. Expirements show that at least 85 MBs (Z170) are used for - // this process. On server systems the issue is much worse due to many devices in place. - // Ideally boot.efi should only count RT code and RT data pages, but it is not easy to change. - // - - UINTN NumEntries; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Desc; - RT_RELOC_PROTECT_INFO *RelocInfo; - - Desc = MemoryMap; - RtReloc->NumEntries = 0; - RelocInfo = &RtReloc->RelocInfo[0]; - NumEntries = MemoryMapSize / DescriptorSize; - - for (Index = 0; Index < NumEntries; ++Index) { - if ((Desc->Attribute & EFI_MEMORY_RUNTIME) != 0 - && Desc->NumberOfPages > 0 - && (Desc->Type == EfiRuntimeServicesCode || Desc->Type == EfiRuntimeServicesData) - && !AREA_WITHIN_DESCRIPTOR (Desc, SysTableArea, SysTableAreaSize)) { - - if (RtReloc->NumEntries == ARRAY_SIZE (RtReloc->RelocInfo)) { - RUNTIME_DEBUG (( - DEBUG_ERROR, - "OCABC: Cannot save mem type for entry: %Lx (type 0x%x)\n", - (UINT64) Desc->PhysicalStart, - (UINT32) Desc->Type - )); - return; - } - - RelocInfo->PhysicalStart = Desc->PhysicalStart; - RelocInfo->PhysicalEnd = LAST_DESCRIPTOR_ADDR (Desc); - RelocInfo->Type = Desc->Type; - Desc->Type = EfiMemoryMappedIO; - ++RelocInfo; - ++RtReloc->NumEntries; - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } -} - -/** - Copy RT flagged areas to separate memmap, define virtual to physical address mapping, - and call SetVirtualAddressMap() only with that partial memmap. - - @param[in,out] KernelState Kernel support state. - @param[in] MemoryMapSize Memory map size. - @param[in] DescriptorSize Memory map descriptor size. - @param[in] DescriptorVersion Memor map descriptor version. - @param[in,out] MemoryMap Complete memory map with all entries. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -PerformRtMemoryVirtualMapping ( - IN OUT KERNEL_SUPPORT_STATE *KernelState, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap - ) -{ - // - // About partial memmap: - // Some UEFIs are converting pointers to virtual addresses even if they do not - // point to regions with RT flag. This means that those UEFIs are using - // Desc->VirtualStart even for non-RT regions. Linux had issues with this: - // http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7cb00b72876ea2451eb79d468da0e8fb9134aa8a - // They are doing it Windows way now - copying RT descriptors to separate - // mem map and passing that stripped map to SetVirtualAddressMap(). - // We'll do the same, although it seems that just assigning - // VirtualStart = PhysicalStart for non-RT areas also does the job. - // - // About virtual to physical mappings: - // Also adds virtual to physical address mappings for RT areas. This is needed since - // SetVirtualAddressMap() does not work on my Aptio without that. Probably because some driver - // has a bug and is trying to access new virtual addresses during the change. - // Linux and Windows are doing the same thing and problem is - // not visible there. - // - - UINTN NumEntries; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Desc; - EFI_MEMORY_DESCRIPTOR *VirtualDesc; - EFI_STATUS Status; - PAGE_MAP_AND_DIRECTORY_POINTER *PageTable; - - Desc = MemoryMap; - NumEntries = MemoryMapSize / DescriptorSize; - VirtualDesc = KernelState->VmMap; - KernelState->VmMapSize = 0; - KernelState->VmMapDescSize = DescriptorSize; - - // - // Get current VM page table. - // - PageTable = OcGetCurrentPageTable (NULL); - - for (Index = 0; Index < NumEntries; ++Index) { - // - // Legacy note. Some UEFIs end up with "reserved" area with EFI_MEMORY_RUNTIME flag set when - // Intel HD3000 or HD4000 is used. For example, on GA-H81N-D2H there is a single 1 GB descriptor: - // 000000009F800000-00000000DF9FFFFF 0000000000040200 8000000000000000 - // - // All known boot.efi starting from at least 10.5.8 properly handle this flag and do not assign - // virtual addresses to reserved descriptors. However, our legacy code had a bug, and did not - // check for EfiReservedMemoryType. Therefore it replaced such entries by EfiMemoryMappedIO - // to "prevent" boot.efi relocations. - // - // The relevant discussion and the original fix can be found here: - // http://web.archive.org/web/20141111124211/http://www.projectosx.com:80/forum/lofiversion/index.php/t2428-450.html - // https://sourceforge.net/p/cloverefiboot/code/605/ - // - // The correct approach is to properly handle EfiReservedMemoryType with EFI_MEMORY_RUNTIME - // attribute set, and not mess with the memory map passed to boot.efi. As done here. - // - if (Desc->Type != EfiReservedMemoryType && (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0) { - // - // Check if there is enough space in virtual map. - // - if (KernelState->VmMapSize + DescriptorSize > sizeof (KernelState->VmMap)) { - RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: Too many RT entries to memory map\n")); - return EFI_OUT_OF_RESOURCES; - } - - // - // Copy region with EFI_MEMORY_RUNTIME flag to virtual map. - // - CopyMem (VirtualDesc, Desc, DescriptorSize); - - // - // Define virtual to physical mapping. - // - Status = VmMapVirtualPages ( - &KernelState->VmContext, - PageTable, - Desc->VirtualStart, - Desc->NumberOfPages, - Desc->PhysicalStart - ); - if (EFI_ERROR(Status)) { - RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: RT mapping failure - %r\n", Status)); - return EFI_OUT_OF_RESOURCES; - } - - // - // Proceed to next virtual map slot. - // - VirtualDesc = NEXT_MEMORY_DESCRIPTOR (VirtualDesc, DescriptorSize); - KernelState->VmMapSize += DescriptorSize; - } - - // - // Proceed to next original map slot. - // - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - VmFlushCaches (); - - Status = gRT->SetVirtualAddressMap ( - KernelState->VmMapSize, - DescriptorSize, - DescriptorVersion, - KernelState->VmMap - ); - - return Status; -} - -/** - Revert RT data protected types to let XNU kernel kernel properly map data. - - @param[in] RtReloc Relocated entry list with entry types. - @param[in] MemoryMapSize Memory map size. - @param[in] DescriptorSize Memory map descriptor size. - @param[in,out] MemoryMap MemoryMap to restore protected entries in. -**/ -STATIC -VOID -RestoreProtectedRtMemoryTypes ( - IN RT_RELOC_PROTECT_DATA *RtReloc, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap - ) -{ - UINTN Index; - UINTN Index2; - UINTN NumEntriesLeft; - UINTN NumEntries; - EFI_PHYSICAL_ADDRESS PhysicalStart; - EFI_PHYSICAL_ADDRESS PhysicalEnd; - EFI_MEMORY_DESCRIPTOR *Desc; - - NumEntriesLeft = RtReloc->NumEntries; - NumEntries = MemoryMapSize / DescriptorSize; - Desc = MemoryMap; - - for (Index = 0; Index < NumEntries && NumEntriesLeft > 0; ++Index) { - PhysicalStart = Desc->PhysicalStart; - PhysicalEnd = LAST_DESCRIPTOR_ADDR (Desc); - - for (Index2 = 0; Index2 < RtReloc->NumEntries; ++Index2) { - // - // PhysicalStart match is enough, but just in case. - // Select firmwares, like Lenovo ThinkPad X240, have insane reserved areas. - // For example 0000000000000000-FFFFFFFFFFFFFFFF 0000000000000000 0000000000000000. - // Any fuzzy matching is prone to errors, so just do exact comparison. - // - if (PhysicalStart == RtReloc->RelocInfo[Index2].PhysicalStart - && PhysicalEnd == RtReloc->RelocInfo[Index2].PhysicalEnd) { - Desc->Type = RtReloc->RelocInfo[Index2].Type; - --NumEntriesLeft; - break; - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - if (NumEntriesLeft > 0) { - RUNTIME_DEBUG (( - DEBUG_ERROR, - "OCABC: Failed to restore %u entries out of %u\n", - (UINT32) NumEntriesLeft, - (UINT32) RtReloc->NumEntries - )); - } -} - -/** - Prepare environment for normal booting. Called when boot.efi jumps to kernel. - - @param[in,out] BootCompat Boot compatibility context. - @param[in,out] BootArgs Apple kernel boot arguments. -**/ -STATIC -VOID -AppleMapPrepareForBooting ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN OUT VOID *BootArgs - ) -{ - EFI_STATUS Status; - DTEntry Chosen; - CHAR8 *ArgsStr; - UINT32 ArgsSize; - OC_BOOT_ARGUMENTS BA; - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN DescriptorSize; - - OcParseBootArgs (&BA, BootArgs); - - if (BootCompat->Settings.ProvideCustomSlide) { - // - // Restore the variables we tampered with to support custom slides. - // - AppleSlideRestore (BootCompat, &BA); - } - - if (BootCompat->Settings.DisableSingleUser) { - // - // First, there is a BootArgs entry for XNU. - // - OcRemoveArgumentFromCmd (BA.CommandLine, "-s"); - - // - // Second, there is a DT entry. - // - DTInit ((VOID *)(UINTN) *BA.DeviceTreeP, BA.DeviceTreeLength); - Status = DTLookupEntry (NULL, "/chosen", &Chosen); - if (!EFI_ERROR(Status)) { - Status = DTGetProperty (Chosen, "boot-args", (VOID **) &ArgsStr, &ArgsSize); - if (!EFI_ERROR(Status) && ArgsSize > 0) { - OcRemoveArgumentFromCmd (ArgsStr, "-s"); - } - } - } - - if (BootCompat->Settings.AvoidRuntimeDefrag) { - MemoryMapSize = *BA.MemoryMapSize; - MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN) (*BA.MemoryMap); - DescriptorSize = *BA.MemoryMapDescriptorSize; - - // - // We must restore EfiRuntimeServicesCode memory area types, because otherwise - // RuntimeServices won't be mapped. - // - RestoreProtectedRtMemoryTypes ( - &BootCompat->RtReloc, - MemoryMapSize, - DescriptorSize, - MemoryMap - ); - - // - // On native Macs due to EfiBoot defragmentation it is guaranteed that - // VADDR % BASE_1GB == PADDR. macOS 11 started to rely on this in - // acpi_count_enabled_logical_processors, which needs to access MADT (APIC) - // ACPI table, and does that through ConfigurationTables. - // - // The simplest approach is to just copy the table, so that it is accessible - // at both actual mapping and 1:1 defragmented mapping. This should be safe, - // as the memory for 1:1 defragmented mapping is reserved by EfiBoot in the - // first place and is otherwise stolen anyway. - // - if (BootCompat->KernelState.ConfigurationTable != NULL) { - CopyMem ( - (VOID*) ((UINTN) BA.SystemTable->ConfigurationTable & (BASE_1GB - 1)), - BootCompat->KernelState.ConfigurationTable, - sizeof (*BootCompat->KernelState.ConfigurationTable) * BA.SystemTable->NumberOfTableEntries - ); - } - } -} - -/** - Prepare environment for hibernate wake. Called when boot.efi jumps to kernel. - - @param[in,out] BootCompat Boot compatibility context. - @param[in,out] ImageHeaderPage Apple hibernate image page number. -**/ -STATIC -VOID -AppleMapPrepareForHibernateWake ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN UINTN ImageHeaderPage - ) -{ - IOHibernateImageHeader *ImageHeader; - IOHibernateHandoff *Handoff; - - ImageHeader = (IOHibernateImageHeader *) EFI_PAGES_TO_SIZE (ImageHeaderPage); - - // - // Legacy note. In legacy implementations systemTableOffset was unconditionally overwritten - // with a wrong address due to ImageHeader->runtimePages not being converted from pages to bytes. - // Fortunately systemTableOffset was unused when kIOHibernateHandoffTypeMemoryMap is unspecified. - // systemTableOffset is calculated properly by boot.efi itself starting from 10.6.8 at least, - // and thus this assignment was useless in the first place. - // - - // - // At this step we have two routes. - // - // 1. Remove newly generated memory map from hibernate image to let XNU use the original mapping. - // This is known to work well on most systems primarily because Windows requires UEFI firmwares - // to preserve physical memory consistency at S4 wake. "On a UEFI platform, firmware runtime memory - // must be consistent across S4 sleep state transitions, in both size and location.", see: - // https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-uefi#hibernation-state-s4-transition-requirements - // 2. Recover memory map just as we do for normal booting. This was causing issues on some firmwares, - // which provided very strange memory maps after S4 wake. In other cases this should not immediately - // break things. XNU will entirely remove efiRuntimeServicesPageStart/efiRuntimeServicesPageSize - // mapping, and our new memory map entries will unconditionally overwrite previous ones. In case - // no physical memory changes happened this should work fine. - // - Handoff = (IOHibernateHandoff *) EFI_PAGES_TO_SIZE ((UINTN) ImageHeader->handoffPages); - while (Handoff->type != kIOHibernateHandoffTypeEnd) { - if (Handoff->type == kIOHibernateHandoffTypeMemoryMap) { - if (BootCompat->Settings.DiscardHibernateMap) { - // - // Route 1. Discard the new memory map here, and let XNU use what it had. - // It is unknown whether there still are any firmwares that need this. - // - Handoff->type = kIOHibernateHandoffType; - } else { - // - // Route 2. Recovery memory protection types just as normal boot. - // - - if (BootCompat->KernelState.VmMapDescSize == 0) { - RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: Saved descriptor size cannot be 0\n")); - return; - } - - if (BootCompat->Settings.AvoidRuntimeDefrag) { - // - // I think we should not be there, but ideally all quirks are relatively independent. - // - RestoreProtectedRtMemoryTypes ( - &BootCompat->RtReloc, - Handoff->bytecount, - BootCompat->KernelState.VmMapDescSize, - (EFI_MEMORY_DESCRIPTOR *)(UINTN) Handoff->data - ); - } - } - - break; - } - - Handoff = (IOHibernateHandoff *) ((UINTN) Handoff + sizeof(Handoff) + Handoff->bytecount); - } -} - -VOID -AppleMapPrepareMemoryPool ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat - ) -{ - EFI_STATUS Status; - - if (!BootCompat->Settings.SetupVirtualMap - || BootCompat->KernelState.VmContext.MemoryPool != NULL) { - return; - } - - Status = VmAllocateMemoryPool ( - &BootCompat->KernelState.VmContext, - OC_DEFAULT_VMEM_PAGE_COUNT, - BootCompat->ServicePtrs.GetMemoryMap - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCABC: Memory pool allocation failure - %r\n", Status)); - } -} - -VOID -AppleMapPrepareBooterState ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN OUT EFI_LOADED_IMAGE *LoadedImage, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ) -{ - EFI_STATUS Status; - - // - // Allocate memory pool if needed. - // - AppleMapPrepareMemoryPool ( - BootCompat - ); - - // - // This function may be called twice, do not redo in this case. - // - AppleMapPlatformSaveState ( - &BootCompat->KernelState.AsmState, - &BootCompat->KernelState.KernelJump - ); - - if (BootCompat->Settings.AvoidRuntimeDefrag) { - if (BootCompat->KernelState.SysTableRtArea == 0) { - // - // Allocate RT data pages for copy of UEFI system table for kernel. - // This one also has to be 32-bit due to XNU BootArgs structure. - // The reason for this allocation to be required is because XNU uses static - // mapping for directly passed pointers (see ProtectRtMemoryFromRelocation). - // - BootCompat->KernelState.SysTableRtArea = BASE_4GB; - BootCompat->KernelState.SysTableRtAreaSize = gST->Hdr.HeaderSize; - Status = OcAllocatePagesFromTop ( - EfiRuntimeServicesData, - EFI_SIZE_TO_PAGES (gST->Hdr.HeaderSize), - &BootCompat->KernelState.SysTableRtArea, - GetMemoryMap, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_ERROR, - "OCABC: Failed to allocate system table memory - %r\n", - Status - )); - BootCompat->KernelState.SysTableRtArea = 0; - return; - } - - // - // Copy UEFI system table to the new location. - // - CopyMem ( - (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, - gST, - gST->Hdr.HeaderSize - ); - // - // Remember physical configuration table location. - // - BootCompat->KernelState.ConfigurationTable = gST->ConfigurationTable; - } - - // - // Assign loaded image with custom system table. - // - LoadedImage->SystemTable = - (EFI_SYSTEM_TABLE *)(UINTN) BootCompat->KernelState.SysTableRtArea; - } -} - -VOID -AppleMapPrepareKernelJump ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN UINTN ImageAddress, - IN BOOLEAN AppleHibernateWake - ) -{ - UINT64 KernelEntryVaddr; - UINT32 KernelEntry; - IOHibernateImageHeader *ImageHeader; - - // - // There is no reason to patch the kernel when we do not need it. - // - if (!BootCompat->Settings.AvoidRuntimeDefrag && !BootCompat->Settings.DiscardHibernateMap) { - return; - } - - // - // Check whether we have image address and abort if not. - // - if (ImageAddress == 0) { - RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: Failed to find image address, hibernate %d\n", AppleHibernateWake)); - return; - } - - if (!AppleHibernateWake) { - // - // ImageAddress points to the first kernel segment, __HIB. - // Kernel image header is located in __TEXT, which follows __HIB. - // - ImageAddress += KERNEL_BASE_PADDR; - - // - // Cut higher virtual address bits. - // - KernelEntryVaddr = MachoRuntimeGetEntryAddress ( - (VOID*) ImageAddress - ); - if (KernelEntryVaddr == 0) { - RUNTIME_DEBUG ((DEBUG_ERROR, "OCABC: Kernel entry point was not found!")); - return; - } - - // - // Perform virtual to physical address conversion by subtracting __TEXT base - // and adding current physical kernel location. - // - KernelEntry = (UINT32) (KernelEntryVaddr - KERNEL_TEXT_VADDR + ImageAddress); - } else { - // - // Read kernel entry from hibernation image and patch it with jump. - // At this stage HIB section is not yet copied from sleep image to it's - // proper memory destination. so we'll patch entry point in sleep image. - // Note the virtual -> physical conversion through truncation. - // - ImageHeader = (IOHibernateImageHeader *) ImageAddress; - KernelEntry = ((UINT32)(UINTN) &ImageHeader->fileExtentMap[0]) - + ImageHeader->fileExtentMapSize + ImageHeader->restore1CodeOffset; - } - - // - // Save original kernel entry code. - // - CopyMem ( - &BootCompat->KernelState.KernelOrg[0], - (VOID *)(UINTN) KernelEntry, - sizeof (BootCompat->KernelState.KernelOrg) - ); - - // - // Copy kernel jump code to kernel entry address. - // - CopyMem ( - (VOID *)(UINTN) KernelEntry, - &BootCompat->KernelState.KernelJump, - sizeof (BootCompat->KernelState.KernelJump) - ); -} - -EFI_STATUS -AppleMapPrepareMemState ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap - ) -{ - EFI_STATUS Status; - - // - // Protect RT areas from relocation by marking then MemMapIO. - // - if (BootCompat->Settings.AvoidRuntimeDefrag) { - ProtectRtMemoryFromRelocation ( - &BootCompat->RtReloc, - MemoryMapSize, - DescriptorSize, - MemoryMap, - BootCompat->KernelState.SysTableRtArea, - BootCompat->KernelState.SysTableRtAreaSize - ); - } - - // - // Virtualize RT services with all needed fixes. - // - if (BootCompat->Settings.SetupVirtualMap) { - Status = PerformRtMemoryVirtualMapping ( - &BootCompat->KernelState, - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } else { - Status = gRT->SetVirtualAddressMap ( - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } - - // - // Copy now virtualized UEFI system table for boot.efi to hand it to the kernel. - // - if (BootCompat->Settings.AvoidRuntimeDefrag) { - CopyMem ( - (VOID *)(UINTN) BootCompat->KernelState.SysTableRtArea, - gST, - gST->Hdr.HeaderSize - ); - } - - return Status; -} - -UINTN -EFIAPI -AppleMapPrepareKernelState ( - IN UINTN Args, - IN BOOLEAN ModeX64 - ) -{ - BOOT_COMPAT_CONTEXT *BootCompatContext; - - BootCompatContext = GetBootCompatContext (); - - if (BootCompatContext->ServiceState.AppleHibernateWake) { - AppleMapPrepareForHibernateWake ( - BootCompatContext, - Args - ); - } else { - AppleMapPrepareForBooting ( - BootCompatContext, - (VOID *) Args - ); - } - - // - // Restore original kernel entry code. - // - CopyMem ( - BootCompatContext->KernelState.AsmState.KernelEntry, - &BootCompatContext->KernelState.KernelOrg[0], - sizeof (BootCompatContext->KernelState.KernelOrg) - ); - - return Args; -} diff --git a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c b/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c deleted file mode 100644 index 01358b4ff..000000000 --- a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c +++ /dev/null @@ -1,160 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "BootCompatInternal.h" - -/** - Apple Boot Compatibility protocol instance. Its GUID matches - with legacy AptioMemoryFix protocol, allowing us to avoid - conflicts between the two. -**/ -STATIC OC_AFTER_BOOT_COMPAT_PROTOCOL mOcAfterBootCompatProtocol = { - OC_AFTER_BOOT_COMPAT_PROTOCOL_REVISION -}; - -/** - Apple Boot Compatibility context. This context is used throughout - the library. Must be accessed through GetBootCompatContext (). -**/ -STATIC BOOT_COMPAT_CONTEXT mOcAfterBootCompatContext; - -STATIC -EFI_STATUS -InstallAbcProtocol ( - VOID - ) -{ - EFI_STATUS Status; - VOID *Interface; - EFI_HANDLE Handle; - - Status = gBS->LocateProtocol ( - &gOcAfterBootCompatProtocolGuid, - NULL, - &Interface - ); - - if (!EFI_ERROR(Status)) { - // - // Ensure we do not run with AptioMemoryFix. - // It also checks for attempts to install this protocol twice. - // - DEBUG ((DEBUG_WARN, "OCABC: Found legacy AptioMemoryFix driver!\n")); - return EFI_ALREADY_STARTED; - } - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gOcAfterBootCompatProtocolGuid, - &mOcAfterBootCompatProtocol, - NULL - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCABC: protocol install failure - %r\n", Status)); - return Status; - } - - return EFI_SUCCESS; -} - -BOOT_COMPAT_CONTEXT * -GetBootCompatContext ( - VOID - ) -{ - return &mOcAfterBootCompatContext; -} - -EFI_STATUS -OcAbcInitialize ( - IN OC_ABC_SETTINGS *Settings - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - UINTN LowMemory; - UINTN TotalMemory; - - Status = InstallAbcProtocol (); - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG (( - DEBUG_INFO, - "OCABC: RTDFRG %d DEVMMIO %d NOSU %d NOVRWR %d NOSB %d NOHBMAP %d SMSLIDE %d WRUNPROT %d\n", - Settings->AvoidRuntimeDefrag, - Settings->DevirtualiseMmio, - Settings->DisableSingleUser, - Settings->DisableVariableWrite, - Settings->ProtectSecureBoot, - Settings->DiscardHibernateMap, - Settings->EnableSafeModeSlide, - Settings->EnableWriteUnprotector - )); - - DEBUG (( - DEBUG_INFO, - "OCABC: FEXITBS %d PRMRG %d CSLIDE %d MSLIDE %d PRSRV %d RBMAP %d VMAP %d APPLOS %d RTPERMS %d\n", - Settings->ForceExitBootServices, - Settings->ProtectMemoryRegions, - Settings->ProvideCustomSlide, - Settings->ProvideMaxSlide, - Settings->ProtectUefiServices, - Settings->RebuildAppleMemoryMap, - Settings->SetupVirtualMap, - Settings->SignalAppleOS, - Settings->SyncRuntimePermissions - )); - - DEBUG_CODE_BEGIN (); - TotalMemory = OcCountFreePages (&LowMemory); - DEBUG (( - DEBUG_INFO, - "OCABC: Firmware has %Lu free pages (%Lu in lower 4 GB)\n", - (UINT64) TotalMemory, - (UINT64) LowMemory - )); - DEBUG_CODE_END (); - - BootCompat = GetBootCompatContext (); - - CopyMem ( - &BootCompat->Settings, - Settings, - sizeof (BootCompat->Settings) - ); - - InstallServiceOverrides (BootCompat); - - return EFI_SUCCESS; -} diff --git a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf b/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf deleted file mode 100644 index e89ff8080..000000000 --- a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.inf +++ /dev/null @@ -1,79 +0,0 @@ -## @file -# -# Component description file for the library producing the Apple Device property protocol. -# -# Copyright (C) 2019, vit9696. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAfterBootCompatLib - FILE_GUID = A393F7CF-3966-4C7E-8763-3DD991681C9B - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAfterBootCompatLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - BootCompatInternal.h - CustomSlide.c - KernelSupport.c - OcAfterBootCompatLib.c - ServiceOverrides.c - # All headers should go to [Sources], this sounds like a bug in EDK II Build System. - Ia32/ContextSwitch.h - X64/ContextSwitch.h - ../../Include/Library/OcAfterBootCompatLib.h - -[Sources.Ia32] - Ia32/ContextSwitchSupport.c - -[Sources.X64] - X64/ContextSwitch.nasm - X64/ContextSwitchSupport.c - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[Guids] - gEfiAppleBootGuid ## SOMETIMES_CONSUMES - -[Protocols] - gOcAfterBootCompatProtocolGuid ## PRODUCES - gOcFirmwareRuntimeProtocolGuid ## SOMETIMES_CONSUMES - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - MemoryAllocationLib - PrintLib - UefiBootServicesTableLib - UefiRuntimeServicesTableLib - OcCpuLib - OcCryptoLib - DeviceTreeLib - OcGuardLib - OcMemoryLib - OcOSInfoLib - OcRngLib diff --git a/Library/OcAfterBootCompatLib/ServiceOverrides.c b/Library/OcAfterBootCompatLib/ServiceOverrides.c deleted file mode 100644 index ebf3165a3..000000000 --- a/Library/OcAfterBootCompatLib/ServiceOverrides.c +++ /dev/null @@ -1,1048 +0,0 @@ -/** @file - Copyright (C) 2013, dmazar. All rights reserved. - Copyright (C) 2017, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootCompatInternal.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/** - Helper function to mark OpenRuntime as executable with proper permissions. - - @param[in] BootCompat Boot compatibility context. -**/ -STATIC -VOID -FixRuntimeAttributes ( - IN BOOT_COMPAT_CONTEXT *BootCompat, - IN UINT32 Type - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; - UINTN Pages; - - if (Type != EfiRuntimeServicesCode && Type != EfiRuntimeServicesData) { - return; - } - - if (BootCompat->Settings.SyncRuntimePermissions && BootCompat->ServiceState.FwRuntime != NULL) { - // - // Be very careful of recursion here, who knows what the firmware can call. - // - BootCompat->Settings.SyncRuntimePermissions = FALSE; - - Status = BootCompat->ServiceState.FwRuntime->GetExecArea (&Address, &Pages); - - if (!EFI_ERROR(Status)) { - OcRebuildAttributes (Address, BootCompat->ServicePtrs.GetMemoryMap); - } - - // - // Permit syncing runtime permissions again. - // - BootCompat->Settings.SyncRuntimePermissions = TRUE; - } -} - -/** - Helper function to call ExitBootServices that can handle outdated MapKey issues. - - @param[in] ExitBootServices ExitBootServices function pointer, optional. - @param[in] GetMemoryMap GetMemoryMap function pointer, optional. - @param[in] ImageHandle Image handle to call ExitBootServices on. - @param[in] MapKey MapKey to call ExitBootServices on. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -ForceExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey, - IN EFI_EXIT_BOOT_SERVICES ExitBootServices OPTIONAL, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MemoryMapSize; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - - if (ExitBootServices == NULL) { - ExitBootServices = gBS->ExitBootServices; - } - - if (GetMemoryMap == NULL) { - GetMemoryMap = gBS->GetMemoryMap; - } - - // - // Firstly try the easy way. - // - Status = ExitBootServices (ImageHandle, MapKey); - - if (EFI_ERROR(Status)) { - // - // It is too late to free memory map here, but it does not matter, because boot.efi has an old one - // and will freely use the memory. - // It is technically forbidden to allocate pool memory here, but we should not hit this code - // in the first place, and for older firmwares, where it was necessary (?), it worked just fine. - // - Status = OcGetCurrentMemoryMapAlloc ( - &MemoryMapSize, - &MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion, - GetMemoryMap, - NULL - ); - if (Status == EFI_SUCCESS) { - // - // We have the latest memory map and its key, try again! - // - Status = ExitBootServices (ImageHandle, MapKey); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCABC: ExitBootServices failed twice - %r\n", Status)); - } - } else { - DEBUG ((DEBUG_WARN, "OCABC: Failed to get MapKey for ExitBootServices - %r\n", Status)); - Status = EFI_INVALID_PARAMETER; - } - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCABC: Waiting 10 secs...\n")); - gBS->Stall (SECONDS_TO_MICROSECONDS (10)); - } - } - - return Status; -} - -/** - Protect regions in memory map. - - @param[in,out] MemoryMapSize Memory map size in bytes, updated on shrink. - @param[in,out] MemoryMap Memory map to shrink. - @param[in] DescriptorSize Memory map descriptor size in bytes. -**/ -STATIC -VOID -ProtectMemoryRegions ( - IN UINTN MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - UINTN NumEntries; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Desc; - UINTN PhysicalEnd; - - // - // AMI CSM module allocates up to two regions for legacy video output. - // 1. For PMM and EBDA areas. - // On Ivy Bridge and below it ends at 0xA0000-0x1000-0x1 and has EfiBootServicesCode type. - // On Haswell and above it is allocated below 0xA0000 address with the same type. - // 2. For Intel RC S3 reserved area, fixed from 0x9F000 to 0x9FFFF. - // On Sandy Bridge and below it is not present in memory map. - // On Ivy Bridge and newer it is present as EfiRuntimeServicesData. - // Starting from at least SkyLake it is present as EfiReservedMemoryType. - // - // Prior to AptioMemoryFix EfiRuntimeServicesData could have been relocated by boot.efi, - // and the 2nd region could have been overwritten by the kernel. Now it is no longer the - // case, and only the 1st region may need special handling. - // For the 1st region there appear to be (unconfirmed) reports that it may still be accessed - // after waking from sleep. This does not seem to be valid according to AMI code, but we still - // protect it in case such systems really exist. - // - // Initially researched and fixed on GIGABYTE boards by Slice. - // - - Desc = MemoryMap; - NumEntries = MemoryMapSize / DescriptorSize; - - for (Index = 0; Index < NumEntries; ++Index) { - if (Desc->NumberOfPages > 0 && Desc->Type == EfiBootServicesData) { - ASSERT (LAST_DESCRIPTOR_ADDR (Desc) < MAX_UINTN); - PhysicalEnd = (UINTN)LAST_DESCRIPTOR_ADDR (Desc) + 1; - - if (PhysicalEnd >= 0x9E000 && PhysicalEnd < 0xA0000) { - Desc->Type = EfiACPIMemoryNVS; - break; - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - // - // Some firmwares may leave MMIO regions as reserved memory with runtime flag, - // which will not get mapped by macOS kernel. This will cause boot failures due - // to these firmwares accessing these regions at runtime for NVRAM support. - // REF: https://github.com/acidanthera/bugtracker/issues/791#issuecomment-608959387 - // - - Desc = MemoryMap; - - for (Index = 0; Index < NumEntries; ++Index) { - if (Desc->Type == EfiReservedMemoryType && (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0) { - Desc->Type = EfiMemoryMappedIO; - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } -} - -/** - Mark MMIO virtual memory regions as non-runtime to reduce the amount - of virtual memory required by boot.efi. - - @param[in] Context Boot compatibility context. - @param[in,out] MemoryMapSize Memory map size in bytes, updated on devirtualisation. - @param[in,out] MemoryMap Memory map to devirtualise. - @param[in] DescriptorSize Memory map descriptor size in bytes. -**/ -STATIC -VOID -DevirtualiseMmio ( - IN VOID *Context, - IN UINTN MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - UINTN NumEntries; - UINTN Index; - UINTN Index2; - EFI_MEMORY_DESCRIPTOR *Desc; - CONST EFI_PHYSICAL_ADDRESS *Whitelist; - UINTN WhitelistSize; - BOOLEAN Skipped; - UINT64 PagesSaved; - - Whitelist = ((BOOT_COMPAT_CONTEXT *) Context)->Settings.MmioWhitelist; - WhitelistSize = ((BOOT_COMPAT_CONTEXT *) Context)->Settings.MmioWhitelistSize; - - // - // Some firmwares (normally Haswell and earlier) need certain MMIO areas to have - // virtual addresses due to their firmware implementations to access NVRAM. - // For example, on Intel Haswell with APTIO that would be: - // 0xFED1C000 (SB_RCBA) is a 0x4 page memory region, containing SPI_BASE at 0x3800 (SPI_BASE_ADDRESS). - // 0xFF000000 (PCI root) is a 0x1000 page memory region. - // One can make exceptions with Whitelist, as it is required on certain laptops. - // - - Desc = MemoryMap; - NumEntries = MemoryMapSize / DescriptorSize; - PagesSaved = 0; - - if (!((BOOT_COMPAT_CONTEXT *) Context)->ServiceState.ReportedMmio) { - DEBUG ((DEBUG_INFO, "OCABC: MMIO devirt start\n")); - } - - for (Index = 0; Index < NumEntries; ++Index) { - if (Desc->NumberOfPages > 0 - && Desc->Type == EfiMemoryMappedIO - && (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0) { - - Skipped = FALSE; - - for (Index2 = 0; Index2 < WhitelistSize; ++Index2) { - if (AREA_WITHIN_DESCRIPTOR (Desc, Whitelist[Index2], 1)) { - Skipped = TRUE; - break; - } - } - - if (!((BOOT_COMPAT_CONTEXT *) Context)->ServiceState.ReportedMmio) { - DEBUG (( - DEBUG_INFO, - "OCABC: MMIO devirt 0x%Lx (0x%Lx pages, 0x%Lx) skip %d\n", - (UINT64) Desc->PhysicalStart, - (UINT64) Desc->NumberOfPages, - (UINT64) Desc->Attribute, - Skipped - )); - } - - if (!Skipped) { - Desc->Attribute &= ~EFI_MEMORY_RUNTIME; - PagesSaved += Desc->NumberOfPages; - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - if (!((BOOT_COMPAT_CONTEXT *) Context)->ServiceState.ReportedMmio) { - DEBUG (( - DEBUG_INFO, - "OCABC: MMIO devirt end, saved %Lu KB\n", - EFI_PAGES_TO_SIZE (PagesSaved) / BASE_1KB - )); - ((BOOT_COMPAT_CONTEXT *) Context)->ServiceState.ReportedMmio = TRUE; - } -} - -/** - UEFI Boot Services AllocatePages override. - Returns pages from free memory block to boot.efi for kernel boot image. -**/ -STATIC -EFI_STATUS -EFIAPI -OcAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - BOOLEAN IsPerfAlloc; - - BootCompat = GetBootCompatContext (); - IsPerfAlloc = FALSE; - - if (BootCompat->ServiceState.AwaitingPerfAlloc) { - if (BootCompat->ServiceState.AppleBootNestedCount > 0) { - if (Type == AllocateMaxAddress - && MemoryType == EfiACPIReclaimMemory - && *Memory == BASE_4GB - 1) { - IsPerfAlloc = TRUE; - } - } else { - BootCompat->ServiceState.AwaitingPerfAlloc = FALSE; - } - } - - Status = BootCompat->ServicePtrs.AllocatePages ( - Type, - MemoryType, - NumberOfPages, - Memory - ); - - if (!EFI_ERROR(Status)) { - FixRuntimeAttributes (BootCompat, MemoryType); - - if (BootCompat->ServiceState.AppleBootNestedCount > 0) { - if (IsPerfAlloc) { - // - // Called from boot.efi. - // New perf data, it can be reallocated multiple times. - // - // OcAppleDebugLogPerfAllocated ((VOID *)(UINTN) *Memory, EFI_PAGES_TO_SIZE (NumberOfPages)); - } else if (Type == AllocateAddress && MemoryType == EfiLoaderData) { - // - // Called from boot.efi. - // Store minimally allocated address to find kernel image start. - // - if (BootCompat->ServiceState.MinAllocatedAddr == 0 - || *Memory < BootCompat->ServiceState.MinAllocatedAddr) { - BootCompat->ServiceState.MinAllocatedAddr = *Memory; - } - } else if (BootCompat->ServiceState.AppleHibernateWake - && Type == AllocateAnyPages && MemoryType == EfiLoaderData - && BootCompat->ServiceState.HibernateImageAddress == 0) { - // - // Called from boot.efi during hibernate wake, - // first such allocation is for hibernate image - // - BootCompat->ServiceState.HibernateImageAddress = *Memory; - } - } - } - - return Status; -} - -/** - UEFI Boot Services FreePages override. - Ensures synchronised memory attribute table. -**/ -STATIC -EFI_STATUS -EFIAPI -OcFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - - BootCompat = GetBootCompatContext (); - - Status = BootCompat->ServicePtrs.FreePages ( - Memory, - Pages - ); - - if (!EFI_ERROR(Status)) { - FixRuntimeAttributes (BootCompat, EfiRuntimeServicesData); - } - - return Status; -} - -/** - UEFI Boot Services GetMemoryMap override. - Returns shrinked memory map as XNU can handle up to PMAP_MEMORY_REGIONS_SIZE (128) entries. - Also applies any further memory map alterations as necessary. -**/ -STATIC -EFI_STATUS -EFIAPI -OcGetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - EFI_STATUS Status; - EFI_STATUS Status2; - BOOT_COMPAT_CONTEXT *BootCompat; - EFI_PHYSICAL_ADDRESS Address; - UINTN Pages; - UINTN OriginalSize; - - BootCompat = GetBootCompatContext (); - - OriginalSize = MemoryMapSize != 0 ? *MemoryMapSize : 0; - Status = BootCompat->ServicePtrs.GetMemoryMap ( - MemoryMapSize, - MemoryMap, - MapKey, - DescriptorSize, - DescriptorVersion - ); - - // - // Reserve larger area for the memory map when we need to split it. - // - if (BootCompat->ServiceState.AppleBootNestedCount > 0 && Status == EFI_BUFFER_TOO_SMALL) { - *MemoryMapSize += OcCountSplitDescriptors () * *DescriptorSize; - return EFI_BUFFER_TOO_SMALL; - } - - if (EFI_ERROR(Status)) { - return Status; - } - - if (BootCompat->Settings.SyncRuntimePermissions && BootCompat->ServiceState.FwRuntime != NULL) { - // - // Some firmwares mark runtime drivers loaded after EndOfDxe as EfiRuntimeServicesData: - // REF: https://github.com/acidanthera/bugtracker/issues/791#issuecomment-607935508 - // - Status2 = BootCompat->ServiceState.FwRuntime->GetExecArea (&Address, &Pages); - - if (!EFI_ERROR (Status2)) { - OcUpdateDescriptors ( - *MemoryMapSize, - MemoryMap, - *DescriptorSize, - Address, - EfiRuntimeServicesCode, - 0, - 0 - ); - } - } - - if (BootCompat->ServiceState.AppleBootNestedCount > 0) { - if (BootCompat->Settings.ProtectMemoryRegions) { - ProtectMemoryRegions ( - *MemoryMapSize, - MemoryMap, - *DescriptorSize - ); - } - - if (BootCompat->Settings.DevirtualiseMmio) { - DevirtualiseMmio ( - BootCompat, - *MemoryMapSize, - MemoryMap, - *DescriptorSize - ); - } - - if (BootCompat->Settings.RebuildAppleMemoryMap) { - OcSortMemoryMap (*MemoryMapSize, MemoryMap, *DescriptorSize); - - Status2 = OcSplitMemoryMapByAttributes ( - OriginalSize, - MemoryMapSize, - MemoryMap, - *DescriptorSize - ); - if (EFI_ERROR (Status2) && Status2 != EFI_UNSUPPORTED) { - DEBUG ((DEBUG_INFO, "OCABC: Cannot rebuild memory map - %r\n", Status)); - } - - OcShrinkMemoryMap ( - MemoryMapSize, - MemoryMap, - *DescriptorSize - ); - } - - // - // Remember some descriptor size, since we will not have it later - // during hibernate wake to be able to iterate memory map. - // - BootCompat->ServiceState.MemoryMapDescriptorSize = *DescriptorSize; - } - - return Status; -} - -/** - UEFI Boot Services AllocatePool override. - Ensures synchronised memory attribute table. -**/ -STATIC -EFI_STATUS -EFIAPI -OcAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - - BootCompat = GetBootCompatContext (); - - Status = BootCompat->ServicePtrs.AllocatePool ( - PoolType, - Size, - Buffer - ); - - if (!EFI_ERROR(Status)) { - FixRuntimeAttributes (BootCompat, PoolType); - } - - return Status; -} - -/** - UEFI Boot Services FreePool override. - Ensures synchronised memory attribute table. -**/ -STATIC -EFI_STATUS -EFIAPI -OcFreePool ( - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - - BootCompat = GetBootCompatContext (); - - Status = BootCompat->ServicePtrs.FreePool ( - Buffer - ); - - if (!EFI_ERROR(Status)) { - FixRuntimeAttributes (BootCompat, EfiRuntimeServicesData); - } - - return Status; -} - -/** - UEFI Boot Services StartImage override. Called to start an efi image. - If this is boot.efi, then our overrides are enabled. -**/ -STATIC -EFI_STATUS -EFIAPI -OcStartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *AppleLoadedImage; - EFI_OS_INFO_PROTOCOL *OSInfo; - BOOT_COMPAT_CONTEXT *BootCompat; - OC_FWRT_CONFIG Config; - UINTN DataSize; - - BootCompat = GetBootCompatContext (); - AppleLoadedImage = OcGetAppleBootLoadedImage (ImageHandle); - - // - // Recover firmware-replaced GetMemoryMap pointer. - // - if (BootCompat->Settings.ProtectUefiServices - && BootCompat->ServicePtrs.GetMemoryMap != OcGetMemoryMap) { - DEBUG ((DEBUG_INFO, "OCABC: Recovering trashed GetMemoryMap pointer\n")); - gBS->GetMemoryMap = OcGetMemoryMap; - gBS->Hdr.CRC32 = 0; - gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32); - } - - FixRuntimeAttributes (BootCompat, EfiRuntimeServicesData); - - // - // Clear monitoring vars - // - BootCompat->ServiceState.MinAllocatedAddr = 0; - - if (AppleLoadedImage != NULL) { - // - // Report about macOS being loaded. - // - ++BootCompat->ServiceState.AppleBootNestedCount; - BootCompat->ServiceState.AppleHibernateWake = OcIsAppleHibernateWake (); - BootCompat->ServiceState.AppleCustomSlide = OcCheckArgumentFromEnv ( - AppleLoadedImage, - BootCompat->ServicePtrs.GetVariable, - "slide=", - L_STR_LEN ("slide=") - ); - - if (BootCompat->Settings.EnableSafeModeSlide) { - ASSERT (AppleLoadedImage->ImageSize <= MAX_UINTN); - AppleSlideUnlockForSafeMode ( - (UINT8 *) AppleLoadedImage->ImageBase, - (UINTN)AppleLoadedImage->ImageSize - ); - } - - AppleMapPrepareBooterState ( - BootCompat, - AppleLoadedImage, - BootCompat->ServicePtrs.GetMemoryMap - ); - } else if (BootCompat->Settings.SignalAppleOS) { - Status = gBS->LocateProtocol ( - &gEfiOSInfoProtocolGuid, - NULL, - (VOID *) &OSInfo - ); - - if (!EFI_ERROR(Status)) { - OSInfo->OSVendor (EFI_OS_INFO_APPLE_VENDOR_NAME); - OSInfo->OSName ("Mac OS X 10.15"); - } - } - - if (BootCompat->ServiceState.FwRuntime != NULL) { - BootCompat->ServiceState.FwRuntime->GetCurrent (&Config); - - // - // Support for ReadOnly and WriteOnly variables is OpenCore & Lilu security basics. - // For now always enable it. - // - Config.RestrictedVariables = TRUE; - - // - // Restrict secure boot variables and never let them slip unless once restricted. - // - Config.ProtectSecureBoot = BootCompat->Settings.ProtectSecureBoot; - - // - // Enable Boot#### variable redirection if OpenCore requested it. - // Do NOT disable it once enabled for stability reasons. - // - DataSize = sizeof (Config.BootVariableRedirect); - BootCompat->ServicePtrs.GetVariable ( - OC_BOOT_REDIRECT_VARIABLE_NAME, - &gOcVendorVariableGuid, - NULL, - &DataSize, - &Config.BootVariableRedirect - ); - - // - // Enable Apple-specific changes if requested. - // Disable them when this is no longer Apple. - // - if (BootCompat->ServiceState.AppleBootNestedCount > 0) { - Config.WriteProtection = BootCompat->Settings.DisableVariableWrite; - Config.WriteUnprotector = BootCompat->Settings.EnableWriteUnprotector; - } else { - Config.WriteProtection = FALSE; - Config.WriteUnprotector = FALSE; - } - - BootCompat->ServiceState.FwRuntime->SetMain ( - &Config - ); - } - - Status = BootCompat->ServicePtrs.StartImage ( - ImageHandle, - ExitDataSize, - ExitData - ); - - if (AppleLoadedImage != NULL) { - // - // We failed but other operating systems should be loadable. - // - --BootCompat->ServiceState.AppleBootNestedCount; - } - - return Status; -} - -/** - UEFI Boot Services ExitBootServices override. - Patches kernel entry point with jump to our KernelEntryPatchJumpBack(). -**/ -STATIC -EFI_STATUS -EFIAPI -OcExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - UINTN Index; - - BootCompat = GetBootCompatContext (); - - // - // Handle events in case we have any. - // - if (BootCompat->Settings.ExitBootServicesHandlers != NULL) { - for (Index = 0; BootCompat->Settings.ExitBootServicesHandlers[Index] != NULL; ++Index) { - BootCompat->Settings.ExitBootServicesHandlers[Index] ( - NULL, - BootCompat->Settings.ExitBootServicesHandlerContexts[Index] - ); - // - // Even if ExitBootServices fails, do not subsequently call the events we handled. - // - BootCompat->Settings.ExitBootServicesHandlers[Index] = NULL; - } - } - - FixRuntimeAttributes (BootCompat, EfiRuntimeServicesData); - - // - // For non-macOS operating systems return directly. - // - if (BootCompat->ServiceState.AppleBootNestedCount == 0) { - return BootCompat->ServicePtrs.ExitBootServices ( - ImageHandle, - MapKey - ); - } - - if (BootCompat->Settings.ForceExitBootServices) { - Status = ForceExitBootServices ( - ImageHandle, - MapKey, - BootCompat->ServicePtrs.ExitBootServices, - BootCompat->ServicePtrs.GetMemoryMap - ); - } else { - Status = BootCompat->ServicePtrs.ExitBootServices ( - ImageHandle, - MapKey - ); - } - - // - // Abort on error. - // - if (EFI_ERROR(Status)) { - return Status; - } - - if (!BootCompat->ServiceState.AppleHibernateWake) { - AppleMapPrepareKernelJump ( - BootCompat, - (UINTN) BootCompat->ServiceState.MinAllocatedAddr, - FALSE - ); - } else { - AppleMapPrepareKernelJump ( - BootCompat, - (UINTN) BootCompat->ServiceState.HibernateImageAddress, - TRUE - ); - } - - return Status; -} - -/** - UEFI Runtime Services SetVirtualAddressMap override. - Fixes virtualizing of RT services. -**/ -STATIC -EFI_STATUS -EFIAPI -OcSetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - - BootCompat = GetBootCompatContext (); - - // - // This is the time for us to remove our hacks. - // Make SetVirtualAddressMap useable once again. - // We do not need to recover BS, since they already are invalid. - // - gRT->SetVirtualAddressMap = BootCompat->ServicePtrs.SetVirtualAddressMap; - gRT->Hdr.CRC32 = 0; - gRT->Hdr.CRC32 = CalculateCrc32 (gRT, gRT->Hdr.HeaderSize); - - if (BootCompat->ServiceState.AppleBootNestedCount == 0) { - Status = gRT->SetVirtualAddressMap ( - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } else { - Status = AppleMapPrepareMemState ( - BootCompat, - MemoryMapSize, - DescriptorSize, - DescriptorVersion, - MemoryMap - ); - } - - return Status; -} - -/** - UEFI Runtime Services GetVariable override. - Used to return customised values for boot-args and csr-active-config variables. -**/ -STATIC -EFI_STATUS -EFIAPI -OcGetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data - ) -{ - EFI_STATUS Status; - BOOT_COMPAT_CONTEXT *BootCompat; - BOOLEAN IsApple; - - BootCompat = GetBootCompatContext (); - IsApple = BootCompat->ServiceState.AppleBootNestedCount > 0; - - if (IsApple && BootCompat->Settings.ProvideCustomSlide) { - Status = AppleSlideGetVariable ( - BootCompat, - BootCompat->ServicePtrs.GetVariable, - BootCompat->ServicePtrs.GetMemoryMap, - BootCompat->Settings.DevirtualiseMmio ? DevirtualiseMmio : NULL, - BootCompat, - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - } else { - Status = BootCompat->ServicePtrs.GetVariable ( - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - } - - // - // Catch performance record allocation. - // - if (IsApple - && Status == EFI_BUFFER_TOO_SMALL - && CompareGuid (VendorGuid, &gEfiAppleBootGuid) - && StrCmp (VariableName, APPLE_EFI_BOOT_PERF_VARIABLE_NAME) == 0) { - BootCompat->ServiceState.AwaitingPerfAlloc = TRUE; - DEBUG ((DEBUG_INFO, "OCABC: Caught successful request for %s\n", VariableName)); - } - - return Status; -} - -/** - UEFI Runtime Services GetVariable override event handler. - We do not override GetVariable ourselves but let our runtime do that. - - @param[in] Event Event handle. - @param[in] Context Apple boot compatibility context. -**/ -STATIC -VOID -EFIAPI -SetGetVariableHookHandler ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; - BOOT_COMPAT_CONTEXT *BootCompat; - - BootCompat = (BOOT_COMPAT_CONTEXT *) Context; - - if (BootCompat->ServicePtrs.GetVariable == NULL) { - Status = gBS->LocateProtocol ( - &gOcFirmwareRuntimeProtocolGuid, - NULL, - (VOID **) &FwRuntime - ); - - if (!EFI_ERROR(Status)) { - if (FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) { - DEBUG ((DEBUG_INFO, "OCABC: Got rendezvous with OpenRuntime r%u\n", OC_FIRMWARE_RUNTIME_REVISION)); - DEBUG ((DEBUG_INFO, "OCABC: MAT support is %d\n", OcGetMemoryAttributes (NULL) != NULL)); - Status = FwRuntime->OnGetVariable (OcGetVariable, &BootCompat->ServicePtrs.GetVariable); - } else { - DEBUG (( - DEBUG_ERROR, - "OCABC: Incompatible OpenRuntime r%u, require r%u\n", - (UINT32) FwRuntime->Revision, - (UINT32) OC_FIRMWARE_RUNTIME_REVISION - )); - CpuDeadLoop (); - } - } else { - DEBUG ((DEBUG_INFO, "OCABC: Awaiting rendezvous with OpenRuntime r%u\n", OC_FIRMWARE_RUNTIME_REVISION)); - Status = EFI_UNSUPPORTED; - } - - // - // Mark protocol as useable. - // - if (!EFI_ERROR(Status)) { - BootCompat->ServiceState.FwRuntime = FwRuntime; - } - } -} - -VOID -InstallServiceOverrides ( - IN OUT BOOT_COMPAT_CONTEXT *BootCompat - ) -{ - EFI_STATUS Status; - VOID *Registration; - UEFI_SERVICES_POINTERS *ServicePtrs; - EFI_TPL OriginalTpl; - - ServicePtrs = &BootCompat->ServicePtrs; - - OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - ServicePtrs->AllocatePages = gBS->AllocatePages; - ServicePtrs->FreePages = gBS->FreePages; - ServicePtrs->GetMemoryMap = gBS->GetMemoryMap; - ServicePtrs->AllocatePool = gBS->AllocatePool; - ServicePtrs->FreePool = gBS->FreePool; - ServicePtrs->ExitBootServices = gBS->ExitBootServices; - ServicePtrs->StartImage = gBS->StartImage; - ServicePtrs->SetVirtualAddressMap = gRT->SetVirtualAddressMap; - - gBS->AllocatePages = OcAllocatePages; - gBS->FreePages = OcFreePages; - gBS->GetMemoryMap = OcGetMemoryMap; - gBS->AllocatePool = OcAllocatePool; - gBS->FreePool = OcFreePool; - gBS->ExitBootServices = OcExitBootServices; - gBS->StartImage = OcStartImage; - gRT->SetVirtualAddressMap = OcSetVirtualAddressMap; - - gBS->Hdr.CRC32 = 0; - gBS->Hdr.CRC32 = CalculateCrc32 (gBS, gBS->Hdr.HeaderSize); - - gRT->Hdr.CRC32 = 0; - gRT->Hdr.CRC32 = CalculateCrc32 (gRT, gRT->Hdr.HeaderSize); - - gBS->RestoreTPL (OriginalTpl); - - // - // Update GetVariable handle with the help of external runtime services. - // - SetGetVariableHookHandler (NULL, BootCompat); - - if (BootCompat->ServicePtrs.GetVariable != NULL) { - return; - } - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - SetGetVariableHookHandler, - BootCompat, - &BootCompat->ServiceState.GetVariableEvent - ); - - if (!EFI_ERROR(Status)) { - Status = gBS->RegisterProtocolNotify ( - &gOcFirmwareRuntimeProtocolGuid, - BootCompat->ServiceState.GetVariableEvent, - &Registration - ); - - if (EFI_ERROR(Status)) { - gBS->CloseEvent (BootCompat->ServiceState.GetVariableEvent); - } - } -} diff --git a/Library/OcAfterBootCompatLib/X64/ContextSwitch.h b/Library/OcAfterBootCompatLib/X64/ContextSwitch.h deleted file mode 100644 index 55da36646..000000000 --- a/Library/OcAfterBootCompatLib/X64/ContextSwitch.h +++ /dev/null @@ -1,95 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef CONTEXT_SWITCH_H -#define CONTEXT_SWITCH_H - -// -// Structure definitions shared with ASM code. -// Keep these definitions in sync with ContextSwitch.nasm! -// - -#pragma pack(push, 1) - -/** - Assembly support state. - This state is used as an intermediate structure to hold UEFI environment - context and kernel environment context for switching between 32-bit - and 64-bit modes during booting as normal XNU boot still happens in 32-bit. -**/ -typedef PACKED struct ASM_SUPPORT_STATE_ { - UINT64 SavedGDTR; - UINT16 SavedGDTRLimit; - UINT64 SavedIDTR; - UINT16 SavedIDTRLimit; - UINT64 SavedCR3; - UINT16 SavedCS; - UINT16 SavedDS; - UINT16 SavedES; - UINT16 SavedFS; - UINT16 SavedGS; - - UINT64 SavedGDTR32; - UINT16 SavedGDTR32Limit; - UINT64 SavedIDTR32; - UINT16 SavedIDTR32Limit; - UINT16 SavedCS32; - UINT16 SavedDS32; - UINT16 SavedES32; - UINT16 SavedFS32; - UINT16 SavedGS32; - - VOID *KernelEntry; -} ASM_SUPPORT_STATE; - -/** - Assembly kernel trampoline. - This structure contains encoded assembly to jump from kernel - code to UEFI code through AsmAppleMapPlatformPrepareKernelState - intermediate handler. -**/ -typedef PACKED struct ASM_KERNEL_JUMP_ { - UINT8 MovInst; - UINT32 Addr; - UINT16 CallInst; -} ASM_KERNEL_JUMP; - -#pragma pack(pop) - -/** - Assembly interface to save UEFI environment state in specific way. - - @param[in,out] AsmState Assembly state to update, can be preserved. -**/ -VOID -EFIAPI -AsmAppleMapPlatformSaveState ( - IN OUT ASM_SUPPORT_STATE *AsmState - ); - -/** - Assembly interface for backjump from kernel code. - Takes kernel arguments through RAX or EAX register. -**/ -VOID -AsmAppleMapPlatformPrepareKernelState ( - ); - -/** - Assembly global variable containing ASM_SUPPORT_STATE address. - Must fit into lower 32-bit bytes due to 32-bit . -**/ -extern UINT32 gOcAbcAsmStateAddr32; - -#endif // CONTEXT_SWITCH_H diff --git a/Library/OcAfterBootCompatLib/X64/ContextSwitch.nasm b/Library/OcAfterBootCompatLib/X64/ContextSwitch.nasm deleted file mode 100755 index b8fcdaf66..000000000 --- a/Library/OcAfterBootCompatLib/X64/ContextSwitch.nasm +++ /dev/null @@ -1,391 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2013, dmazar. All rights reserved. -; Copyright (C) 2019, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 64 -DEFAULT REL - -;------------------------------------------------------------------------------ -; Structure definitions shared with C code. -; Keep these definitions in sync with ContextSwitch.h! -;------------------------------------------------------------------------------ - -struc ASM_SUPPORT_STATE - ;------------------------------------------------------------------------------ - ; 64-bit state - ;------------------------------------------------------------------------------ - - .SavedGDTR resq 1 - .SavedGDTRLimit resw 1 - .SavedIDTR resq 1 - .SavedIDTRLimit resw 1 - .SavedCR3 resq 1 - .SavedCS resw 1 - .SavedDS resw 1 - .SavedES resw 1 - .SavedFS resw 1 - .SavedGS resw 1 - - ;------------------------------------------------------------------------------ - ; 32-bit state - ;------------------------------------------------------------------------------ - - .SavedGDTR32 resq 1 - .SavedGDTR32Limit resw 1 - .SavedIDTR32 resq 1 - .SavedIDTR32Limit resw 1 - .SavedCS32 resw 1 - .SavedDS32 resw 1 - .SavedES32 resw 1 - .SavedFS32 resw 1 - .SavedGS32 resw 1 - - ;------------------------------------------------------------------------------ - ; Kernel entry address. - ;------------------------------------------------------------------------------ - - .KernelEntry resq 1 - - .Size: -endstruc - -struc ASM_KERNEL_JUMP - .MovInst resb 1 - .Addr resd 1 - .CallInst resw 1 - - .Size: -endstruc - -;------------------------------------------------------------------------------ -; C callback method called on jump to kernel after boot.efi finishes. -;------------------------------------------------------------------------------ - -extern ASM_PFX(AppleMapPrepareKernelState) - -SECTION .text - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; AsmAppleMapPlatformSaveState ( -; OUT ASM_SUPPORT_STATE *AsmState -; ); -;------------------------------------------------------------------------------ -align 8 -global ASM_PFX(AsmAppleMapPlatformSaveState) -ASM_PFX(AsmAppleMapPlatformSaveState): -BITS 64 - sgdt [rcx + ASM_SUPPORT_STATE.SavedGDTR] - sidt [rcx + ASM_SUPPORT_STATE.SavedIDTR] - mov rax, cr3 - mov [rcx + ASM_SUPPORT_STATE.SavedCR3], rax - mov word [rcx + ASM_SUPPORT_STATE.SavedCS], cs - mov word [rcx + ASM_SUPPORT_STATE.SavedDS], ds - mov word [rcx + ASM_SUPPORT_STATE.SavedES], es - mov word [rcx + ASM_SUPPORT_STATE.SavedFS], fs - mov word [rcx + ASM_SUPPORT_STATE.SavedGS], gs - ret - -;------------------------------------------------------------------------------ -; Apple kernel starts through call gate, an assembly structure allocated in -; 32-bit high memory, that transitions to 32-bit mode and then calls the kernel -; with 32-bit GDT and UEFI stack. -; -; KernelCallGate: -; lea rax, StartKernelIn32Bit -; mov cs:gKernelBooter32, eax -; lea rax, gKernelGdtTable -; mov cs:gKernelGdtBase, rax -; lgdt fword ptr cs:gKernelGdtLimit -; mov ax, 10h -; mov ds, ax -; mov es, ax -; mov gs, ax -; mov fs, ax -; lea rax, gKernelBooter32 -; jmp fword ptr [rax] -; -; StartKernelIn32Bit: -; mov rax, cr0 -; btr eax, 1Fh -; mov cr0, rax -; mov ebx, ecx ; ebx = boot-args -; mov edi, edx -; ; Disable long mode -; mov ecx, 0C0000080h ; EFER MSR number. -; rdmsr -; btr eax, 8 ; Set LME=0. -; wrmsr -; jmp short SwitchTo32Bit -; -; SwitchTo32Bit: -; mov eax, ebx -; jmp rdi ; Jump to kernel -; hlt -; ret -; -; gKernelBooter32: -; dd 0 -; dw 8 ; New CS value -; gKernelGdtLimit: ; IA32_DESCRIPTOR -; dw 18h -; gKernelGdtBase: -; dq 0 -; gKernelGdtTable: ; Array of IA32_GDT. -; dw 0 ; [0] = LimitLow -; dw 0 ; [0] = BaseLow -; db 0 ; [0] = BaseMid -; dw 0 ; [0] = Flags -; db 0 ; [0] = BaseHigh -; dw 0FFFFh ; [1] = LimitLow -; dw 0 ; [1] = BaseLow -; db 0 ; [1] = BaseMid -; dw 0CF9Eh ; [1] - Flags -; db 0 ; [1] = BaseHigh -; dw 0FFFFh ; [2] = LimitLow -; dw 0 ; [2] = BaseLow -; db 0 ; [2] = BaseMid -; dw 0CF92h ; [2] = Flags -; db 0 ; [2] = BaseHigh -;------------------------------------------------------------------------------ - -;------------------------------------------------------------------------------ -; Long (far) return. -; retfq (lretq) - 64-bit encoding 48 CB -; retf (lret) - 32-bit encoding CB -;------------------------------------------------------------------------------ -LONG_RET64: - db 048h -LONG_RET32: - db 0CBh - -;------------------------------------------------------------------------------ -; AsmAppleMapPlatformPrepareKernelState -; -; Callback from boot.efi - this is where we jump when boot.efi jumps to kernel. -; eax register contains boot arguments for the kernel. -; -; - test if we are in 32 bit or in 64 bit -; - if 64 bit, then jump to AsmJumpFromKernel64 -; - else just continue with AsmJumpFromKernel32 -;------------------------------------------------------------------------------ -global ASM_PFX(AsmAppleMapPlatformPrepareKernelState) -ASM_PFX(AsmAppleMapPlatformPrepareKernelState): -BITS 32 - push eax ; save bootArgs pointer to stack - mov dword ecx, 0C0000080h ; EFER MSR number. - rdmsr ; Read EFER. - bt eax, 8 ; Check if LME==1 -> CF=1. - pop eax - jc AsmJumpFromKernel64 ; LME==1 -> jump to 64 bit code - ; otherwise, continue with AsmJumpFromKernel32 - -; Above 32-bit code must give the opcodes equivalent to following in 64-bit. -;BITS 64 -; push rax ; save bootArgs pointer to stack -; mov ecx, C0000080h ; EFER MSR number. -; rdmsr ; Read EFER. -; bt eax, 8 ; Check if LME==1 -> CF=1. -; pop rax -; jc AsmJumpFromKernel64 ; LME==1 -> jump to 64 bit code - -;------------------------------------------------------------------------------ -; AsmJumpFromKernel32 -; -; Callback from boot.efi in 32 bit mode. -;------------------------------------------------------------------------------ -AsmJumpFromKernel32: -BITS 32 - ; Save bootArgs pointer to edi. - mov edi, eax - - ; Load ebx with AsmState - we'll access our saved data with it. - db 0BBh ; mov ebx, OFFSET DataBase - -;------------------------------------------------------------------------------ -; 32-bit pointer to AsmState used to reduce global variable access. -; Defined here becuase 32-bit mode does not support relative addressing. -; As both jumps can happen from 64-bit kernel, the address must fit in 4 bytes. -;------------------------------------------------------------------------------ -global ASM_PFX(gOcAbcAsmStateAddr32) -ASM_PFX(gOcAbcAsmStateAddr32): - dd 0 - - ; Store kernel entery point prior to hunk code. - pop ecx - sub ecx, ASM_KERNEL_JUMP.Size - mov dword [ebx + ASM_SUPPORT_STATE.KernelEntry], ecx - - ; Store 32-bit state to be able to recover it later. - sgdt [ebx + ASM_SUPPORT_STATE.SavedGDTR32] - sidt [ebx + ASM_SUPPORT_STATE.SavedIDTR32] - mov word [ebx + ASM_SUPPORT_STATE.SavedCS32], cs - mov word [ebx + ASM_SUPPORT_STATE.SavedDS32], ds - mov word [ebx + ASM_SUPPORT_STATE.SavedES32], es - mov word [ebx + ASM_SUPPORT_STATE.SavedFS32], fs - mov word [ebx + ASM_SUPPORT_STATE.SavedGS32], gs - - ; - ; Transition to 64-bit mode... - ; boot.efi disables interrupts for us, so we are safe. - ; - - ; Load saved UEFI GDT and IDT. - ; They will become active after code segment is changed in long jump. - lgdt [ebx + ASM_SUPPORT_STATE.SavedGDTR] - lidt [ebx + ASM_SUPPORT_STATE.SavedIDTR] - - ; Enable the 64-bit page-translation-table entries by setting CR4.PAE=1. - mov eax, cr4 - bts eax, 5 - mov cr4, eax - - ; Set the long-mode page tables by reusing saved UEFI tables. - mov eax, dword [ebx + ASM_SUPPORT_STATE.SavedCR3] - mov cr3, eax - - ; Enable long mode (set EFER.LME=1). - mov ecx, 0C0000080h ; EFER MSR number. - rdmsr ; Read EFER. - bts eax, 8 ; Set LME=1. - wrmsr ; Write EFER. - - ; Enable paging to activate long mode (set CR0.PG=1). - mov eax, cr0 ; Read CR0. - bts eax, 31 ; Set PG=1. - mov cr0, eax ; Write CR0. - - ; Jump to the 64-bit code segment. - mov ax, word [ebx + ASM_SUPPORT_STATE.SavedCS] - push eax - call LONG_RET32 - -BITS 64 - - ; - ; Done transitioning to 64-bit code. - ; - - ; Set other segment selectors. In most firmwares all segment registers but cs - ; point to the same selector, but we must not rely on it. - mov ax, word [rbx + ASM_SUPPORT_STATE.SavedDS] - mov ds, ax - mov ax, word [rbx + ASM_SUPPORT_STATE.SavedES] - mov es, ax - mov ax, word [rbx + ASM_SUPPORT_STATE.SavedFS] - mov fs, ax - mov ax, word [rbx + ASM_SUPPORT_STATE.SavedGS] - mov gs, ax - - ; boot.efi preserves ss selector from UEFI GDT to just use UEFI stack (and memory) as is. - ; For this reason just assume the stack is useable but align it for definite 64-bit compat. - and rsp, 0FFFFFFFFFFFFFFF0h - - ; Call AppleMapPrepareKernelState (rcx = rax = bootArgs, rdx = 0 = 32 bit kernel jump). - mov rcx, rdi - xor edx, edx - push rdx - push rdx - push rdx - push rcx - call ASM_PFX(AppleMapPrepareKernelState) - - ; Return value in rax is bootArgs pointer again. - mov rdi, rax - - ; - ; Transition back to 32-bit. - ; - - ; Load saved 32-bit GDT. - lgdt [rbx + ASM_SUPPORT_STATE.SavedGDTR32] - - ; Jump to the 32-bit code segment. - mov ax, word [rbx + ASM_SUPPORT_STATE.SavedCS32] - push rax - call LONG_RET64 - -BITS 32 - - ; - ; Done transitioning to 32-bit code. - ; - - ; Disable paging (set CR0.PG=0). - mov eax, cr0 ; Read CR0. - btr eax, 31 ; Set PG=0. - mov cr0, eax ; Write CR0. - - ; Disable long mode (set EFER.LME=0). - mov ecx, 0C0000080h ; EFER MSR number. - rdmsr ; Read EFER. - btr eax, 8 ; Set LME=0. - wrmsr ; Write EFER. - jmp AsmJumpFromKernel32Compatibility - -AsmJumpFromKernel32Compatibility: - - ; - ; We are in 32-bit protected mode, no paging. - ; - - ; Reload saved 32 bit state data. - ; Since boot.efi relies on segment registers shadow part and preserves ss value, - ; which contains previously read GDT data, we are not allowed to later update it. - lidt [ebx + ASM_SUPPORT_STATE.SavedIDTR32] - mov ax, word [ebx + ASM_SUPPORT_STATE.SavedDS32] - mov ds, ax - mov ax, word [ebx + ASM_SUPPORT_STATE.SavedES32] - mov es, ax - mov ax, word [ebx + ASM_SUPPORT_STATE.SavedFS32] - mov fs, ax - mov ax, word [ebx + ASM_SUPPORT_STATE.SavedGS32] - mov gs, ax - - ; Jump back to the kernel passing boot arguments in eax. - mov eax, edi - mov edx, dword [ebx + ASM_SUPPORT_STATE.KernelEntry] - jmp edx - -;------------------------------------------------------------------------------ -; AsmJumpFromKernel64 -; -; Callback from boot.efi in 64 bit mode. -; State is prepared for kernel: 64 bit, pointer to bootArgs in rax. -;------------------------------------------------------------------------------ -AsmJumpFromKernel64: -BITS 64 - ; Load rbx with AsmState - we'll access our saved data with it. - mov ebx, dword [ASM_PFX(gOcAbcAsmStateAddr32)] - - ; Store kernel entery point prior to hunk code. - pop rcx - sub rcx, ASM_KERNEL_JUMP.Size - mov qword [rbx + ASM_SUPPORT_STATE.KernelEntry], rcx - - ; Call AppleMapPrepareKernelState (rcx = rax = bootArgs, rdx = 1 = 64-bit kernel jump). - mov rcx, rax - xor edx, edx - push rdx - push rdx - push rdx - push rcx - inc edx - call ASM_PFX(AppleMapPrepareKernelState) - - ; Jump back to the kernel passing boot arguments in rax. - mov rdx, [rbx + ASM_SUPPORT_STATE.KernelEntry] - jmp rdx diff --git a/Library/OcAfterBootCompatLib/X64/ContextSwitchSupport.c b/Library/OcAfterBootCompatLib/X64/ContextSwitchSupport.c deleted file mode 100644 index 3af7d3c47..000000000 --- a/Library/OcAfterBootCompatLib/X64/ContextSwitchSupport.c +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "../BootCompatInternal.h" - -#include - -VOID -AppleMapPlatformSaveState ( - IN OUT ASM_SUPPORT_STATE *AsmState, - OUT ASM_KERNEL_JUMP *KernelJump - ) -{ - // - // Save current 64-bit state - will be used later in callback from kernel jump - // to be able to transition to 64-bit in case 32-bit kernel startup code is used. - // - AsmAppleMapPlatformSaveState (AsmState); - - // - // Assembly state must fit into 32-bit address as we may jumo from 32-bit kernel - // startup code. This is used instead of GetBootCompatContext. - // - ASSERT ((UINT32)(UINTN) AsmState == (UINTN) AsmState); - gOcAbcAsmStateAddr32 = (UINT32)(UINTN) AsmState; - - // - // Kernel trampoline for jumping to kernel. - // - ASSERT ( - (UINT32)(UINTN) AsmAppleMapPlatformPrepareKernelState - == (UINTN) AsmAppleMapPlatformPrepareKernelState - ); - KernelJump->MovInst = 0xB9; - KernelJump->Addr = (UINT32)(UINTN) AsmAppleMapPlatformPrepareKernelState; - KernelJump->CallInst = 0xD1FF; -} diff --git a/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c b/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c deleted file mode 100644 index 1bdb9bb26..000000000 --- a/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c +++ /dev/null @@ -1,1726 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef DEBUG_BULK_INFO -#define DEBUG_BULK_INFO (DEBUG_VERBOSE|DEBUG_INFO) -#endif - - -typedef struct { - EFI_HANDLE Handle; - GUID ContainerGuid; - GUID VolumeGuid; - APPLE_APFS_VOLUME_ROLE VolumeRole; -} APFS_VOLUME_INFO; - -typedef struct { - EFI_HANDLE Handle; - CHAR16 *VolumeDirName; - EFI_FILE_PROTOCOL *Root; -} APFS_VOLUME_ROOT; - -/// -/// An array of file paths to search for in case no file is blessed. -/// On Apple Macs this list includes: -/// 1. APPLE_BOOTER_DEFAULT_FILE_NAME -- \System\Library\CoreServices\boot.efi -/// 2. APPLE_REMOVABLE_MEDIA_FILE_NAME -- \EFI\APPLE\X64\BOOT.EFI -/// 3. EFI_REMOVABLE_MEDIA_FILE_NAME -- \EFI\BOOT\BOOTX64.EFI -/// 4. APPLE_BOOTER_ROOT_FILE_NAME -- \boot.efi -/// -/// Since in real world only 1st and 3rd entries are used, we do not include -/// 2nd and 4th until further notice. However, we do include a custom entry -/// for Windows, for the reason OpenCore, unlike Apple EFI, may override -/// BOOTx64.efi, and this is not the case for Apple EFI. So we end up with: -/// 1. APPLE_BOOTER_DEFAULT_FILE_NAME -- \System\Library\CoreServices\boot.efi -/// 2. MS_BOOTER_DEFAULT_FILE_NAME -- \EFI\Microsoft\Boot\bootmgfw.efi -/// 3. EFI_REMOVABLE_MEDIA_FILE_NAME -- \EFI\BOOT\BOOTX64.EFI -/// -/// This resolves a problem when Windows installer does not replace our BOOTx64.efi -/// file with Windows file and then NVRAM reset or Boot Camp software reboot to macOS -/// results in the removal of the Windows boot entry from NVRAM making Windows -/// disappear from the list of OpenCore entries without BlessOverride. -/// -/// Linux and related entries are not present here, because they have fine working -/// software for boot management and do not use BOOTx64.efi in the first place. -/// -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 *gAppleBootPolicyPredefinedPaths[] = { - APPLE_BOOTER_DEFAULT_FILE_NAME, - MS_BOOTER_DEFAULT_FILE_NAME, - EFI_REMOVABLE_MEDIA_FILE_NAME -}; - -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN gAppleBootPolicyNumPredefinedPaths = - ARRAY_SIZE (gAppleBootPolicyPredefinedPaths); - -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN gAppleBootPolicyCoreNumPredefinedPaths = 2; - -EFI_STATUS -EFIAPI -BootPolicyGetBootFile ( - IN EFI_HANDLE Device, - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -EFI_STATUS -EFIAPI -BootPolicyGetBootFileEx ( - IN EFI_HANDLE Device, - IN BOOT_POLICY_ACTION Action, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ); - -EFI_STATUS -EFIAPI -BootPolicyDevicePathToDirPath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device, - OUT EFI_HANDLE *ApfsVolumeHandle - ); - -EFI_STATUS -EFIAPI -BootPolicyGetApfsRecoveryFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *PathName, - OUT CHAR16 **FullPathName, - OUT VOID **Reserved, - OUT EFI_FILE_PROTOCOL **Root, - OUT EFI_HANDLE *DeviceHandle - ); - -EFI_STATUS -EFIAPI -BootPolicyGetAllApfsRecoveryFilePath ( - IN EFI_HANDLE Handle OPTIONAL, - OUT VOID **Volumes, - OUT UINTN *NumberOfEntries - ); - -/// -/// The APPLE_BOOT_POLICY_PROTOCOL instance to get installed. -/// -STATIC APPLE_BOOT_POLICY_PROTOCOL mAppleBootPolicyProtocol = { - APPLE_BOOT_POLICY_PROTOCOL_REVISION, - BootPolicyGetBootFile, - BootPolicyGetBootFileEx, - BootPolicyDevicePathToDirPath, - BootPolicyGetApfsRecoveryFilePath, - BootPolicyGetAllApfsRecoveryFilePath -}; - -/** - Checks whether the given file exists or not. - - @param[in] Root The volume's opened root. - @param[in] FileName The path of the file to check. - - @return Returned is whether the specified file exists or not. - -**/ -STATIC -EFI_STATUS -InternalFileExists ( - IN EFI_FILE_HANDLE Root, - IN CONST CHAR16 *FileName - ) -{ - EFI_STATUS Status; - EFI_FILE_HANDLE FileHandle; - - Status = SafeFileOpen ( - Root, - &FileHandle, - FileName, - EFI_FILE_MODE_READ, - 0 - ); - - if (!EFI_ERROR(Status)) { - FileHandle->Close (FileHandle); - return EFI_SUCCESS; - } - - return Status; -} - -STATIC -EFI_STATUS -InternalGetApfsSpecialFileInfo ( - IN EFI_FILE_PROTOCOL *Root, - IN OUT APPLE_APFS_VOLUME_INFO **VolumeInfo OPTIONAL, - IN OUT APPLE_APFS_CONTAINER_INFO **ContainerInfo OPTIONAL - ) -{ - if (ContainerInfo == NULL && VolumeInfo == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (VolumeInfo != NULL) { - *VolumeInfo = GetFileInfo ( - Root, - &gAppleApfsVolumeInfoGuid, - sizeof (**VolumeInfo), - NULL - ); - - if (*VolumeInfo == NULL) { - DEBUG ((DEBUG_VERBOSE, "OCBP: APFS Volume Info is missing\n")); - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: APFS Volume Info - %p (%u, %g, %u)\n", - *VolumeInfo, - (*VolumeInfo)->Always1, - &(*VolumeInfo)->Uuid, - (*VolumeInfo)->Role - )); - } - - if (ContainerInfo != NULL) { - *ContainerInfo = GetFileInfo ( - Root, - &gAppleApfsContainerInfoGuid, - sizeof (**ContainerInfo), - NULL - ); - - if (*ContainerInfo == NULL) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: APFS Container Info is missing\n")); - if (VolumeInfo != NULL) { - FreePool (*VolumeInfo); - } - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: APFS Container Info - %p (%u, %g)\n", - *ContainerInfo, - (*ContainerInfo)->Always1, - &(*ContainerInfo)->Uuid - )); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -InternalGetBooterFromBlessedSystemFilePath ( - IN EFI_FILE_PROTOCOL *Root, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - UINTN FilePathSize; - - *FilePath = (EFI_DEVICE_PATH_PROTOCOL *) GetFileInfo ( - Root, - &gAppleBlessedSystemFileInfoGuid, - sizeof (EFI_DEVICE_PATH_PROTOCOL), - &FilePathSize - ); - - if (*FilePath == NULL) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed file is missing\n")); - return EFI_NOT_FOUND; - } - - DebugPrintHexDump (DEBUG_BULK_INFO, "OCBP: BlessedFileHEX", (UINT8 *) *FilePath, FilePathSize); - - if (!IsDevicePathValid (*FilePath, FilePathSize)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed file is invalid\n")); - FreePool (*FilePath); - *FilePath = NULL; - return EFI_NOT_FOUND; - } - - DebugPrintDevicePath (DEBUG_BULK_INFO, "OCBP: BlessedFileDP", *FilePath); - - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed file is valid\n")); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -InternalGetBooterFromBlessedSystemFolderPath ( - IN EFI_HANDLE Device, - IN EFI_FILE_PROTOCOL *Root, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - EFI_STATUS Status; - - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker; - FILEPATH_DEVICE_PATH *FolderDevicePath; - UINTN DevicePathSize; - UINTN BooterDirPathSize; - UINTN BooterPathSize; - CHAR16 *BooterPath; - - Status = EFI_NOT_FOUND; - - DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) GetFileInfo ( - Root, - &gAppleBlessedSystemFolderInfoGuid, - sizeof (EFI_DEVICE_PATH_PROTOCOL), - &DevicePathSize - ); - - if (DevicePath == NULL) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed folder is missing\n")); - return Status; - } - - DebugPrintHexDump (DEBUG_BULK_INFO, "OCBP: BlessedFolderHEX", (UINT8 *) DevicePath, DevicePathSize); - - if (!IsDevicePathValid (DevicePath, DevicePathSize)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed folder is invalid\n")); - FreePool (DevicePath); - return EFI_NOT_FOUND; - } - - DebugPrintDevicePath (DEBUG_BULK_INFO, "OCBP: BlessedFolderDP", DevicePath); - - DevicePathWalker = DevicePath; - - while (!IsDevicePathEnd (DevicePathWalker)) { - if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) - && (DevicePathSubType (DevicePathWalker) == MEDIA_FILEPATH_DP)) { - - FolderDevicePath = (FILEPATH_DEVICE_PATH *) DevicePathWalker; - BooterDirPathSize = OcFileDevicePathNameSize (FolderDevicePath); - BooterPathSize = BooterDirPathSize + L_STR_SIZE (APPLE_BOOTER_ROOT_FILE_NAME) - sizeof (CHAR16); - BooterPath = AllocateZeroPool (BooterPathSize); - - if (BooterPath != NULL) { - // - // FolderDevicePath->PathName may be unaligned, thus byte copying is needed. - // - CopyMem (BooterPath, FolderDevicePath->PathName, BooterDirPathSize); - StrCatS (BooterPath, BooterPathSize, APPLE_BOOTER_ROOT_FILE_NAME); - Status = EFI_SUCCESS; - } else { - Status = EFI_OUT_OF_RESOURCES; - } - - break; - } - - DevicePathWalker = NextDevicePathNode (DevicePathWalker); - } - - FreePool (DevicePath); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed folder append failed - %r\n", Status)); - return Status; - } - - Status = InternalFileExists (Root, BooterPath); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Blessed folder %s is missing - %r\n", BooterPath, Status)); - return EFI_NOT_FOUND; - } - - *FilePath = FileDevicePath (Device, BooterPath); - return EFI_SUCCESS; -} - -EFI_STATUS -OcGetBooterFromPredefinedPathList ( - IN EFI_HANDLE Device, - IN EFI_FILE_PROTOCOL *Root, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - IN CHAR16 *Prefix OPTIONAL - ) -{ - UINTN Index; - UINTN FullPathSize; - CHAR16 *FullPath; - CONST CHAR16 *PathName; - EFI_STATUS Status; - - for (Index = 0; Index < NumPredefinedPaths; ++Index) { - PathName = PredefinedPaths[Index]; - - // - // For relative paths (i.e. when Prefix is a volume GUID) we must - // not use leading slash. This is what AppleBootPolicy does. - // - if (Prefix != NULL) { - ASSERT (PathName[0] == L'\\'); - } - Status = InternalFileExists ( - Root, - Prefix != NULL ? &PathName[1] : &PathName[0] - ); - if (!EFI_ERROR(Status)) { - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Predefined %s %s was found\n", - Prefix != NULL ? Prefix : L"", - PathName - )); - if (DevicePath != NULL) { - // - // Append volume directory prefix if any. - // - if (Prefix != NULL) { - ASSERT (Prefix[0] != L'\\'); - FullPathSize = StrSize (Prefix) + StrSize (PathName); - FullPath = AllocatePool (FullPathSize); - if (FullPath != NULL) { - UnicodeSPrint (FullPath, FullPathSize, L"\\%s%s", Prefix, PathName); - *DevicePath = FileDevicePath (Device, FullPath); - FreePool (FullPath); - } else { - return EFI_OUT_OF_RESOURCES; - } - } else { - *DevicePath = FileDevicePath (Device, PathName); - } - } - ASSERT (DevicePath == NULL || *DevicePath != NULL); - return EFI_SUCCESS; - } else { - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Predefined %s %s is missing - %r\n", - Prefix != NULL ? Prefix : L"", - PathName, - Status - )); - } - } - - return EFI_NOT_FOUND; -} - -STATIC -EFI_STATUS -InternalGetApfsVolumeInfo ( - IN EFI_HANDLE Device, - OUT EFI_GUID *ContainerGuid, - OUT EFI_GUID *VolumeGuid, - OUT APPLE_APFS_VOLUME_ROLE *VolumeRole - ) -{ - EFI_STATUS Status; - - EFI_FILE_PROTOCOL *Root; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - APPLE_APFS_CONTAINER_INFO *ApfsContainerInfo; - APPLE_APFS_VOLUME_INFO *ApfsVolumeInfo; - - Root = NULL; - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = InternalGetApfsSpecialFileInfo (Root, &ApfsVolumeInfo, &ApfsContainerInfo); - - Root->Close (Root); - - if (EFI_ERROR(Status)) { - return EFI_NOT_FOUND; - } - - CopyGuid ( - VolumeGuid, - &ApfsVolumeInfo->Uuid - ); - - *VolumeRole = ApfsVolumeInfo->Role; - - CopyGuid ( - ContainerGuid, - &ApfsContainerInfo->Uuid - ); - - FreePool (ApfsVolumeInfo); - FreePool (ApfsContainerInfo); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -InternalGetBooterFromApfsVolumePredefinedPathList ( - IN EFI_HANDLE Device, - IN EFI_FILE_PROTOCOL *PrebootRoot, - IN CHAR16 *VolumeDirectoryName, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL *VolumeDirectoryHandle; - EFI_FILE_INFO *VolumeDirectoryInfo; - - Status = SafeFileOpen ( - PrebootRoot, - &VolumeDirectoryHandle, - VolumeDirectoryName, - EFI_FILE_MODE_READ, - 0 - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Missing partition %s on preboot - %r\n", VolumeDirectoryName, Status)); - return Status; - } else { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Found partition %s on preboot\n", VolumeDirectoryName)); - } - - VolumeDirectoryInfo = GetFileInfo ( - VolumeDirectoryHandle, - &gEfiFileInfoGuid, - sizeof (*VolumeDirectoryInfo), - NULL - ); - - if (VolumeDirectoryInfo == NULL) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Missing volume file info %s - %r\n", VolumeDirectoryName, Status)); - VolumeDirectoryHandle->Close (VolumeDirectoryHandle); - return EFI_NOT_FOUND; - } - - Status = EFI_NOT_FOUND; - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Want predefined list for APFS %u at %s\n", - VolumeDirectoryInfo->Attribute, - VolumeDirectoryName - )); - - if ((VolumeDirectoryInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { - Status = OcGetBooterFromPredefinedPathList ( - Device, - VolumeDirectoryHandle, - PredefinedPaths, - NumPredefinedPaths, - DevicePath, - VolumeDirectoryName - ); - } - - FreePool (VolumeDirectoryInfo); - VolumeDirectoryHandle->Close (VolumeDirectoryHandle); - - return Status; -} - -/** - APFS boot happens from Preboot volume, which normally contains blessed file - or folder. In case blessed path location fails, we iterate every volume - within the container, and try to locate a predefined booter path on Preboot - volume (e.g. Preboot://{VolumeUuid}/System/Library/CoreServices/boot.efi). -**/ -STATIC -EFI_STATUS -InternalGetBooterFromApfsPredefinedPathList ( - IN EFI_HANDLE Device, - IN EFI_FILE_PROTOCOL *PrebootRoot, - IN CONST GUID *ContainerUuid, - IN CONST CHAR16 *VolumeUuid OPTIONAL, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - OUT EFI_HANDLE *VolumeHandle OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_STATUS TmpStatus; - - UINTN NumberOfHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *HandleRoot; - APPLE_APFS_CONTAINER_INFO *ContainerInfo; - APPLE_APFS_VOLUME_INFO *VolumeInfo; - CHAR16 VolumeDirectoryName[GUID_STRING_LENGTH+1]; - EFI_DEVICE_PATH_PROTOCOL *VolumeDevPath; - EFI_DEVICE_PATH_PROTOCOL *TempDevPath; - BOOLEAN ContainerMatch; - - ASSERT (VolumeUuid == NULL || (VolumeUuid != NULL && VolumeHandle != NULL && *VolumeHandle == NULL)); - - NumberOfHandles = 0; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumberOfHandles, - &HandleBuffer - ); - - DEBUG ((DEBUG_BULK_INFO, "OCBP: %u filesystems for APFS - %r\n", (UINT32) NumberOfHandles, Status)); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - for (Index = 0; Index < NumberOfHandles; ++Index) { - TmpStatus = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR (TmpStatus)) { - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Borked APFS filesystem %u of %u - %r\n", - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - TmpStatus - )); - continue; - } - - TmpStatus = FileSystem->OpenVolume (FileSystem, &HandleRoot); - if (EFI_ERROR (TmpStatus)) { - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Borked APFS root volume %u of %u - %r\n", - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - TmpStatus - )); - continue; - } - - TmpStatus = InternalGetApfsSpecialFileInfo (HandleRoot, &VolumeInfo, &ContainerInfo); - - HandleRoot->Close (HandleRoot); - - if (EFI_ERROR (TmpStatus)) { - DEBUG (( - DEBUG_VERBOSE, - "OCBP: No APFS info %u of %u - %r\n", - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - TmpStatus - )); - continue; - } - - ContainerMatch = CompareGuid (&ContainerInfo->Uuid, ContainerUuid); - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: APFS match container %g vs %g for %u of %u - %d\n", - &ContainerInfo->Uuid, - ContainerUuid, - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - ContainerMatch - )); - - if (!ContainerMatch) { - FreePool (ContainerInfo); - FreePool (VolumeInfo); - continue; - } - - UnicodeSPrint ( - VolumeDirectoryName, - sizeof (VolumeDirectoryName), - L"%g", - &VolumeInfo->Uuid - ); - - FreePool (ContainerInfo); - FreePool (VolumeInfo); - - if (VolumeUuid != NULL && StrStr (VolumeUuid, VolumeDirectoryName) != NULL) { - *VolumeHandle = HandleBuffer[Index]; - } - - TmpStatus = InternalGetBooterFromApfsVolumePredefinedPathList ( - Device, - PrebootRoot, - VolumeDirectoryName, - PredefinedPaths, - NumPredefinedPaths, - DevicePath != NULL ? &VolumeDevPath : NULL - ); - - if (EFI_ERROR (TmpStatus)) { - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: No APFS booter %u of %u for %s - %r\n", - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - VolumeDirectoryName, - TmpStatus - )); - } else { - Status = EFI_SUCCESS; - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: Found APFS booter %u of %u for %s (%p)\n", - (UINT32) (Index + 1), - (UINT32) NumberOfHandles, - VolumeDirectoryName, - DevicePath - )); - - if (DevicePath != NULL) { - TempDevPath = *DevicePath; - *DevicePath = OcAppendDevicePathInstanceDedupe ( - TempDevPath, - VolumeDevPath - ); - if (TempDevPath != NULL) { - FreePool (TempDevPath); - } - } - } - } - - FreePool (HandleBuffer); - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: APFS bless for %g:%s is %r\n", - ContainerUuid, - VolumeUuid, - Status - )); - - return Status; -} - -STATIC -BOOLEAN -HasValidGuidStringPrefix ( - IN CONST CHAR16 *String - ) -{ - UINTN Length; - UINTN Index; - UINTN GuidLength = GUID_STRING_LENGTH; - - Length = StrLen (String); - if (Length < GuidLength) { - return FALSE; - } - - for (Index = 0; Index < GuidLength; ++Index) { - if (Index == 8 || Index == 13 || Index == 18 || Index == 23) { - if (String[Index] != '-') { - return FALSE; - } - } else if (!(String[Index] >= L'0' && String[Index] <= L'9') - && !(String[Index] >= L'A' && String[Index] <= L'F') - && !(String[Index] >= L'a' && String[Index] <= L'f')) { - return FALSE; - } - } - - return TRUE; -} - -STATIC -EFI_STATUS -InternalGetBootPathName ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName - ) -{ - UINTN Size; - CHAR16 *PathName; - UINTN PathNameSize; - FILEPATH_DEVICE_PATH *FilePath; - CHAR16 *Slash; - UINTN Len; - CHAR16 *FilePathName; - - if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) - && (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) { - FilePath = (FILEPATH_DEVICE_PATH *) DevicePath; - - Size = OcFileDevicePathNameSize (FilePath); - - PathNameSize = Size + sizeof (CHAR16); - PathName = AllocateZeroPool (PathNameSize); - - if (PathName == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (PathName, FilePath->PathName, Size); - - Slash = StrStr (PathName, L"\\"); - - if (Slash != NULL) { - Len = StrLen (PathName); - - FilePathName = &PathName[Len - 1]; - - while (*FilePathName != L'\\') { - *FilePathName = L'\0'; - --FilePathName; - } - } else { - StrCpyS (PathName, PathNameSize, L"\\"); - } - } else { - PathName = AllocateZeroPool (sizeof (L"\\")); - - if (PathName == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - StrCpyS (PathName, sizeof (L"\\"), L"\\"); - } - - *BootPathName = PathName; - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -InternalGetApfsVolumeHandle ( - IN EFI_HANDLE DeviceHandle, - IN CHAR16 *PathName, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_HANDLE *ApfsVolumeHandle - ) -{ - EFI_STATUS Status; - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *Root; - APPLE_APFS_CONTAINER_INFO *ContainerInfo; - CHAR16 *FilePathName; - - FilePathName = &PathName[0]; - - if (PathName[0] == L'\\') { - FilePathName = &PathName[1]; - } - - if (!HasValidGuidStringPrefix (FilePathName)) { - return EFI_INVALID_PARAMETER; - } - - Status = gBS->HandleProtocol ( - DeviceHandle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = InternalGetApfsSpecialFileInfo (Root, NULL, &ContainerInfo); - if (!EFI_ERROR(Status)) { - // - // FIXME: ApfsVolumeHandle is only returned when a predefined path exists - // - Status = InternalGetBooterFromApfsPredefinedPathList ( - DeviceHandle, - Root, - &ContainerInfo->Uuid, - FilePathName, - PredefinedPaths, - NumPredefinedPaths, - NULL, - ApfsVolumeHandle - ); - - FreePool (ContainerInfo); - } - - Root->Close (Root); - - return Status; -} - -EFI_STATUS -OcBootPolicyGetBootFile ( - IN EFI_HANDLE Device, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - EFI_STATUS Status; - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *Root; - - ASSERT (Device != NULL); - ASSERT (FilePath != NULL); - - *FilePath = NULL; - Root = NULL; - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = InternalGetBooterFromBlessedSystemFilePath (Root, FilePath); - if (EFI_ERROR(Status)) { - Status = InternalGetBooterFromBlessedSystemFolderPath (Device, Root, FilePath); - if (EFI_ERROR(Status)) { - Status = OcGetBooterFromPredefinedPathList ( - Device, - Root, - PredefinedPaths, - NumPredefinedPaths, - FilePath, - NULL - ); - } - } - - Root->Close (Root); - - return Status; -} - -EFI_STATUS -EFIAPI -BootPolicyGetBootFile ( - IN EFI_HANDLE Device, - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - if (Device == NULL || FilePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - return OcBootPolicyGetBootFile ( - Device, - gAppleBootPolicyPredefinedPaths, - ARRAY_SIZE (gAppleBootPolicyPredefinedPaths), - FilePath - ); -} - -EFI_STATUS -OcBootPolicyGetBootFileEx ( - IN EFI_HANDLE Device, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - EFI_STATUS Status; - EFI_STATUS TmpStatus; - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *Root; - APPLE_APFS_CONTAINER_INFO *ContainerInfo; - APPLE_APFS_VOLUME_INFO *VolumeInfo; - - ASSERT (Device != NULL); - ASSERT (FilePath != NULL); - - *FilePath = NULL; - Root = NULL; - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Missing filesystem - %r\n", Status)); - return Status; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: Invalid root volume - %r\n", Status)); - return Status; - } - - Status = InternalGetApfsSpecialFileInfo (Root, &VolumeInfo, &ContainerInfo); - if (!EFI_ERROR(Status)) { - Status = EFI_NOT_FOUND; - if ((VolumeInfo->Role & APPLE_APFS_VOLUME_ROLE_PREBOOT) != 0) { - TmpStatus = InternalGetBooterFromBlessedSystemFilePath (Root, FilePath); - if (EFI_ERROR (TmpStatus)) { - TmpStatus = InternalGetBooterFromBlessedSystemFolderPath (Device, Root, FilePath); - } - - // - // Blessed entry is always first, and subsequent entries are added with deduplication. - // - Status = InternalGetBooterFromApfsPredefinedPathList ( - Device, - Root, - &ContainerInfo->Uuid, - NULL, - PredefinedPaths, - NumPredefinedPaths, - FilePath, - NULL - ); - if (!EFI_ERROR (TmpStatus)) { - Status = TmpStatus; - } - } - - FreePool (VolumeInfo); - FreePool (ContainerInfo); - } else { - Status = InternalGetBooterFromBlessedSystemFilePath (Root, FilePath); - if (EFI_ERROR(Status)) { - Status = InternalGetBooterFromBlessedSystemFolderPath (Device, Root, FilePath); - if (EFI_ERROR(Status)) { - Status = OcGetBooterFromPredefinedPathList ( - Device, - Root, - PredefinedPaths, - NumPredefinedPaths, - FilePath, - NULL - ); - } - } - } - - Root->Close (Root); - - return Status; -} - -EFI_STATUS -EFIAPI -BootPolicyGetBootFileEx ( - IN EFI_HANDLE Device, - IN BOOT_POLICY_ACTION Action, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath - ) -{ - if (Device == NULL || FilePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - return OcBootPolicyGetBootFileEx ( - Device, - gAppleBootPolicyPredefinedPaths, - ARRAY_SIZE (gAppleBootPolicyPredefinedPaths), - FilePath - ); -} - -EFI_STATUS -OcBootPolicyDevicePathToDirPath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device - ) -{ - EFI_STATUS Status; - - ASSERT (DevicePath != NULL); - ASSERT (BootPathName != NULL); - ASSERT (Device != NULL); - - *BootPathName = NULL; - *Device = NULL; - - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - &DevicePath, - Device - ); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = InternalGetBootPathName (DevicePath, BootPathName); - if (EFI_ERROR(Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -OcBootPolicyDevicePathToDirPathAndApfsHandle ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device, - OUT EFI_HANDLE *ApfsVolumeHandle - ) -{ - EFI_STATUS Status; - - ASSERT (DevicePath != NULL); - ASSERT (BootPathName != NULL); - ASSERT (Device != NULL); - ASSERT (ApfsVolumeHandle != NULL); - - Status = OcBootPolicyDevicePathToDirPath ( - DevicePath, - BootPathName, - Device - ); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // InternalGetApfsVolumeHandle status code is ignored, as ApfsVolumeHandle - // may not exist. - // - *ApfsVolumeHandle = NULL; - (VOID) InternalGetApfsVolumeHandle ( - *Device, - *BootPathName, - PredefinedPaths, - NumPredefinedPaths, - ApfsVolumeHandle - ); - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -BootPolicyDevicePathToDirPath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT CHAR16 **BootPathName, - OUT EFI_HANDLE *Device, - OUT EFI_HANDLE *ApfsVolumeHandle - ) -{ - EFI_STATUS Status; - - if (DevicePath == NULL - || BootPathName == NULL - || Device == NULL - || ApfsVolumeHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = OcBootPolicyDevicePathToDirPathAndApfsHandle ( - DevicePath, - gAppleBootPolicyPredefinedPaths, - ARRAY_SIZE (gAppleBootPolicyPredefinedPaths), - BootPathName, - Device, - ApfsVolumeHandle - ); - if (EFI_ERROR(Status)) { - *BootPathName = NULL; - *Device = NULL; - *ApfsVolumeHandle = NULL; - return Status; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -OcBootPolicyGetApfsRecoveryFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *PathName, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - OUT CHAR16 **FullPathName, - OUT EFI_FILE_PROTOCOL **Root, - OUT EFI_HANDLE *DeviceHandle - ) -{ - EFI_STATUS Result; - - EFI_STATUS Status; - - CHAR16 *BootPathName; - EFI_HANDLE Device; - EFI_HANDLE VolumeHandle; - - GUID ContainerGuid; - GUID VolumeGuid; - APPLE_APFS_VOLUME_ROLE VolumeRole; - - GUID ContainerGuid2; - GUID VolumeGuid2; - APPLE_APFS_VOLUME_ROLE VolumeRole2; - - UINTN NoHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - - CHAR16 *FullPathBuffer; - UINTN FullPathNameSize; - - EFI_FILE_PROTOCOL *NewHandle; - - EFI_FILE_INFO *FileInfo; - - ASSERT (DevicePath != NULL); - ASSERT (PathName != NULL); - ASSERT (FullPathName != NULL); - ASSERT (Root != NULL); - ASSERT (DeviceHandle != NULL); - - NewHandle = NULL; - *Root = NULL; - *FullPathName = NULL; - - Status = OcBootPolicyDevicePathToDirPathAndApfsHandle ( - DevicePath, - PredefinedPaths, - NumPredefinedPaths, - &BootPathName, - &Device, - &VolumeHandle - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: APFS recovery boot info failed - %r\n", Status)); - return EFI_NOT_FOUND; - } - - if (VolumeHandle == NULL) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: APFS recovery volume handle missing - %s\n", BootPathName)); - FreePool (BootPathName); - return EFI_NOT_FOUND; - } - - FreePool (BootPathName); - - Status = InternalGetApfsVolumeInfo ( - VolumeHandle, - &ContainerGuid, - &VolumeGuid, - &VolumeRole - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: APFS recovery volume info missing\n")); - return EFI_NOT_FOUND; - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NoHandles, - &HandleBuffer - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_BULK_INFO, "OCBP: APFS recovery simple fs missing - %r\n", Status)); - return Status; - } - - Result = EFI_NOT_FOUND; - - for (Index = 0; Index < NoHandles; ++Index) { - ZeroMem (&ContainerGuid2, sizeof (ContainerGuid2)); - ZeroMem (&VolumeGuid2, sizeof (VolumeGuid2)); - VolumeRole2 = 0; - - Status = InternalGetApfsVolumeInfo ( - HandleBuffer[Index], - &ContainerGuid2, - &VolumeGuid2, - &VolumeRole2 - ); - - DEBUG (( - DEBUG_BULK_INFO, - "OCBP: APFS recovery info %u/%u due to %g/%g/%X - %r\n", - (UINT32) Index, - (UINT32) NoHandles, - &ContainerGuid2, - &ContainerGuid, - (UINT32) VolumeRole2, - Status - )); - - if (EFI_ERROR(Status) - || VolumeRole2 != APPLE_APFS_VOLUME_ROLE_RECOVERY - || !CompareGuid (&ContainerGuid2, &ContainerGuid)) { - continue; - } - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR(Status)) { - continue; - } - - Status = FileSystem->OpenVolume (FileSystem, Root); - if (EFI_ERROR(Status)) { - continue; - } - - FullPathNameSize = sizeof (CHAR16) + StrSize (PathName); - FullPathNameSize += GUID_STRING_LENGTH * sizeof (CHAR16); - FullPathBuffer = AllocateZeroPool (FullPathNameSize); - - if (FullPathBuffer == NULL) { - (*Root)->Close (*Root); - continue; - } - - // - // Note, this \\ prefixing does not exist in Apple code, and should not be required, - // but we add it for return path consistency. - // - UnicodeSPrint ( - FullPathBuffer, - FullPathNameSize, - L"\\%g%s", - &VolumeGuid, - PathName - ); - - Status = SafeFileOpen ( - *Root, - &NewHandle, - FullPathBuffer, - EFI_FILE_MODE_READ, - 0 - ); - - if (EFI_ERROR(Status)) { - (*Root)->Close (*Root); - FreePool (FullPathBuffer); - continue; - } - - FileInfo = GetFileInfo ( - NewHandle, - &gEfiFileInfoGuid, - sizeof (*FileInfo), - NULL - ); - - if (FileInfo != NULL) { - if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { - *FullPathName = FullPathBuffer; - *DeviceHandle = HandleBuffer[Index]; - Result = EFI_SUCCESS; - } - - FreePool (FileInfo); - } - - NewHandle->Close (NewHandle); - - if (!EFI_ERROR (Result)) { - break; - } - - (*Root)->Close (*Root); - FreePool (FullPathBuffer); - } - - FreePool (HandleBuffer); - - return Result; -} - -EFI_STATUS -EFIAPI -BootPolicyGetApfsRecoveryFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *PathName, - OUT CHAR16 **FullPathName, - OUT VOID **Reserved, - OUT EFI_FILE_PROTOCOL **Root, - OUT EFI_HANDLE *DeviceHandle - ) -{ - if (DevicePath == NULL - || PathName == NULL - || FullPathName == NULL - || Reserved == NULL - || Root == NULL - || DeviceHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Reserved = NULL; - - return OcBootPolicyGetApfsRecoveryFilePath ( - DevicePath, - PathName, - gAppleBootPolicyPredefinedPaths, - ARRAY_SIZE (gAppleBootPolicyPredefinedPaths), - FullPathName, - Root, - DeviceHandle - ); -} - -EFI_STATUS -OcBootPolicyGetAllApfsRecoveryFilePath ( - IN EFI_HANDLE Handle OPTIONAL, - OUT VOID **Volumes, - OUT UINTN *NumberOfEntries - ) -{ - EFI_STATUS Status; - - UINTN NumberOfHandles; - EFI_HANDLE *HandleBuffer; - APFS_VOLUME_INFO *VolumeInfo; - GUID *ContainerGuids; - UINTN NumberOfContainers; - UINTN NumberOfVolumeInfos; - UINTN Index; - UINTN Index2; - UINTN Index3; - APFS_VOLUME_ROOT **ApfsVolumes; - BOOLEAN GuidPresent; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *Root; - EFI_FILE_PROTOCOL *NewHandle; - CHAR16 VolumePathName[GUID_STRING_LENGTH + 1]; - EFI_FILE_INFO *FileInfo; - APFS_VOLUME_ROOT *ApfsRoot; - - ASSERT (Volumes != NULL); - ASSERT (NumberOfEntries != NULL); - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumberOfHandles, - &HandleBuffer - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - VolumeInfo = AllocateZeroPool (NumberOfHandles * sizeof (*VolumeInfo)); - ContainerGuids = AllocateZeroPool (NumberOfHandles * sizeof (*ContainerGuids)); - - if (VolumeInfo == NULL || ContainerGuids == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } - - if (EFI_ERROR(Status)) { - FreePool (HandleBuffer); - - if (VolumeInfo != NULL) { - FreePool (VolumeInfo); - } - - if (ContainerGuids != NULL) { - FreePool (ContainerGuids); - } - - return Status; - } - - NumberOfVolumeInfos = 0; - NumberOfContainers = 0; - - for (Index = 0; Index < NumberOfHandles; ++Index) { - Status = InternalGetApfsVolumeInfo ( - HandleBuffer[Index], - &VolumeInfo[NumberOfVolumeInfos].ContainerGuid, - &VolumeInfo[NumberOfVolumeInfos].VolumeGuid, - &VolumeInfo[NumberOfVolumeInfos].VolumeRole - ); - - if (EFI_ERROR(Status)) { - continue; - } - - VolumeInfo[NumberOfVolumeInfos].Handle = HandleBuffer[Index]; - - GuidPresent = FALSE; - for (Index2 = 0; Index2 < NumberOfContainers; ++Index2) { - if (CompareGuid (&ContainerGuids[Index2], &VolumeInfo[NumberOfVolumeInfos].ContainerGuid)) { - GuidPresent = TRUE; - break; - } - } - - if (!GuidPresent) { - CopyGuid ( - &ContainerGuids[NumberOfContainers], - &VolumeInfo[NumberOfVolumeInfos].ContainerGuid - ); - - if (Index2 != 0 && HandleBuffer[Index] == Handle) { - CopyMem ( - &ContainerGuids[1], - &ContainerGuids[0], - NumberOfContainers * sizeof (ContainerGuids[0]) - ); - CopyGuid ( - &ContainerGuids[0], - &VolumeInfo[NumberOfVolumeInfos].ContainerGuid - ); - } - - ++NumberOfContainers; - } - - ++NumberOfVolumeInfos; - } - - Status = EFI_SUCCESS; - - if (NumberOfVolumeInfos > 0) { - ApfsVolumes = AllocateZeroPool ( - NumberOfVolumeInfos * sizeof (*ApfsVolumes) - ); - if (ApfsVolumes == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } - } else { - Status = EFI_NOT_FOUND; - } - - if (EFI_ERROR(Status)) { - FreePool (HandleBuffer); - FreePool (VolumeInfo); - FreePool (ContainerGuids); - return Status; - } - - *Volumes = ApfsVolumes; - *NumberOfEntries = 0; - - for (Index = 0; Index < NumberOfContainers; ++Index) { - for (Index2 = 0; Index2 < NumberOfVolumeInfos; ++Index2) { - if ((VolumeInfo[Index2].VolumeRole & APPLE_APFS_VOLUME_ROLE_RECOVERY) == 0 - || !CompareGuid (&ContainerGuids[Index], &VolumeInfo[Index2].ContainerGuid)) { - continue; - } - - Status = gBS->HandleProtocol ( - VolumeInfo[Index2].Handle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR(Status)) { - continue; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - if (EFI_ERROR(Status)) { - continue; - } - - // - // Locate recovery for every volume present. - // - for (Index3 = 0; Index3 < NumberOfVolumeInfos; ++Index3) { - if ((VolumeInfo[Index2].VolumeRole & - (APPLE_APFS_VOLUME_ROLE_RECOVERY|APPLE_APFS_VOLUME_ROLE_PREBOOT)) != 0 - || !CompareGuid (&ContainerGuids[Index], &VolumeInfo[Index3].ContainerGuid)) { - continue; - } - - UnicodeSPrint ( - VolumePathName, - sizeof (VolumePathName), - L"%g", - &VolumeInfo[Index3].VolumeGuid - ); - - Status = SafeFileOpen ( - Root, - &NewHandle, - VolumePathName, - EFI_FILE_MODE_READ, - 0 - ); - - if (EFI_ERROR(Status)) { - continue; - } - - FileInfo = GetFileInfo ( - NewHandle, - &gEfiFileInfoGuid, - sizeof (*FileInfo), - NULL - ); - - NewHandle->Close (NewHandle); - - if (FileInfo != NULL) { - if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { - ApfsRoot = ApfsVolumes[*NumberOfEntries]; - ApfsRoot->Handle = VolumeInfo[Index2].Handle; - ApfsRoot->VolumeDirName = AllocateCopyPool ( - StrSize (VolumePathName), - VolumePathName - ); - ApfsRoot->Root = Root; - - ++(*NumberOfEntries); - } - FreePool (FileInfo); - } - } - } - } - - FreePool (VolumeInfo); - FreePool (ContainerGuids); - FreePool (HandleBuffer); - - if (!EFI_ERROR(Status) && *NumberOfEntries == 0) { - Status = EFI_NOT_FOUND; - } - - return Status; -} - -EFI_STATUS -EFIAPI -BootPolicyGetAllApfsRecoveryFilePath ( - IN EFI_HANDLE Handle OPTIONAL, - OUT VOID **Volumes, - OUT UINTN *NumberOfEntries - ) -{ - if (Volumes == NULL || NumberOfEntries == NULL) { - return EFI_INVALID_PARAMETER; - } - - return OcBootPolicyGetAllApfsRecoveryFilePath ( - Handle, - Volumes, - NumberOfEntries - ); -} - -APPLE_BOOT_POLICY_PROTOCOL * -OcAppleBootPolicyInstallProtocol ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - - APPLE_BOOT_POLICY_PROTOCOL *Protocol; - EFI_HANDLE Handle; - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gAppleBootPolicyProtocolGuid); - if (EFI_ERROR(Status)) { - // DEBUG ((DEBUG_ERROR, "OCBP: Uninstall failed: %r\n", Status)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gAppleBootPolicyProtocolGuid, - NULL, - (VOID *) &Protocol - ); - - if (!EFI_ERROR(Status)) { - return Protocol; - } - } - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gAppleBootPolicyProtocolGuid, - (VOID **) &mAppleBootPolicyProtocol, - NULL - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - return &mAppleBootPolicyProtocol; -} diff --git a/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf b/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf deleted file mode 100644 index 6566c1177..000000000 --- a/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf +++ /dev/null @@ -1,64 +0,0 @@ -## @file -# -# Component description file for the library producing the Apple Device property protocol. -# -# Copyright (C) 2019, vit9696. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleBootPolicyLib - FILE_GUID = 330E9083-C008-4030-AA86-ECF1FBAE824D - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleBootPolicyLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - OcAppleBootPolicyLib.c - ../../Include/Library/OcAppleBootPolicyLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[Guids] - gAppleApfsContainerInfoGuid ## SOMETIMES_CONSUMES - gAppleApfsVolumeInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedSystemFileInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedSystemFolderInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedOsxFolderInfoGuid ## SOMETIMES_CONSUMES - gEfiFileInfoGuid ## SOMETIMES_CONSUMES - -[Protocols] - gAppleBootPolicyProtocolGuid ## PRODUCES - gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - MemoryAllocationLib - PrintLib - UefiBootServicesTableLib - OcGuardLib - OcFileLib - OcXmlLib diff --git a/Library/OcAppleChunklistLib/OcAppleChunklistLib.c b/Library/OcAppleChunklistLib/OcAppleChunklistLib.c deleted file mode 100644 index 85ff2414a..000000000 --- a/Library/OcAppleChunklistLib/OcAppleChunklistLib.c +++ /dev/null @@ -1,194 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -BOOLEAN -OcAppleChunklistInitializeContext ( - OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN OUT VOID *Buffer, - IN UINT32 BufferSize - ) -{ - APPLE_CHUNKLIST_HEADER *ChunklistHeader; - UINTN DataEnd; - UINT8 *Signature; - UINT32 SigLength; - UINT32 Index; - UINT8 SwapValue; - - ASSERT (Buffer != NULL); - ASSERT (BufferSize > 0); - ASSERT (Context != NULL); - - ChunklistHeader = (APPLE_CHUNKLIST_HEADER *) Buffer; - - if (BufferSize < sizeof (APPLE_CHUNKLIST_HEADER)) { - return FALSE; - } - - // - // Ensure the header is compatible. - // - if (ChunklistHeader->Magic != APPLE_CHUNKLIST_MAGIC - || ChunklistHeader->Length != sizeof (APPLE_CHUNKLIST_HEADER) - || ChunklistHeader->FileVersion != APPLE_CHUNKLIST_FILE_VERSION_10 - || ChunklistHeader->ChunkMethod != APPLE_CHUNKLIST_CHUNK_METHOD_10 - || ChunklistHeader->SigMethod != APPLE_CHUNKLIST_SIG_METHOD_10) { - return FALSE; - } - - // - // Ensure that chunk and signature addresses are valid in the first place. - // - if (OcOverflowAddUN ((UINTN) Buffer, (UINTN) ChunklistHeader->ChunkOffset, (UINTN *) &Context->Chunks) - || OcOverflowAddUN ((UINTN) Buffer, (UINTN) ChunklistHeader->SigOffset, (UINTN *) &Context->Signature)) { - return FALSE; - } - - // - // Ensure that chunks and signature reside within Buffer. - // - if (ChunklistHeader->ChunkCount > MAX_UINTN) { - return FALSE; - } - - Context->ChunkCount = (UINTN)ChunklistHeader->ChunkCount; - - if (OcOverflowMulAddUN (sizeof (APPLE_CHUNKLIST_CHUNK), Context->ChunkCount, (UINTN) Context->Chunks, &DataEnd) - || DataEnd > (UINTN) Buffer + BufferSize - || OcOverflowAddUN (sizeof (APPLE_CHUNKLIST_SIG), (UINTN) Context->Signature, &DataEnd) - || DataEnd != (UINTN) Buffer + BufferSize) { - return FALSE; - } - - // - // Prepare signature verification data. - // - Sha256 (Context->Hash, (UINT8 *)ChunklistHeader, (UINTN)ChunklistHeader->SigOffset); - - Signature = Context->Signature->Signature; - SigLength = sizeof (Context->Signature->Signature); - - for (Index = 0; Index < (SigLength / 2); ++Index) { - SwapValue = Signature[Index]; - Signature[Index] = Signature[SigLength - Index - 1]; - Signature[SigLength - Index - 1] = SwapValue; - } - - return TRUE; -} - -BOOLEAN -OcAppleChunklistVerifySignature ( - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN CONST OC_RSA_PUBLIC_KEY *PublicKey - ) -{ - BOOLEAN Result; - - ASSERT (Context != NULL); - ASSERT (Context->Signature != NULL); - - Result = RsaVerifySigHashFromKey ( - PublicKey, - Context->Signature->Signature, - sizeof (Context->Signature->Signature), - Context->Hash, - sizeof (Context->Hash), - OcSigHashTypeSha256 - ); - DEBUG_CODE ( - if (Result) { - Context->Signature = NULL; - } - ); - - return Result; -} - -BOOLEAN -OcAppleChunklistVerifyData ( - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *Context, - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable - ) -{ - BOOLEAN Result; - - UINTN Index; - UINT8 ChunkHash[SHA256_DIGEST_SIZE]; - CONST APPLE_CHUNKLIST_CHUNK *CurrentChunk; - UINTN CurrentOffset; - - UINT32 ChunkDataSize; - VOID *ChunkData; - - ASSERT (Context != NULL); - ASSERT (Context->Chunks != NULL); - ASSERT (ExtentTable != NULL); - - DEBUG_CODE ( - ASSERT (Context->Signature == NULL); - ); - - ChunkDataSize = 0; - for (Index = 0; Index < Context->ChunkCount; ++Index) { - CurrentChunk = &Context->Chunks[Index]; - if (ChunkDataSize < CurrentChunk->Length) { - ChunkDataSize = CurrentChunk->Length; - } - } - - ChunkData = AllocatePool (ChunkDataSize); - if (ChunkData == NULL) { - return FALSE; - } - - CurrentOffset = 0; - for (Index = 0; Index < Context->ChunkCount; Index++) { - CurrentChunk = &Context->Chunks[Index]; - - Result = OcAppleRamDiskRead ( - ExtentTable, - CurrentOffset, - CurrentChunk->Length, - ChunkData - ); - if (!Result) { - FreePool (ChunkData); - return FALSE; - } - // - // Calculate checksum of data and ensure they match. - // - DEBUG ((DEBUG_VERBOSE, "OCCL: Validating chunk %lu of %lu\n", - (UINT64)Index + 1, (UINT64)Context->ChunkCount)); - Sha256 (ChunkHash, ChunkData, CurrentChunk->Length); - if (CompareMem (ChunkHash, CurrentChunk->Checksum, SHA256_DIGEST_SIZE) != 0) { - FreePool (ChunkData); - return FALSE; - } - - CurrentOffset += CurrentChunk->Length; - } - - FreePool (ChunkData); - return TRUE; -} diff --git a/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf b/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf deleted file mode 100644 index 27abdc1d6..000000000 --- a/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# Copyright (C) 2019, Goldfish64. All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleChunklistLib - FILE_GUID = D891DF81-0C83-47FF-ABAD-546050E1A07F - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleChunklistLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - OcAppleRamDiskLib - OcCryptoLib - UefiLib - -[Sources] - OcAppleChunklistLib.c - ../../Include/Library/OcAppleChunklistLib.h diff --git a/Library/OcAppleDiskImageLib/OcAppleDiskImageBlockIo.c b/Library/OcAppleDiskImageLib/OcAppleDiskImageBlockIo.c deleted file mode 100644 index a891712e1..000000000 --- a/Library/OcAppleDiskImageLib/OcAppleDiskImageBlockIo.c +++ /dev/null @@ -1,367 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcAppleDiskImageLibInternal.h" - -#define DMG_FILE_PATH_LEN (L_STR_LEN (L"DMG_.dmg") + 16 + 1) - -#pragma pack(push, 1) - -typedef PACKED struct { - VENDOR_DEFINED_DEVICE_PATH Vendor; - UINT64 Length; -} DMG_SIZE_DEVICE_PATH; - -typedef PACKED struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// A NULL-terminated Path string including directory and file names. - /// - CHAR16 PathName[DMG_FILE_PATH_LEN]; -} DMG_FILEPATH_DEVICE_PATH; - -typedef PACKED struct { - APPLE_RAM_DISK_DP_HEADER RamDisk; - DMG_FILEPATH_DEVICE_PATH FilePath; - DMG_SIZE_DEVICE_PATH Size; - EFI_DEVICE_PATH_PROTOCOL End; -} DMG_DEVICE_PATH; - -#pragma pack(pop) - -#define OC_APPLE_DISK_IMAGE_MOUNTED_DATA_SIGNATURE \ - SIGNATURE_32('D','m','g','I') - -#define OC_APPLE_DISK_IMAGE_MOUNTED_DATA_FROM_THIS(This) \ - BASE_CR ( \ - (This), \ - OC_APPLE_DISK_IMAGE_MOUNTED_DATA, \ - BlockIo \ - ) - -typedef struct { - UINT32 Signature; - - EFI_BLOCK_IO_PROTOCOL BlockIo; - EFI_BLOCK_IO_MEDIA BlockIoMedia; - DMG_DEVICE_PATH DevicePath; - - OC_APPLE_DISK_IMAGE_CONTEXT *ImageContext; -} OC_APPLE_DISK_IMAGE_MOUNTED_DATA; - -STATIC -EFI_STATUS -EFIAPI -DiskImageBlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -DiskImageBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - OC_APPLE_DISK_IMAGE_MOUNTED_DATA *DiskImageData; - BOOLEAN Result; - - if ((This == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((BufferSize % APPLE_DISK_IMAGE_SECTOR_SIZE) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - DiskImageData = OC_APPLE_DISK_IMAGE_MOUNTED_DATA_FROM_THIS (This); - if (DiskImageData->Signature == 0) { - return EFI_UNSUPPORTED; - } - - ASSERT (DiskImageData->Signature == OC_APPLE_DISK_IMAGE_MOUNTED_DATA_SIGNATURE); - - if (Lba >= DiskImageData->ImageContext->SectorCount) { - return EFI_INVALID_PARAMETER; - } - - Result = OcAppleDiskImageRead ( - DiskImageData->ImageContext, - (UINTN)Lba, - BufferSize, - Buffer - ); - if (!Result) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -DiskImageBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return EFI_WRITE_PROTECTED; -} - -STATIC -EFI_STATUS -EFIAPI -DiskImageBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - return EFI_SUCCESS; -} - -STATIC UINT32 mDmgCounter; ///< FIXME: This should exist on a protocol basis! - -STATIC -VOID -InternalConstructDmgDevicePath ( - IN OUT OC_APPLE_DISK_IMAGE_MOUNTED_DATA *DiskImageData, - IN UINTN FileSize - ) -{ - UINT64 RamDmgAddress; - DMG_DEVICE_PATH *DevPath; - CHAR16 *UnicodeDevPath; - - ASSERT (DiskImageData != NULL); - ASSERT (DiskImageData->ImageContext); - - RamDmgAddress = (UINTN)DiskImageData->ImageContext->ExtentTable; - - DevPath = &DiskImageData->DevicePath; - - DevPath->RamDisk.Vendor.Vendor.Header.Type = HARDWARE_DEVICE_PATH; - DevPath->RamDisk.Vendor.Vendor.Header.SubType = HW_VENDOR_DP; - CopyGuid ( - &DevPath->RamDisk.Vendor.Vendor.Guid, - &gAppleRamDiskProtocolGuid - ); - DevPath->RamDisk.Vendor.Counter = mDmgCounter++; - SetDevicePathNodeLength ( - &DevPath->RamDisk.Vendor, - sizeof (DevPath->RamDisk.Vendor) - ); - - DevPath->RamDisk.MemMap.Header.Type = HARDWARE_DEVICE_PATH; - DevPath->RamDisk.MemMap.Header.SubType = HW_MEMMAP_DP; - DevPath->RamDisk.MemMap.MemoryType = EfiACPIMemoryNVS; - DevPath->RamDisk.MemMap.StartingAddress = RamDmgAddress; - DevPath->RamDisk.MemMap.EndingAddress = RamDmgAddress + sizeof (APPLE_RAM_DISK_EXTENT_TABLE); - SetDevicePathNodeLength (&DevPath->RamDisk.MemMap, sizeof (DevPath->RamDisk.MemMap)); - - DevPath->FilePath.Header.Type = MEDIA_DEVICE_PATH; - DevPath->FilePath.Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength (&DevPath->FilePath, sizeof (DevPath->FilePath)); - UnicodeSPrint ( - DevPath->FilePath.PathName, - sizeof (DevPath->FilePath.PathName), - L"DMG_%16X.dmg", - FileSize - ); - - DevPath->Size.Vendor.Header.Type = MESSAGING_DEVICE_PATH; - DevPath->Size.Vendor.Header.SubType = MSG_VENDOR_DP; - DevPath->Size.Length = FileSize; - SetDevicePathNodeLength (&DevPath->Size, sizeof (DevPath->Size)); - CopyGuid ( - (VOID *)&DevPath->Size.Vendor.Guid, - &gAppleDiskImageProtocolGuid - ); - - SetDevicePathEndNode (&DevPath->End); - - DEBUG_CODE_BEGIN (); - ASSERT ( - IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) DevPath, sizeof (*DevPath)) - ); - - UnicodeDevPath = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)DevPath, FALSE, FALSE); - DEBUG ((DEBUG_INFO, "OCDI: Built DMG DP: %s\n", UnicodeDevPath != NULL ? UnicodeDevPath : L"")); - if (UnicodeDevPath != NULL) { - FreePool (UnicodeDevPath); - } - DEBUG_CODE_END (); -} - -STATIC CONST EFI_BLOCK_IO_PROTOCOL mDiskImageBlockIo = { - EFI_BLOCK_IO_PROTOCOL_REVISION, - NULL, - DiskImageBlockIoReset, - DiskImageBlockIoReadBlocks, - DiskImageBlockIoWriteBlocks, - DiskImageBlockIoFlushBlocks -}; - -EFI_HANDLE -OcAppleDiskImageInstallBlockIo ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN FileSize, - OUT CONST EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, - OUT UINTN *DevicePathSize OPTIONAL - ) -{ - EFI_HANDLE BlockIoHandle; - - EFI_STATUS Status; - OC_APPLE_DISK_IMAGE_MOUNTED_DATA *DiskImageData; - - ASSERT (Context != NULL); - ASSERT (FileSize > 0); - - DiskImageData = AllocateZeroPool (sizeof (*DiskImageData)); - if (DiskImageData == NULL) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to allocate DMG mount context\n")); - return NULL; - } - - DiskImageData->Signature = OC_APPLE_DISK_IMAGE_MOUNTED_DATA_SIGNATURE; - DiskImageData->ImageContext = Context; - CopyMem ( - &DiskImageData->BlockIo, - &mDiskImageBlockIo, - sizeof (DiskImageData->BlockIo) - ); - - DiskImageData->BlockIo.Media = &DiskImageData->BlockIoMedia; - DiskImageData->BlockIoMedia.MediaPresent = TRUE; - DiskImageData->BlockIoMedia.ReadOnly = TRUE; - DiskImageData->BlockIoMedia.BlockSize = APPLE_DISK_IMAGE_SECTOR_SIZE; - DiskImageData->BlockIoMedia.LastBlock = (Context->SectorCount - 1); - - InternalConstructDmgDevicePath (DiskImageData, FileSize); - - BlockIoHandle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &BlockIoHandle, - &gEfiDevicePathProtocolGuid, - &DiskImageData->DevicePath, - &gEfiBlockIoProtocolGuid, - &DiskImageData->BlockIo, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to install protocols %r\n", Status)); - FreePool (DiskImageData); - return NULL; - } - - Status = gBS->ConnectController (BlockIoHandle, NULL, NULL, TRUE); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to connect DMG handle %r\n", Status)); - - Status = gBS->UninstallMultipleProtocolInterfaces ( - BlockIoHandle, - &gEfiDevicePathProtocolGuid, - &DiskImageData->DevicePath, - &gEfiBlockIoProtocolGuid, - &DiskImageData->BlockIo, - NULL - ); - if (!EFI_ERROR(Status)) { - FreePool (DiskImageData); - } else { - DEBUG ((DEBUG_INFO, "OCDI: Failed to uninstall protocols %r\n", Status)); - DiskImageData->Signature = 0; - } - return NULL; - } - - if (DevicePath != NULL) { - *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&DiskImageData->DevicePath; - - if (DevicePathSize != NULL) { - *DevicePathSize = sizeof (DiskImageData->DevicePath); - } - } - - return BlockIoHandle; -} - -VOID -OcAppleDiskImageUninstallBlockIo ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN VOID *BlockIoHandle - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - OC_APPLE_DISK_IMAGE_MOUNTED_DATA *DiskImageData; - - ASSERT (Context != NULL); - ASSERT (BlockIoHandle != NULL); - - Status = gBS->HandleProtocol ( - BlockIoHandle, - &gEfiBlockIoProtocolGuid, - (VOID **)&BlockIo - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCDI: Invalid handle for Block I/O uninstall\n")); - return; - } - - DiskImageData = OC_APPLE_DISK_IMAGE_MOUNTED_DATA_FROM_THIS (BlockIo); - - Status = gBS->DisconnectController (BlockIoHandle, NULL, NULL); - Status |= gBS->UninstallMultipleProtocolInterfaces ( - BlockIoHandle, - &gEfiBlockIoProtocolGuid, - &DiskImageData->BlockIo, - &gEfiDevicePathProtocolGuid, - &DiskImageData->DevicePath, - NULL - ); - if (!EFI_ERROR(Status)) { - FreePool (DiskImageData); - } else { - DEBUG (( - DEBUG_INFO, - "OCDI: Failed to disconnect DMG controller or uninstal protocols\n" - )); - DiskImageData->Signature = 0; - } -} diff --git a/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.c b/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.c deleted file mode 100644 index 1d2c9cdba..000000000 --- a/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.c +++ /dev/null @@ -1,422 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcAppleDiskImageLibInternal.h" - -BOOLEAN -OcAppleDiskImageInitializeContext ( - OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN FileSize - ) -{ - BOOLEAN Result; - UINTN TrailerOffset; - APPLE_DISK_IMAGE_TRAILER Trailer; - UINT32 DmgBlockCount; - APPLE_DISK_IMAGE_BLOCK_DATA **DmgBlocks; - UINT32 SwappedSig; - UINT64 OffsetTop; - - UINT32 HeaderSize; - UINT64 DataForkOffset; - UINT64 DataForkLength; - UINT32 SegmentCount; - APPLE_DISK_IMAGE_CHECKSUM DataForkChecksum; - UINT64 XmlOffset; - UINT64 XmlLength; - UINT64 SectorCount; - - CHAR8 *PlistData; - - ASSERT (Context != NULL); - ASSERT (ExtentTable != NULL); - ASSERT (FileSize > 0); - - if (FileSize <= sizeof (Trailer)) { - DEBUG (( - DEBUG_INFO, - "OCDI: DMG file size error: %u/%u\n", - FileSize, - (UINT32) sizeof (Trailer) - )); - return FALSE; - } - - SwappedSig = SwapBytes32 (APPLE_DISK_IMAGE_MAGIC); - - TrailerOffset = (FileSize - sizeof (Trailer)); - - Result = OcAppleRamDiskRead ( - ExtentTable, - TrailerOffset, - sizeof (Trailer), - &Trailer - ); - if (!Result || (Trailer.Signature != SwappedSig)) { - DEBUG (( - DEBUG_INFO, - "OCDI: DMG trailer error: %d - %Lx/%Lx - %X/%X\n", - Result, - (UINT64) TrailerOffset, - (UINT64) FileSize, - SwappedSig, - Trailer.Signature - )); - return FALSE; - } - - HeaderSize = SwapBytes32 (Trailer.HeaderSize); - DataForkOffset = SwapBytes64 (Trailer.DataForkOffset); - DataForkLength = SwapBytes64 (Trailer.DataForkLength); - SegmentCount = SwapBytes32 (Trailer.SegmentCount); - XmlOffset = SwapBytes64 (Trailer.XmlOffset); - XmlLength = SwapBytes64 (Trailer.XmlLength); - SectorCount = SwapBytes64 (Trailer.SectorCount); - DataForkChecksum.Size = SwapBytes32 (Trailer.DataForkChecksum.Size); - - if ((HeaderSize != sizeof (Trailer)) - || (XmlLength == 0) - || (XmlLength > MAX_UINT32) - || (DataForkChecksum.Size > (sizeof (DataForkChecksum.Data) * 8)) - || (SectorCount == 0)) { - DEBUG (( - DEBUG_INFO, - "OCDI: DMG context error: %u/%Lu/%Lu/%u/%u\n", - HeaderSize, - XmlLength, - SectorCount, - DataForkChecksum.Size - )); - return FALSE; - } - - if ((SegmentCount != 0) && (SegmentCount != 1)) { - DEBUG ((DEBUG_ERROR, "OCDI: Multiple segments are unsupported\n")); - return FALSE; - } - - Result = OcOverflowMulU64 ( - SectorCount, - APPLE_DISK_IMAGE_SECTOR_SIZE, - &OffsetTop - ); - if (Result || (OffsetTop > MAX_UINTN)) { - DEBUG ((DEBUG_INFO, "OCDI: DMG sector error: %Lu %Lu\n", SectorCount, OffsetTop)); - return FALSE; - } - - Result = OcOverflowAddU64 ( - XmlOffset, - XmlLength, - &OffsetTop - ); - if (Result || (OffsetTop > TrailerOffset)) { - DEBUG ((DEBUG_INFO, "OCDI: DMG xml error: %Lu %Lu %Lu %Lu\n", XmlOffset, XmlLength, OffsetTop, TrailerOffset)); - return FALSE; - } - - Result = OcOverflowAddU64 ( - DataForkOffset, - DataForkLength, - &OffsetTop - ); - if (Result || (OffsetTop > TrailerOffset)) { - DEBUG ((DEBUG_INFO, "OCDI: DMG data error: %Lu %Lu %Lu %Lu\n", DataForkOffset, DataForkLength, OffsetTop, TrailerOffset)); - return FALSE; - } - - PlistData = AllocatePool ((UINT32)XmlLength); - if (PlistData == NULL) { - DEBUG ((DEBUG_INFO, "OCDI: DMG plist alloc error: %Lu\n", XmlLength)); - return FALSE; - } - - Result = OcAppleRamDiskRead ( - ExtentTable, - (UINTN)XmlOffset, - (UINTN)XmlLength, - PlistData - ); - if (!Result) { - DEBUG ((DEBUG_INFO, "OCDI: DMG plist read error: %Lu %Lu\n", XmlOffset, XmlLength)); - FreePool (PlistData); - return FALSE; - } - - Result = InternalParsePlist ( - PlistData, - (UINT32)XmlLength, - (UINTN)SectorCount, - (UINTN)DataForkOffset, - (UINTN)DataForkLength, - &DmgBlockCount, - &DmgBlocks - ); - - FreePool (PlistData); - - if (!Result) { - DEBUG ((DEBUG_INFO, "OCDI: DMG plist parse error: %Lu %Lu\n", XmlOffset, XmlLength)); - return FALSE; - } - - Context->ExtentTable = ExtentTable; - Context->BlockCount = DmgBlockCount; - Context->Blocks = DmgBlocks; - Context->SectorCount = (UINTN)SectorCount; - - return TRUE; -} - -BOOLEAN -OcAppleDiskImageInitializeFromFile ( - OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN EFI_FILE_PROTOCOL *File - ) -{ - EFI_STATUS Status; - BOOLEAN Result; - - UINT32 FileSize; - CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable; - - ASSERT (Context != NULL); - ASSERT (File != NULL); - - Status = GetFileSize (File, &FileSize); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to retrieve DMG file size\n")); - return FALSE; - } - - ExtentTable = OcAppleRamDiskAllocate (FileSize, EfiACPIMemoryNVS); - if (ExtentTable == NULL) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to allocate DMG data\n")); - return FALSE; - } - - Result = OcAppleRamDiskLoadFile (ExtentTable, File, FileSize); - if (!Result) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to load DMG file\n")); - - OcAppleRamDiskFree (ExtentTable); - return FALSE; - } - - Result = OcAppleDiskImageInitializeContext (Context, ExtentTable, FileSize); - if (!Result) { - DEBUG ((DEBUG_INFO, "OCDI: Failed to initialise DMG context\n")); - - OcAppleRamDiskFree (ExtentTable); - return FALSE; - } - - return TRUE; -} - -BOOLEAN -OcAppleDiskImageVerifyData ( - IN OUT OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN OUT OC_APPLE_CHUNKLIST_CONTEXT *ChunklistContext - ) -{ - ASSERT (Context != NULL); - ASSERT (ChunklistContext != NULL); - - return OcAppleChunklistVerifyData ( - ChunklistContext, - Context->ExtentTable - ); -} - -VOID -OcAppleDiskImageFreeContext ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context - ) -{ - UINT32 Index; - - ASSERT (Context != NULL); - - for (Index = 0; Index < Context->BlockCount; ++Index) { - FreePool (Context->Blocks[Index]); - } - - FreePool (Context->Blocks); -} - -VOID -OcAppleDiskImageFreeFile ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context - ) -{ - OcAppleRamDiskFree (Context->ExtentTable); - OcAppleDiskImageFreeContext (Context); -} - -BOOLEAN -OcAppleDiskImageRead ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - BOOLEAN Result; - - APPLE_DISK_IMAGE_BLOCK_DATA *BlockData; - APPLE_DISK_IMAGE_CHUNK *Chunk; - UINT64 ChunkTotalLength; - UINT64 ChunkLength; - UINT64 ChunkOffset; - UINT8 *ChunkData; - UINT8 *ChunkDataCompressed; - - UINTN LbaCurrent; - UINTN LbaOffset; - UINTN LbaLength; - UINTN RemainingBufferSize; - UINTN BufferChunkSize; - UINT8 *BufferCurrent; - - UINTN OutSize; - - ASSERT (Context != NULL); - ASSERT (Buffer != NULL); - ASSERT (Lba < Context->SectorCount); - - LbaCurrent = Lba; - RemainingBufferSize = BufferSize; - BufferCurrent = Buffer; - - while (RemainingBufferSize > 0) { - Result = InternalGetBlockChunk (Context, LbaCurrent, &BlockData, &Chunk); - if (!Result) { - return FALSE; - } - - LbaOffset = (LbaCurrent - (UINTN)DMG_SECTOR_START_ABS (BlockData, Chunk)); - LbaLength = ((UINTN)Chunk->SectorCount - LbaOffset); - - Result = OcOverflowMulU64 ( - LbaOffset, - APPLE_DISK_IMAGE_SECTOR_SIZE, - &ChunkOffset - ); - if (Result) { - return FALSE; - } - - Result = OcOverflowMulU64 ( - Chunk->SectorCount, - APPLE_DISK_IMAGE_SECTOR_SIZE, - &ChunkTotalLength - ); - if (Result) { - return FALSE; - } - - ChunkLength = (ChunkTotalLength - ChunkOffset); - - BufferChunkSize = (UINTN)MIN (RemainingBufferSize, ChunkLength); - - switch (Chunk->Type) { - case APPLE_DISK_IMAGE_CHUNK_TYPE_ZERO: - case APPLE_DISK_IMAGE_CHUNK_TYPE_IGNORE: - { - ZeroMem (BufferCurrent, BufferChunkSize); - break; - } - - case APPLE_DISK_IMAGE_CHUNK_TYPE_RAW: - { - Result = OcAppleRamDiskRead ( - Context->ExtentTable, - (UINTN)(Chunk->CompressedOffset + ChunkOffset), - BufferChunkSize, - BufferCurrent - ); - if (!Result) { - return FALSE; - } - - break; - } - - case APPLE_DISK_IMAGE_CHUNK_TYPE_ZLIB: - { - ChunkData = AllocatePool ((UINTN)(ChunkTotalLength + Chunk->CompressedLength)); - if (ChunkData == NULL) { - return FALSE; - } - - ChunkDataCompressed = (ChunkData + (UINTN)ChunkTotalLength); - Result = OcAppleRamDiskRead ( - Context->ExtentTable, - (UINTN)Chunk->CompressedOffset, - (UINTN)Chunk->CompressedLength, - ChunkDataCompressed - ); - if (!Result) { - FreePool (ChunkData); - return FALSE; - } - - OutSize = DecompressZLIB ( - ChunkData, - (UINTN)ChunkTotalLength, - ChunkDataCompressed, - (UINTN)Chunk->CompressedLength - ); - if (OutSize != (UINTN)ChunkTotalLength) { - FreePool (ChunkData); - return FALSE; - } - - CopyMem (BufferCurrent, (ChunkData + ChunkOffset), BufferChunkSize); - FreePool (ChunkData); - break; - } - - default: - { - DEBUG (( - DEBUG_ERROR, - "OCDI: Compression type %x unsupported\n", - Chunk->Type - )); - return FALSE; - } - } - - RemainingBufferSize -= BufferChunkSize; - BufferCurrent += BufferChunkSize; - LbaCurrent += LbaLength; - } - - return TRUE; -} diff --git a/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf b/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf deleted file mode 100644 index 1556fe6e1..000000000 --- a/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf +++ /dev/null @@ -1,50 +0,0 @@ -## @file -# Copyright (C) 2019, Goldfish64. All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleDiskImageLib - FILE_GUID = F8E071ED-3EAB-46C6-9C50-B99B6B3915FF - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleDiskImageLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - DevicePathLib - MemoryAllocationLib - OcAppleRamDiskLib - OcCompressionLib - OcDevicePathLib - OcGuardLib - OcXmlLib - PrintLib - -[Protocols] - gEfiDevicePathProtocolGuid # PRODUCES - gEfiBlockIoProtocolGuid # PRODUCES - gAppleRamDiskProtocolGuid # CONSUMES - gAppleDiskImageProtocolGuid # CONSUMES - -[Sources] - OcAppleDiskImageBlockIo.c - OcAppleDiskImageLib.c - OcAppleDiskImageLibInternal.c - OcAppleDiskImageLibInternal.h - ../../Include/Library/OcAppleDiskImageLib.h diff --git a/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.c b/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.c deleted file mode 100644 index ed0c1eab9..000000000 --- a/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.c +++ /dev/null @@ -1,355 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include - -#include "OcAppleDiskImageLibInternal.h" - -STATIC -BOOLEAN -InternalFindPlistDictChild ( - IN XML_NODE *Node, - IN CHAR8 *KeyName, - OUT XML_NODE **Key, - OUT XML_NODE **Value - ) -{ - UINT32 ChildCount; - XML_NODE *ChildValue; - XML_NODE *ChildKey; - CONST CHAR8 *ChildKeyName; - UINT32 Index; - - ASSERT (Node != NULL); - ASSERT (KeyName != NULL); - ASSERT (Key != NULL); - ASSERT (Value != NULL); - - ChildCount = PlistDictChildren (Node); - for (Index = 0; Index < ChildCount; ++Index) { - ChildKey = PlistDictChild (Node, Index, &ChildValue); - if (ChildKey == NULL) { - break; - } - - ChildKeyName = PlistKeyValue (ChildKey); - if (ChildKeyName == NULL) { - break; - } - - if (AsciiStrCmp (ChildKeyName, KeyName) == 0) { - *Key = ChildKey; - *Value = ChildValue; - return TRUE; - } - } - - return FALSE; -} - -STATIC -BOOLEAN -InternalSwapBlockData ( - IN OUT APPLE_DISK_IMAGE_BLOCK_DATA *BlockData, - IN UINT32 MaxSize, - IN UINTN SectorCount, - IN UINTN DataForkOffset, - IN UINTN DataForkSize - ) -{ - UINT32 ChunksSize; - UINTN MaxOffset; - BOOLEAN Result; - APPLE_DISK_IMAGE_CHUNK *Chunk; - UINT32 Index; - UINT64 BlockSectorTop; - UINT64 ChunkSectorTop; - UINT64 OffsetTop; - - ASSERT (MaxSize >= sizeof (*BlockData)); - - BlockData->ChunkCount = SwapBytes32 (BlockData->ChunkCount); - - Result = OcOverflowMulU32 ( - BlockData->ChunkCount, - sizeof (*BlockData->Chunks), - &ChunksSize - ); - if (Result || (ChunksSize > (MaxSize - sizeof (*BlockData)))) { - return FALSE; - } - - MaxOffset = (DataForkOffset + DataForkSize); - - BlockData->Version = SwapBytes32 (BlockData->Version); - BlockData->SectorNumber = SwapBytes64 (BlockData->SectorNumber); - BlockData->SectorCount = SwapBytes64 (BlockData->SectorCount); - BlockData->DataOffset = SwapBytes64 (BlockData->DataOffset); - BlockData->BuffersNeeded = SwapBytes32 (BlockData->BuffersNeeded); - BlockData->BlockDescriptors = SwapBytes32 (BlockData->BlockDescriptors); - BlockData->Checksum.Type = SwapBytes32 (BlockData->Checksum.Type); - BlockData->Checksum.Size = SwapBytes32 (BlockData->Checksum.Size); - - if (BlockData->DataOffset > DataForkOffset - || (BlockData->Checksum.Size > (sizeof (BlockData->Checksum.Data) * 8)) - || (BlockData->DataOffset > MaxOffset)) { - return FALSE; - } - - Result = OcOverflowAddU64 ( - BlockData->SectorNumber, - BlockData->SectorCount, - &BlockSectorTop - ); - if (Result || BlockSectorTop > SectorCount) { - DEBUG ((DEBUG_ERROR, "OCDI: Block sectors exceed DMG sectors %lu %lu\n", BlockSectorTop, SectorCount)); - return FALSE; - } - - for (Index = 0; Index < APPLE_DISK_IMAGE_CHECKSUM_SIZE; ++Index) { - BlockData->Checksum.Data[Index] = SwapBytes32 ( - BlockData->Checksum.Data[Index] - ); - } - - for (Index = 0; Index < BlockData->ChunkCount; ++Index) { - Chunk = &BlockData->Chunks[Index]; - - Chunk->Type = SwapBytes32 (Chunk->Type); - Chunk->Comment = SwapBytes32 (Chunk->Comment); - Chunk->SectorNumber = SwapBytes64 (Chunk->SectorNumber); - Chunk->SectorCount = SwapBytes64 (Chunk->SectorCount); - Chunk->CompressedOffset = SwapBytes64 (Chunk->CompressedOffset); - Chunk->CompressedLength = SwapBytes64 (Chunk->CompressedLength); - - Result = OcOverflowAddU64 ( - Chunk->SectorNumber, - Chunk->SectorCount, - &ChunkSectorTop - ); - if (Result || (ChunkSectorTop > BlockSectorTop)) { - return FALSE; - } - - Result = OcOverflowAddU64 ( - Chunk->CompressedOffset, - Chunk->CompressedLength, - &OffsetTop - ); - if (Result || (OffsetTop > MaxOffset)) { - return FALSE; - } - } - - return TRUE; -} - -BOOLEAN -InternalParsePlist ( - IN CHAR8 *Plist, - IN UINT32 PlistSize, - IN UINTN SectorCount, - IN UINTN DataForkOffset, - IN UINTN DataForkSize, - OUT UINT32 *BlockCount, - OUT APPLE_DISK_IMAGE_BLOCK_DATA ***Blocks - ) -{ - BOOLEAN Result; - - XML_DOCUMENT *XmlPlistDoc; - XML_NODE *NodeRoot; - XML_NODE *NodeResourceForkKey; - XML_NODE *NodeResourceForkValue; - XML_NODE *NodeBlockListKey; - XML_NODE *NodeBlockListValue; - - XML_NODE *NodeBlockDict; - XML_NODE *BlockDictChildKey; - XML_NODE *BlockDictChildValue; - UINT32 BlockDictChildDataSize; - - UINT32 NumDmgBlocks; - UINT32 DmgBlocksSize; - APPLE_DISK_IMAGE_BLOCK_DATA **DmgBlocks; - APPLE_DISK_IMAGE_BLOCK_DATA *Block; - - UINT32 Index; - - ASSERT (Plist != NULL); - ASSERT (PlistSize > 0); - ASSERT (BlockCount != NULL); - ASSERT (Blocks != NULL); - - DmgBlocks = NULL; - - XmlPlistDoc = NULL; - - XmlPlistDoc = XmlDocumentParse (Plist, PlistSize, FALSE); - if (XmlPlistDoc == NULL) { - Result = FALSE; - goto DONE_ERROR; - } - - NodeRoot = PlistDocumentRoot (XmlPlistDoc); - if (NodeRoot == NULL) { - Result = FALSE; - goto DONE_ERROR; - } - - Result = InternalFindPlistDictChild ( - NodeRoot, - DMG_PLIST_RESOURCE_FORK_KEY, - &NodeResourceForkKey, - &NodeResourceForkValue - ); - if (!Result) { - goto DONE_ERROR; - } - - Result = InternalFindPlistDictChild ( - NodeResourceForkValue, - DMG_PLIST_BLOCK_LIST_KEY, - &NodeBlockListKey, - &NodeBlockListValue - ); - if (!Result) { - goto DONE_ERROR; - } - - NumDmgBlocks = XmlNodeChildren (NodeBlockListValue); - if (NumDmgBlocks == 0) { - Result = FALSE; - goto DONE_ERROR; - } - - Result = !OcOverflowMulU32 (NumDmgBlocks, sizeof (*DmgBlocks), &DmgBlocksSize); - if (!Result) { ///< Result must be FALSE on error, it's checked at DONE_ERROR - goto DONE_ERROR; - } - - DmgBlocks = AllocatePool (DmgBlocksSize); - if (DmgBlocks == NULL) { - Result = FALSE; - goto DONE_ERROR; - } - - for (Index = 0; Index < NumDmgBlocks; ++Index) { - NodeBlockDict = XmlNodeChild (NodeBlockListValue, Index); - - Result = InternalFindPlistDictChild ( - NodeBlockDict, - DMG_PLIST_DATA, - &BlockDictChildKey, - &BlockDictChildValue - ); - if (!Result) { - goto DONE_ERROR; - } - - Result = PlistDataSize (BlockDictChildValue, &BlockDictChildDataSize); - if (!Result || (BlockDictChildDataSize < sizeof (*Block))) { - Result = FALSE; - goto DONE_ERROR; - } - - Block = AllocatePool (BlockDictChildDataSize); - if (Block == NULL) { - Result = FALSE; - goto DONE_ERROR; - } - - DmgBlocks[Index] = Block; - - Result = PlistDataValue ( - BlockDictChildValue, - (UINT8 *)Block, - &BlockDictChildDataSize - ); - if (!Result) { - FreePool (Block); - goto DONE_ERROR; - } - - Result = InternalSwapBlockData ( - Block, - BlockDictChildDataSize, - SectorCount, - DataForkOffset, - DataForkSize - ); - if (!Result) { - FreePool (Block); - goto DONE_ERROR; - } - } - - *BlockCount = NumDmgBlocks; - *Blocks = DmgBlocks; - Result = TRUE; - -DONE_ERROR: - if (!Result && (DmgBlocks != NULL)) { - while ((Index--) != 0) { - FreePool (DmgBlocks[Index]); - } - - FreePool (DmgBlocks); - } - - if (XmlPlistDoc != NULL) { - XmlDocumentFree (XmlPlistDoc); - } - - return Result; -} - -BOOLEAN -InternalGetBlockChunk ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN Lba, - OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data, - OUT APPLE_DISK_IMAGE_CHUNK **Chunk - ) -{ - UINT32 BlockIndex; - UINT32 ChunkIndex; - APPLE_DISK_IMAGE_BLOCK_DATA *BlockData; - APPLE_DISK_IMAGE_CHUNK *BlockChunk; - - for (BlockIndex = 0; BlockIndex < Context->BlockCount; ++BlockIndex) { - BlockData = Context->Blocks[BlockIndex]; - - if ((Lba >= BlockData->SectorNumber) - && (Lba < (BlockData->SectorNumber + BlockData->SectorCount))) { - for (ChunkIndex = 0; ChunkIndex < BlockData->ChunkCount; ++ChunkIndex) { - BlockChunk = &BlockData->Chunks[ChunkIndex]; - - if ((Lba >= DMG_SECTOR_START_ABS (BlockData, BlockChunk)) - && (Lba < (DMG_SECTOR_START_ABS (BlockData, BlockChunk) + BlockChunk->SectorCount))) { - *Data = BlockData; - *Chunk = BlockChunk; - return TRUE; - } - } - } - } - - return FALSE; -} diff --git a/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.h b/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.h deleted file mode 100644 index 0d8fc11fc..000000000 --- a/Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - Copyright (C) 2019, Goldfish64. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef APPLE_DISK_IMAGE_LIB_INTERNAL_H -#define APPLE_DISK_IMAGE_LIB_INTERNAL_H - -#define BASE_256B 0x0100U -#define SIZE_512B 0x0200U - -#define DMG_SECTOR_START_ABS(b, c) (((b)->SectorNumber) + ((c)->SectorNumber)) - -#define DMG_PLIST_RESOURCE_FORK_KEY "resource-fork" -#define DMG_PLIST_BLOCK_LIST_KEY "blkx" -#define DMG_PLIST_ATTRIBUTES "Attributes" -#define DMG_PLIST_CFNAME "CFName" -#define DMG_PLIST_DATA "Data" -#define DMG_PLIST_ID "ID" -#define DMG_PLIST_NAME "Name" - -BOOLEAN -InternalParsePlist ( - IN CHAR8 *Plist, - IN UINT32 PlistSize, - IN UINTN SectorCount, - IN UINTN DataForkOffset, - IN UINTN DataForkSize, - OUT UINT32 *BlockCount, - OUT APPLE_DISK_IMAGE_BLOCK_DATA ***Blocks - ); - -BOOLEAN -InternalGetBlockChunk ( - IN OC_APPLE_DISK_IMAGE_CONTEXT *Context, - IN UINTN Lba, - OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data, - OUT APPLE_DISK_IMAGE_CHUNK **Chunk - ); - -#endif // APPLE_DISK_IMAGE_LIB_INTERNAL_H diff --git a/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.c b/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.c deleted file mode 100644 index 7aecb0538..000000000 --- a/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.c +++ /dev/null @@ -1,668 +0,0 @@ -/** @file - -AppleKeyMapAggregator - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APPLE_KEY_CODE APPLE_KEY - -// KEY_MAP_AGGREGATOR_DATA_SIGNATURE -#define KEY_MAP_AGGREGATOR_DATA_SIGNATURE \ - SIGNATURE_32 ('K', 'e', 'y', 'A') - -// KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS -#define KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS(This) \ - CR ( \ - (This), \ - KEY_MAP_AGGREGATOR_DATA, \ - Aggregator, \ - KEY_MAP_AGGREGATOR_DATA_SIGNATURE \ - ) - -// KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS -#define KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS(This) \ - CR ( \ - (This), \ - KEY_MAP_AGGREGATOR_DATA, \ - Database, \ - KEY_MAP_AGGREGATOR_DATA_SIGNATURE \ - ) - -// KEY_MAP_AGGREGATOR_DATA -typedef struct { - UINTN Signature; - UINTN NextKeyStrokeIndex; - APPLE_KEY_CODE *KeyCodeBuffer; - UINTN KeyCodeBufferLength; - LIST_ENTRY KeyStrokesInfoList; - APPLE_KEY_MAP_DATABASE_PROTOCOL Database; - APPLE_KEY_MAP_AGGREGATOR_PROTOCOL Aggregator; -} KEY_MAP_AGGREGATOR_DATA; - -// APPLE_KEY_STROKES_INFO_SIGNATURE -#define APPLE_KEY_STROKES_INFO_SIGNATURE SIGNATURE_32 ('K', 'e', 'y', 'S') - -// APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY -#define APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY(Entry) \ - CR ( \ - (Entry), \ - APPLE_KEY_STROKES_INFO, \ - Link, \ - APPLE_KEY_STROKES_INFO_SIGNATURE \ - ) - -#define SIZE_OF_APPLE_KEY_STROKES_INFO \ - OFFSET_OF (APPLE_KEY_STROKES_INFO, KeyCodes) - -// APPLE_KEY_STROKES_INFO -typedef struct { - UINTN Signature; - LIST_ENTRY Link; - UINTN Index; - UINTN KeyCodeBufferLength; - UINTN NumberOfKeyCodes; - APPLE_MODIFIER_MAP Modifiers; - APPLE_KEY_CODE KeyCodes[]; -} APPLE_KEY_STROKES_INFO; - -// InternalGetKeyStrokesByIndex -STATIC -APPLE_KEY_STROKES_INFO * -InternalGetKeyStrokesByIndex ( - IN KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData, - IN UINTN Index - ) -{ - APPLE_KEY_STROKES_INFO *KeyStrokesInfo; - - LIST_ENTRY *Entry; - APPLE_KEY_STROKES_INFO *KeyStrokesInfoWalker; - - KeyStrokesInfo = NULL; - - for ( - Entry = GetFirstNode (&KeyMapAggregatorData->KeyStrokesInfoList); - !IsNull (&KeyMapAggregatorData->KeyStrokesInfoList, Entry); - Entry = GetNextNode (&KeyMapAggregatorData->KeyStrokesInfoList, Entry) - ) { - KeyStrokesInfoWalker = APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY (Entry); - - if (KeyStrokesInfoWalker->Index == Index) { - KeyStrokesInfo = KeyStrokesInfoWalker; - - break; - } - } - - return KeyStrokesInfo; -} - -// InternalGetKeyStrokes -/** Returns all pressed keys and key modifiers into the appropiate buffers. - - @param[in] This A pointer to the protocol instance. - @param[out] Modifiers The modifiers manipulating the given keys. - @param[out] NumberOfKeyCodes On input the number of keys allocated. - On output the number of keys returned into - KeyCodes. - @param[out] KeyCodes A Pointer to a caller-allocated the pressed - keys get returned in. - - @retval EFI_SUCCESS The pressed keys have been returned into - KeyCodes. - @retval EFI_BUFFER_TOO_SMALL The memory required to return the value exceeds - the size of the allocated Buffer. - The required number of keys to allocate to - complete the operation has been returned into - NumberOfKeyCodes. - @retval other An error returned by a sub-operation. -**/ -STATIC -EFI_STATUS -EFIAPI -InternalGetKeyStrokes ( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This, - OUT APPLE_MODIFIER_MAP *Modifiers, - OUT UINTN *NumberOfKeyCodes, - IN OUT APPLE_KEY_CODE *KeyCodes OPTIONAL - ) -{ - EFI_STATUS Status; - - KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData; - LIST_ENTRY *Entry; - APPLE_KEY_STROKES_INFO *KeyStrokesInfo; - BOOLEAN Result; - APPLE_MODIFIER_MAP DbModifiers; - UINTN DbNumberOfKeyCodestrokes; - UINTN Index; - UINTN Index2; - APPLE_KEY_CODE Key; - - KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS (This); - - DbModifiers = 0; - DbNumberOfKeyCodestrokes = 0; - - for ( - Entry = GetFirstNode (&KeyMapAggregatorData->KeyStrokesInfoList); - !IsNull (&KeyMapAggregatorData->KeyStrokesInfoList, Entry); - Entry = GetNextNode (&KeyMapAggregatorData->KeyStrokesInfoList, Entry) - ) { - KeyStrokesInfo = APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY (Entry); - - DbModifiers |= KeyStrokesInfo->Modifiers; - - for (Index = 0; Index < KeyStrokesInfo->NumberOfKeyCodes; ++Index) { - Key = KeyStrokesInfo->KeyCodes[Index]; - - for (Index2 = 0; Index2 < DbNumberOfKeyCodestrokes; ++Index2) { - if (KeyMapAggregatorData->KeyCodeBuffer[Index2] == Key) { - break; - } - } - - if (Index2 == DbNumberOfKeyCodestrokes) { - KeyMapAggregatorData->KeyCodeBuffer[DbNumberOfKeyCodestrokes] = Key; - ++DbNumberOfKeyCodestrokes; - } - } - } - - Result = (BOOLEAN)(DbNumberOfKeyCodestrokes > *NumberOfKeyCodes); - - *NumberOfKeyCodes = DbNumberOfKeyCodestrokes; - - Status = EFI_BUFFER_TOO_SMALL; - - if (!Result) { - *Modifiers = DbModifiers; - - Status = EFI_SUCCESS; - - if (KeyCodes != NULL) { - CopyMem ( - (VOID *)KeyCodes, - (VOID *)KeyMapAggregatorData->KeyCodeBuffer, - (DbNumberOfKeyCodestrokes * sizeof (*KeyCodes)) - ); - } - } - - return Status; -} - -BOOLEAN -OcKeyMapHasKeys ( - IN CONST APPLE_KEY_CODE *Keys, - IN UINTN NumKeys, - IN CONST APPLE_KEY_CODE *CheckKeys, - IN UINTN NumCheckKeys, - IN BOOLEAN ExactMatch - ) -{ - UINTN CheckIndex; - UINTN Index; - - if (ExactMatch && NumKeys != NumCheckKeys) { - return FALSE; - } - - for (CheckIndex = 0; CheckIndex < NumCheckKeys; ++CheckIndex) { - for (Index = 0; Index < NumKeys; ++Index) { - if (CheckKeys[CheckIndex] == Keys[Index]) { - break; - } - } - - if (NumKeys == Index) { - return FALSE; - } - } - - return TRUE; -} - -BOOLEAN -OcKeyMapHasKey ( - IN CONST APPLE_KEY_CODE *Keys, - IN UINTN NumKeys, - IN CONST APPLE_KEY_CODE KeyCode - ) -{ - return OcKeyMapHasKeys (Keys, NumKeys, &KeyCode, 1, FALSE); -} - -VOID -OcKeyMapFlush ( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - IN APPLE_KEY_CODE Key, - IN BOOLEAN FlushConsole - ) -{ - EFI_STATUS Status; - UINTN NumKeys; - APPLE_MODIFIER_MAP Modifiers; - EFI_INPUT_KEY EfiKey; - APPLE_KEY_CODE Keys[OC_KEY_MAP_DEFAULT_SIZE]; - - ASSERT (KeyMap != NULL); - - while (TRUE) { - NumKeys = ARRAY_SIZE (Keys); - Status = KeyMap->GetKeyStrokes ( - KeyMap, - &Modifiers, - &NumKeys, - Keys - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCKM: GetKeyStrokes failure - %r\n", Status)); - break; - } - - if (Key != 0 && !OcKeyMapHasKey (Keys, NumKeys, Key) && Modifiers == 0) { - break; - } - - if (Key == 0 && NumKeys == 0 && Modifiers == 0) { - break; - } - - MicroSecondDelay (10); - } - - if (FlushConsole) { - do { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &EfiKey); - } while (!EFI_ERROR(Status)); - - // - // This one is required on APTIO IV after holding OPT key. - // Interestingly it does not help adding this after OPT key handling. - // - gST->ConIn->Reset (gST->ConIn, FALSE); - } -} - -// InternalContainsKeyStrokes -/** Returns whether or not a list of keys and their modifiers are part of the - database of pressed keys. - - @param[in] This A pointer to the protocol instance. - @param[in] Modifiers The modifiers manipulating the given keys. - @param[in] NumberOfKeyCodes The number of keys present in KeyCodes. - @param[in,out] KeyCodes The list of keys to check for. The children - may be sorted in the process. - @param[in] ExactMatch Specifies whether Modifiers and KeyCodes should be - exact matches or just contained. - - @return Returns whether or not a list of keys and their - modifiers are part of the database of pressed keys. - @retval EFI_SUCCESS The queried keys are part of the database. - @retval EFI_NOT_FOUND The queried keys could not be found. -**/ -STATIC -EFI_STATUS -EFIAPI -InternalContainsKeyStrokes ( - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This, - IN APPLE_MODIFIER_MAP Modifiers, - IN UINTN NumberOfKeyCodes, - IN OUT APPLE_KEY_CODE *KeyCodes, - IN BOOLEAN ExactMatch - ) -{ - EFI_STATUS Status; - BOOLEAN Result; - - UINTN DbNumberOfKeyCodes; - APPLE_MODIFIER_MAP DbModifiers; - APPLE_KEY_CODE DbKeyCodes[8]; - - DbNumberOfKeyCodes = ARRAY_SIZE (DbKeyCodes); - Status = This->GetKeyStrokes ( - This, - &DbModifiers, - &DbNumberOfKeyCodes, - DbKeyCodes - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - if (ExactMatch) { - if (DbModifiers != Modifiers) { - return FALSE; - } - } else if ((DbModifiers & Modifiers) != Modifiers) { - return FALSE; - } - - Result = OcKeyMapHasKeys ( - DbKeyCodes, - DbNumberOfKeyCodes, - KeyCodes, - NumberOfKeyCodes, - ExactMatch - ); - if (!Result) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -// KeyMapCreateKeyStrokesBuffer -/** Creates a new key set with a given number of keys allocated. The index - within the database is returned. - - @param[in] This A pointer to the protocol instance. - @param[in] BufferLength The amount of keys to allocate for the key set. - @param[out] Index The assigned index of the created key set. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS A key set with the given number of keys - allocated has been created. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval other An error returned by a sub-operation. -**/ -STATIC -EFI_STATUS -EFIAPI -InternalCreateKeyStrokesBuffer ( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN BufferLength, - OUT UINTN *Index - ) -{ - EFI_STATUS Status; - - KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData; - UINTN TotalBufferLength; - APPLE_KEY_CODE *Buffer; - APPLE_KEY_STROKES_INFO *KeyStrokesInfo; - - KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This); - - if (KeyMapAggregatorData->KeyCodeBuffer != NULL) { - gBS->FreePool ((VOID *)KeyMapAggregatorData->KeyCodeBuffer); - } - - TotalBufferLength = (KeyMapAggregatorData->KeyCodeBufferLength + BufferLength); - - KeyMapAggregatorData->KeyCodeBufferLength = TotalBufferLength; - - Buffer = AllocateZeroPool (TotalBufferLength * sizeof (*Buffer)); - - KeyMapAggregatorData->KeyCodeBuffer = Buffer; - - Status = EFI_OUT_OF_RESOURCES; - - if (Buffer != NULL) { - KeyStrokesInfo = AllocateZeroPool ( - SIZE_OF_APPLE_KEY_STROKES_INFO - + (BufferLength * sizeof (*Buffer)) - ); - - Status = EFI_OUT_OF_RESOURCES; - - if (KeyStrokesInfo != NULL) { - KeyStrokesInfo->Signature = APPLE_KEY_STROKES_INFO_SIGNATURE; - KeyStrokesInfo->KeyCodeBufferLength = BufferLength; - KeyStrokesInfo->Index = KeyMapAggregatorData->NextKeyStrokeIndex++; - - InsertTailList ( - &KeyMapAggregatorData->KeyStrokesInfoList, - &KeyStrokesInfo->Link - ); - - Status = EFI_SUCCESS; - - *Index = KeyStrokesInfo->Index; - } - } - - return Status; -} - -// KeyMapRemoveKeyStrokesBuffer -/** Removes a key set specified by its index from the database. - - @param[in] This A pointer to the protocol instance. - @param[in] Index The index of the key set to remove. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS The specified key set has been removed. - @retval EFI_NOT_FOUND No key set could be found for the given index. - @retval other An error returned by a sub-operation. -**/ -STATIC -EFI_STATUS -EFIAPI -InternalRemoveKeyStrokesBuffer ( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN Index - ) -{ - EFI_STATUS Status; - - KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData; - APPLE_KEY_STROKES_INFO *KeyStrokesInfo; - - KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This); - - KeyStrokesInfo = InternalGetKeyStrokesByIndex ( - KeyMapAggregatorData, - Index - ); - - Status = EFI_NOT_FOUND; - - if (KeyStrokesInfo != NULL) { - KeyMapAggregatorData->KeyCodeBufferLength -= KeyStrokesInfo->KeyCodeBufferLength; - - RemoveEntryList (&KeyStrokesInfo->Link); - gBS->FreePool ((VOID *)KeyStrokesInfo); - - Status = EFI_SUCCESS; - } - - return Status; -} - -// KeyMapSetKeyStrokeBufferKeys -/** Sets the keys of a key set specified by its index to the given KeyCodes - Buffer. - - @param[in] This A pointer to the protocol instance. - @param[in] Index The index of the key set to edit. - @param[in] Modifiers The key modifiers manipulating the given keys. - @param[in] NumberOfKeyCodes The number of keys contained in KeyCodes. - @param[in] KeyCodes An array of keys to add to the specified key - set. - - @return Returned is the status of the operation. - @retval EFI_SUCCESS The given keys were set for the specified key - set. - @retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation - could not be allocated. - @retval EFI_NOT_FOUND No key set could be found for the given index. - @retval other An error returned by a sub-operation. -**/ -STATIC -EFI_STATUS -EFIAPI -InternalSetKeyStrokeBufferKeys ( - IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This, - IN UINTN Index, - IN APPLE_MODIFIER_MAP Modifiers, - IN UINTN NumberOfKeyCodes, - IN APPLE_KEY_CODE *KeyCodes - ) -{ - EFI_STATUS Status; - - KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData; - APPLE_KEY_STROKES_INFO *KeyStrokesInfo; - - KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This); - - KeyStrokesInfo = InternalGetKeyStrokesByIndex ( - KeyMapAggregatorData, - Index - ); - - Status = EFI_NOT_FOUND; - - if (KeyStrokesInfo != NULL) { - Status = EFI_OUT_OF_RESOURCES; - - if (KeyStrokesInfo->KeyCodeBufferLength >= NumberOfKeyCodes) { - KeyStrokesInfo->NumberOfKeyCodes = NumberOfKeyCodes; - KeyStrokesInfo->Modifiers = Modifiers; - - CopyMem ( - (VOID *)&KeyStrokesInfo->KeyCodes[0], - (VOID *)KeyCodes, - (NumberOfKeyCodes * sizeof (*KeyCodes)) - ); - - Status = EFI_SUCCESS; - } - } - - return Status; -} - -STATIC APPLE_KEY_MAP_DATABASE_PROTOCOL *mKeyMapDatabase = NULL; - -/** - Returns the previously install Apple Key Map Database protocol. - - @retval installed or located protocol or NULL -**/ -APPLE_KEY_MAP_DATABASE_PROTOCOL * -OcAppleKeyMapGetDatabase ( - VOID - ) -{ - return mKeyMapDatabase; -} - -/** - Install and initialise Apple Key Map protocols. - - @param[in] Reinstall Overwrite installed protocols. - - @retval installed or located protocol or NULL -**/ -APPLE_KEY_MAP_AGGREGATOR_PROTOCOL * -OcAppleKeyMapInstallProtocols ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - EFI_STATUS Status2; - KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData; - APPLE_KEY_MAP_DATABASE_PROTOCOL *Database; - APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *Aggregator; - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gAppleKeyMapDatabaseProtocolGuid); - Status2 = OcUninstallAllProtocolInstances (&gAppleKeyStateProtocolGuid); - if (EFI_ERROR(Status) || EFI_ERROR (Status2)) { - DEBUG ((DEBUG_ERROR, "OCKM: Uninstall failed: %r/%r\n", Status, Status2)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gAppleKeyMapDatabaseProtocolGuid, - NULL, - (VOID *)&Database - ); - Status2 = gBS->LocateProtocol ( - &gAppleKeyStateProtocolGuid, - NULL, - (VOID *)&Aggregator - ); - - if (!EFI_ERROR (Status2)) { - // - // VMware Fusion has no KeyMapDatabase, and it is intended. - // - if (!EFI_ERROR(Status)) { - mKeyMapDatabase = Database; - } - return Aggregator; - } else if (!EFI_ERROR(Status)) { - // - // Installed KeyMapDatabase makes no sense, however. - // - return NULL; - } - } - - KeyMapAggregatorData = AllocateZeroPool (sizeof (*KeyMapAggregatorData)); - - if (KeyMapAggregatorData == NULL) { - return NULL; - } - - KeyMapAggregatorData->Signature = KEY_MAP_AGGREGATOR_DATA_SIGNATURE; - KeyMapAggregatorData->NextKeyStrokeIndex = 3000; - - KeyMapAggregatorData->Database.Revision = APPLE_KEY_MAP_DATABASE_PROTOCOL_REVISION; - KeyMapAggregatorData->Database.CreateKeyStrokesBuffer = InternalCreateKeyStrokesBuffer; - KeyMapAggregatorData->Database.RemoveKeyStrokesBuffer = InternalRemoveKeyStrokesBuffer; - KeyMapAggregatorData->Database.SetKeyStrokeBufferKeys = InternalSetKeyStrokeBufferKeys; - - KeyMapAggregatorData->Aggregator.Revision = APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION; - KeyMapAggregatorData->Aggregator.GetKeyStrokes = InternalGetKeyStrokes; - KeyMapAggregatorData->Aggregator.ContainsKeyStrokes = InternalContainsKeyStrokes; - - InitializeListHead (&KeyMapAggregatorData->KeyStrokesInfoList); - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gAppleKeyMapDatabaseProtocolGuid, - (VOID *)&KeyMapAggregatorData->Database, - &gAppleKeyStateProtocolGuid, - (VOID *)&KeyMapAggregatorData->Aggregator, - NULL - ); - if (EFI_ERROR(Status)) { - FreePool (KeyMapAggregatorData); - return NULL; - } - - mKeyMapDatabase = &KeyMapAggregatorData->Database; - return &KeyMapAggregatorData->Aggregator; -} diff --git a/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf b/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf deleted file mode 100644 index f618e7946..000000000 --- a/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf +++ /dev/null @@ -1,52 +0,0 @@ -## @file -# -# Component description file for the library producing the Apple Event protocol. -# -# Copyright (C) 2019, Download-Fritz. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleKeyMapLib - FILE_GUID = 3A5CA054-2A65-4A00-AE58-B61BAFD6CF9A - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleKeyMapLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - OcAppleKeyMapLib.c - ../../Include/Library/OcAppleKeyMapLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[Protocols] - gAppleKeyMapDatabaseProtocolGuid ## SOMETIMES_PRODUCES - gAppleKeyStateProtocolGuid ## SOMETIMES_PRODUCES - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - OcMiscLib - MemoryAllocationLib - UefiBootServicesTableLib diff --git a/Library/OcAppleKeysLib/OcAppleKeysLib.c b/Library/OcAppleKeysLib/OcAppleKeysLib.c deleted file mode 100644 index 529e649c9..000000000 --- a/Library/OcAppleKeysLib/OcAppleKeysLib.c +++ /dev/null @@ -1,334 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include - -#pragma pack(push, 1) - -/// -/// The data size of a 2048 Bits RSA Public Key. Includes N and R^2 mod N. -/// -#define OC_RSA_PK_2048_NUM_BYTES (2 * (2048 / OC_CHAR_BIT)) - -typedef PACKED struct { - /// - /// RSA Public Key header structure. - /// - OC_RSA_PUBLIC_KEY_HDR Hdr; - /// - /// The Modulus and Montgomery's R^2 mod N in little endian byte order. - /// - union { - UINT8 Bytes[OC_RSA_PK_2048_NUM_BYTES]; - UINT64 Qwords[OC_RSA_PK_2048_NUM_BYTES / sizeof (UINT64)]; - } Data; -} OC_RSA_PUBLIC_KEY_2048; - -#pragma pack(pop) - -// -// Verify the structure size equals to the header plus two times the key size -// (N and R^2 mod N). -// -/* -STATIC_ASSERT ( - sizeof (OC_RSA_PUBLIC_KEY_2048) == sizeof (OC_RSA_PUBLIC_KEY_HDR) + OC_RSA_PK_2048_NUM_BYTES, - "The 2048-bit RSA PK struct is malformed." - ); -*/ -STATIC CONST OC_RSA_PUBLIC_KEY_2048 mPkDb1 = { - { ARRAY_SIZE (mPkDb1.Data.Qwords) / 2, { 0 }, 0xb9a584a4e7cd16d1 }, - /** - CFFD3E6B FE66EC75 F44B7E2E 0ED26398 08A98D10 AC378E55 - 1CAA0E1C 1D85EF6C D51C758C 751816BF 599FBEDA EF4D6B0C - EBA31024 7357CDE1 05696D2E F6A36FE8 540A010E 96311C7E - 1F1971E8 34C3A237 EFF5FFCC 1262FDA4 B399EE9A 29CCCBFC - 1E767165 3F3F2F61 08DAACA3 372D465A C518D154 56A315FC - 555F417D F0095974 755F5150 E667EDA8 823162E0 8CF831F7 - AF5831CF 3F0D92CA BAD076C1 3F74ED92 4CC8A3DE CCD11863 - 9120D1CB 2E85B06B DB155AE2 DA144006 44B63635 CD9AF896 - C172DF2B 4ED961FE 1F467BEA F0EB0BCE EDA1DF17 7D5112CA - 299E9EC8 6F5E85D4 79213FB1 F9DD5B93 8C57DE9A 52FF62A7 - E1431EA9 250EE129 4338CDD9 CA48E7C3 - **/ - { - { - // - // N - // - 0xcf, 0xfd, 0x3e, 0x6b, - 0xfe, 0x66, 0xec, 0x75, 0xf4, 0x4b, 0x7e, 0x2e, 0x0e, 0xd2, 0x63, 0x98, - 0x08, 0xa9, 0x8d, 0x10, 0xac, 0x37, 0x8e, 0x55, 0x1c, 0xaa, 0x0e, 0x1c, - 0x1d, 0x85, 0xef, 0x6c, 0xd5, 0x1c, 0x75, 0x8c, 0x75, 0x18, 0x16, 0xbf, - 0x59, 0x9f, 0xbe, 0xda, 0xef, 0x4d, 0x6b, 0x0c, 0xeb, 0xa3, 0x10, 0x24, - 0x73, 0x57, 0xcd, 0xe1, 0x05, 0x69, 0x6d, 0x2e, 0xf6, 0xa3, 0x6f, 0xe8, - 0x54, 0x0a, 0x01, 0x0e, 0x96, 0x31, 0x1c, 0x7e, 0x1f, 0x19, 0x71, 0xe8, - 0x34, 0xc3, 0xa2, 0x37, 0xef, 0xf5, 0xff, 0xcc, 0x12, 0x62, 0xfd, 0xa4, - 0xb3, 0x99, 0xee, 0x9a, 0x29, 0xcc, 0xcb, 0xfc, 0x1e, 0x76, 0x71, 0x65, - 0x3f, 0x3f, 0x2f, 0x61, 0x08, 0xda, 0xac, 0xa3, 0x37, 0x2d, 0x46, 0x5a, - 0xc5, 0x18, 0xd1, 0x54, 0x56, 0xa3, 0x15, 0xfc, 0x55, 0x5f, 0x41, 0x7d, - 0xf0, 0x09, 0x59, 0x74, 0x75, 0x5f, 0x51, 0x50, 0xe6, 0x67, 0xed, 0xa8, - 0x82, 0x31, 0x62, 0xe0, 0x8c, 0xf8, 0x31, 0xf7, 0xaf, 0x58, 0x31, 0xcf, - 0x3f, 0x0d, 0x92, 0xca, 0xba, 0xd0, 0x76, 0xc1, 0x3f, 0x74, 0xed, 0x92, - 0x4c, 0xc8, 0xa3, 0xde, 0xcc, 0xd1, 0x18, 0x63, 0x91, 0x20, 0xd1, 0xcb, - 0x2e, 0x85, 0xb0, 0x6b, 0xdb, 0x15, 0x5a, 0xe2, 0xda, 0x14, 0x40, 0x06, - 0x44, 0xb6, 0x36, 0x35, 0xcd, 0x9a, 0xf8, 0x96, 0xc1, 0x72, 0xdf, 0x2b, - 0x4e, 0xd9, 0x61, 0xfe, 0x1f, 0x46, 0x7b, 0xea, 0xf0, 0xeb, 0x0b, 0xce, - 0xed, 0xa1, 0xdf, 0x17, 0x7d, 0x51, 0x12, 0xca, 0x29, 0x9e, 0x9e, 0xc8, - 0x6f, 0x5e, 0x85, 0xd4, 0x79, 0x21, 0x3f, 0xb1, 0xf9, 0xdd, 0x5b, 0x93, - 0x8c, 0x57, 0xde, 0x9a, 0x52, 0xff, 0x62, 0xa7, 0xe1, 0x43, 0x1e, 0xa9, - 0x25, 0x0e, 0xe1, 0x29, 0x43, 0x38, 0xcd, 0xd9, 0xca, 0x48, 0xe7, 0xc3, - // - // R^2 mod N - // - 0x4f, 0x4b, 0x25, 0x95, 0x56, 0xa1, 0xa9, 0x4f, 0x33, 0x4f, 0x0f, 0xdc, - 0xcd, 0x7c, 0xb6, 0xab, 0x41, 0xa8, 0xfe, 0x2c, 0x24, 0x94, 0xad, 0x39, - 0x7f, 0x5a, 0x6d, 0x82, 0x40, 0x42, 0x32, 0xf9, 0xbb, 0x27, 0xc1, 0x17, - 0xc2, 0x5e, 0x3e, 0xbe, 0x49, 0xa8, 0x4f, 0x83, 0x56, 0x2e, 0x97, 0x1a, - 0x64, 0x58, 0xa3, 0x71, 0x53, 0x0e, 0xe1, 0x81, 0x38, 0x27, 0x76, 0xac, - 0xf2, 0x65, 0x48, 0x16, 0x30, 0x7c, 0xb1, 0x80, 0xfc, 0x5e, 0x4d, 0xd3, - 0x6b, 0xc0, 0x03, 0x50, 0x5d, 0xa7, 0xd8, 0xba, 0xad, 0xea, 0x2f, 0xe5, - 0x9c, 0x25, 0x36, 0xca, 0x4e, 0x0b, 0xef, 0xcf, 0x6f, 0x2d, 0xa5, 0x9c, - 0x1e, 0x52, 0xfc, 0x6c, 0x17, 0xb6, 0xd1, 0x93, 0x5c, 0x27, 0x64, 0xd9, - 0xaa, 0x9e, 0x4f, 0x13, 0x2d, 0x1a, 0x19, 0x46, 0x0b, 0x9a, 0xa4, 0x92, - 0x75, 0x48, 0xbb, 0x2c, 0xcd, 0xb8, 0x3e, 0xe5, 0x16, 0x9a, 0xfd, 0x7e, - 0xea, 0x81, 0xad, 0xba, 0xb6, 0x6d, 0x61, 0x4c, 0x35, 0xe5, 0xa4, 0x3c, - 0x36, 0x15, 0x4c, 0x38, 0x20, 0xde, 0xf7, 0x65, 0x8b, 0x19, 0x75, 0x25, - 0x98, 0x32, 0xd5, 0xd2, 0x4d, 0x0d, 0x65, 0x17, 0x29, 0xe7, 0x67, 0x39, - 0x55, 0xeb, 0xab, 0x6d, 0x7a, 0x7e, 0x52, 0x49, 0xf9, 0x74, 0x07, 0x07, - 0x72, 0x37, 0x14, 0x25, 0xe9, 0x38, 0xe1, 0xe4, 0xff, 0x18, 0x8c, 0x0d, - 0xe7, 0x46, 0x8d, 0x9a, 0x89, 0xaf, 0x31, 0xb2, 0xcf, 0x66, 0x08, 0x09, - 0x4e, 0xd4, 0xf7, 0xc1, 0xee, 0xb3, 0xee, 0xed, 0xf5, 0xce, 0x99, 0x85, - 0xc6, 0x21, 0xb2, 0xf6, 0x45, 0x17, 0x2d, 0x73, 0xbe, 0xda, 0x6a, 0x93, - 0x60, 0xf9, 0x09, 0xcd, 0xcb, 0xfb, 0x0b, 0xce, 0x1b, 0x06, 0x41, 0xe8, - 0xe1, 0x72, 0xc3, 0x6c, 0x5f, 0xe4, 0x66, 0x0d, 0x4e, 0x08, 0x65, 0x9c, - 0x46, 0xc5, 0x7b, 0x04 - } - } -}; - -STATIC CONST OC_RSA_PUBLIC_KEY_2048 mPkDb2 = { - { ARRAY_SIZE (mPkDb2.Data.Qwords) / 2, { 0 }, 0x646a020e9ed45d13 }, - /** - E50AC288 2D44B7E3 3B67C51D AC639329 DA0363BD EAB5179F - F88E460E E703D6CE 30383B25 0DE0E2FF 39386811 512A1A3B - 7531294F 9C512D28 FF56E5CD EB989342 B3A1A866 B41382A6 - 2FB17D5D 3E97454A E19EB3C8 FA42F103 1DA21EEC 8D33BCE7 - 8C4E3C55 EFF8A596 3A3CDAB7 2F475061 30FC1978 03DB6CA5 - A0FDC594 82EC0A3F 408364E3 4FAE9FD6 D5EBF633 357E3E7A - 3BA491D3 34A62604 B9CBF382 63BFF475 5168DB6D FBBA8669 - B7DB7280 218C4EAC 561CBF2F 932EAD6B 41159573 D7FF75B1 - 9D65195F 0A41DC32 ED6F6D55 51716B6F 744ACD2D 3EE64FDE - 29742594 5ED2FF45 2B8CC72B C5D4C987 D0D1DC0A FC543E28 - F7A49046 8F434122 58F91106 8253C0B6 - **/ - { - { - // - // N - // - 0xe5, 0x0a, 0xc2, 0x88, - 0x2d, 0x44, 0xb7, 0xe3, 0x3b, 0x67, 0xc5, 0x1d, 0xac, 0x63, 0x93, 0x29, - 0xda, 0x03, 0x63, 0xbd, 0xea, 0xb5, 0x17, 0x9f, 0xf8, 0x8e, 0x46, 0x0e, - 0xe7, 0x03, 0xd6, 0xce, 0x30, 0x38, 0x3b, 0x25, 0x0d, 0xe0, 0xe2, 0xff, - 0x39, 0x38, 0x68, 0x11, 0x51, 0x2a, 0x1a, 0x3b, 0x75, 0x31, 0x29, 0x4f, - 0x9c, 0x51, 0x2d, 0x28, 0xff, 0x56, 0xe5, 0xcd, 0xeb, 0x98, 0x93, 0x42, - 0xb3, 0xa1, 0xa8, 0x66, 0xb4, 0x13, 0x82, 0xa6, 0x2f, 0xb1, 0x7d, 0x5d, - 0x3e, 0x97, 0x45, 0x4a, 0xe1, 0x9e, 0xb3, 0xc8, 0xfa, 0x42, 0xf1, 0x03, - 0x1d, 0xa2, 0x1e, 0xec, 0x8d, 0x33, 0xbc, 0xe7, 0x8c, 0x4e, 0x3c, 0x55, - 0xef, 0xf8, 0xa5, 0x96, 0x3a, 0x3c, 0xda, 0xb7, 0x2f, 0x47, 0x50, 0x61, - 0x30, 0xfc, 0x19, 0x78, 0x03, 0xdb, 0x6c, 0xa5, 0xa0, 0xfd, 0xc5, 0x94, - 0x82, 0xec, 0x0a, 0x3f, 0x40, 0x83, 0x64, 0xe3, 0x4f, 0xae, 0x9f, 0xd6, - 0xd5, 0xeb, 0xf6, 0x33, 0x35, 0x7e, 0x3e, 0x7a, 0x3b, 0xa4, 0x91, 0xd3, - 0x34, 0xa6, 0x26, 0x04, 0xb9, 0xcb, 0xf3, 0x82, 0x63, 0xbf, 0xf4, 0x75, - 0x51, 0x68, 0xdb, 0x6d, 0xfb, 0xba, 0x86, 0x69, 0xb7, 0xdb, 0x72, 0x80, - 0x21, 0x8c, 0x4e, 0xac, 0x56, 0x1c, 0xbf, 0x2f, 0x93, 0x2e, 0xad, 0x6b, - 0x41, 0x15, 0x95, 0x73, 0xd7, 0xff, 0x75, 0xb1, 0x9d, 0x65, 0x19, 0x5f, - 0x0a, 0x41, 0xdc, 0x32, 0xed, 0x6f, 0x6d, 0x55, 0x51, 0x71, 0x6b, 0x6f, - 0x74, 0x4a, 0xcd, 0x2d, 0x3e, 0xe6, 0x4f, 0xde, 0x29, 0x74, 0x25, 0x94, - 0x5e, 0xd2, 0xff, 0x45, 0x2b, 0x8c, 0xc7, 0x2b, 0xc5, 0xd4, 0xc9, 0x87, - 0xd0, 0xd1, 0xdc, 0x0a, 0xfc, 0x54, 0x3e, 0x28, 0xf7, 0xa4, 0x90, 0x46, - 0x8f, 0x43, 0x41, 0x22, 0x58, 0xf9, 0x11, 0x06, 0x82, 0x53, 0xc0, 0xb6, - // - // R^2 mod N - // - 0xa7, 0x3e, 0xe4, 0x73, 0x82, 0xbe, 0x69, 0xc7, 0x7c, 0x75, 0x84, 0xea, - 0xb2, 0x84, 0xaf, 0xff, 0x16, 0x2f, 0xe4, 0xce, 0x22, 0x68, 0xf6, 0x35, - 0x42, 0x90, 0xd7, 0x3a, 0x15, 0xee, 0x79, 0x8a, 0x54, 0x99, 0x93, 0x6e, - 0xde, 0x7b, 0x0d, 0xf9, 0x9b, 0xbc, 0xf4, 0xe5, 0xc1, 0xb0, 0x83, 0xf5, - 0x16, 0xfa, 0x50, 0x9c, 0x82, 0xf2, 0xf4, 0x18, 0x58, 0xa4, 0xa4, 0x04, - 0x29, 0x34, 0xa4, 0xb3, 0x47, 0xc5, 0x86, 0xf0, 0x1f, 0xb0, 0x8e, 0xce, - 0x18, 0xcd, 0x5f, 0x0a, 0x57, 0x17, 0x4b, 0x78, 0x2e, 0x80, 0xaa, 0x01, - 0xac, 0x86, 0xa4, 0xc5, 0x2b, 0x5b, 0xb6, 0x22, 0xd1, 0x50, 0xfc, 0x8f, - 0xce, 0x72, 0x05, 0x82, 0x59, 0xe6, 0xb7, 0x0f, 0xe9, 0x93, 0x58, 0x04, - 0xf1, 0x3e, 0xe7, 0x94, 0xd5, 0x4f, 0x65, 0x95, 0x8a, 0x77, 0x6b, 0x68, - 0xd3, 0x6a, 0xe6, 0x49, 0x6b, 0x79, 0xe2, 0x4b, 0x3f, 0x3e, 0x83, 0x0c, - 0x3d, 0x00, 0x51, 0x87, 0xbb, 0x90, 0x56, 0x47, 0xb5, 0x23, 0x88, 0x4c, - 0xd0, 0x75, 0x7a, 0xf1, 0xbc, 0x46, 0x61, 0xa6, 0xeb, 0x80, 0xb9, 0x0e, - 0xec, 0x28, 0x22, 0x5a, 0x27, 0x8a, 0x92, 0xe1, 0x56, 0x54, 0xe8, 0xc7, - 0xbe, 0x3d, 0x11, 0xa7, 0x67, 0xf8, 0xa7, 0x89, 0x02, 0xb2, 0xf4, 0xf4, - 0xe7, 0x31, 0x86, 0xe8, 0x7c, 0x7c, 0xa2, 0xfc, 0xe8, 0x3c, 0xd2, 0xfa, - 0xe3, 0xf6, 0x34, 0xfc, 0x48, 0x1b, 0xf0, 0x46, 0x34, 0xb8, 0x36, 0x80, - 0x35, 0xbe, 0xdc, 0xd3, 0x60, 0x6c, 0x79, 0x66, 0x03, 0x03, 0x7e, 0xe0, - 0xba, 0xdb, 0xb6, 0x1d, 0x6a, 0xed, 0x24, 0x31, 0x0c, 0x81, 0xf9, 0x54, - 0xba, 0xf1, 0x02, 0x53, 0x21, 0x93, 0xea, 0x6d, 0x93, 0x6d, 0x6a, 0x85, - 0x37, 0x2e, 0x4c, 0x39, 0x19, 0xa0, 0x4e, 0x43, 0xe0, 0xcc, 0xd9, 0x87, - 0x2c, 0xd1, 0x2c, 0x3e - } - } -}; - -// -// The pointer casts are safe because the structs are compatible. -// -CONST APPLE_PK_ENTRY PkDataBase[NUM_OF_PK] = { - { - // - // PublicKey hash - // - { - 0xc7, 0xa1, 0xb9, 0x36, 0x28, 0x80, 0xde, 0x69, 0x57, 0x62, 0xb7, 0xb6, - 0x5b, 0xec, 0x6b, 0xf1, 0x56, 0xa5, 0x5c, 0xf9, 0x24, 0x7f, 0x22, 0xef, - 0x78, 0x62, 0x35, 0x53, 0x7f, 0x95, 0x2b, 0x45 - }, - (CONST OC_RSA_PUBLIC_KEY *)&mPkDb1 - }, - { - // - // PublicKey hash - // - { - 0x74, 0x61, 0x89, 0x8e, 0x6e, 0x62, 0x96, 0x2e, 0xdd, 0x64, 0x44, 0x71, - 0x45, 0xf0, 0xd9, 0xd0, 0x2b, 0xcc, 0x95, 0x19, 0x49, 0x20, 0x46, 0x67, - 0x1e, 0x1f, 0xcd, 0xdd, 0x18, 0xdc, 0x9b, 0x8b - }, - (CONST OC_RSA_PUBLIC_KEY *)&mPkDb2 - } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 gAppleX86SecureBootRootCaCert[] = { - 0x30, 0x82, 0x05, 0x62, 0x30, 0x82, 0x03, 0x4A, 0xA0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x08, 0x25, 0x2D, 0x14, 0x97, 0x18, 0x5C, 0x6A, 0xA0, 0x30, 0x0D, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C, 0x05, 0x00, 0x30, - 0x4F, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x41, - 0x70, 0x70, 0x6C, 0x65, 0x20, 0x58, 0x38, 0x36, 0x20, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x20, 0x42, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, - 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x41, 0x70, 0x70, 0x6C, 0x65, 0x20, 0x49, 0x6E, - 0x63, 0x2E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x33, 0x32, 0x32, 0x32, - 0x31, 0x34, 0x32, 0x34, 0x33, 0x5A, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x33, 0x32, - 0x33, 0x32, 0x31, 0x34, 0x32, 0x34, 0x33, 0x5A, 0x30, 0x4F, 0x31, 0x2B, 0x30, - 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x41, 0x70, 0x70, 0x6C, 0x65, - 0x20, 0x58, 0x38, 0x36, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, - 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, - 0x20, 0x47, 0x31, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, - 0x0A, 0x41, 0x70, 0x70, 0x6C, 0x65, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x0B, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, - 0x02, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0F, 0x00, 0x30, 0x82, 0x02, 0x0A, - 0x02, 0x82, 0x02, 0x01, 0x00, 0xB9, 0x98, 0x5C, 0x71, 0x28, 0x38, 0xA7, 0x89, - 0x96, 0x9E, 0x3C, 0x6E, 0xF6, 0xEE, 0x77, 0x26, 0x5D, 0x42, 0x65, 0xE0, 0xE8, - 0xA3, 0x5D, 0x71, 0x08, 0xC5, 0x5A, 0xD3, 0x86, 0x49, 0xBB, 0xC3, 0xB8, 0xBB, - 0x4D, 0x58, 0x74, 0x3F, 0xFB, 0x49, 0x55, 0xA6, 0xE4, 0xDA, 0x1B, 0xF0, 0x90, - 0xB9, 0x60, 0x2F, 0x2D, 0x45, 0x37, 0xB2, 0x41, 0xF0, 0x0C, 0x5D, 0x94, 0x30, - 0xB5, 0xCE, 0x9E, 0xC0, 0xCE, 0x88, 0x9B, 0x71, 0x42, 0xEE, 0x9B, 0xDD, 0x57, - 0xAB, 0x7D, 0x2B, 0xBE, 0x80, 0xD5, 0x4B, 0xB9, 0x2F, 0xAC, 0xAD, 0x56, 0xB4, - 0xCB, 0xCE, 0xFD, 0x36, 0xF9, 0xD7, 0xA8, 0xA4, 0xF5, 0x2A, 0x8F, 0x0E, 0x37, - 0x86, 0xA8, 0x76, 0x9A, 0xB6, 0xCC, 0x3A, 0x3F, 0x67, 0xC3, 0x5E, 0x92, 0x0E, - 0xAE, 0xB3, 0x79, 0x60, 0x72, 0x18, 0xCB, 0x28, 0xCD, 0xD3, 0xA4, 0x75, 0xAE, - 0xED, 0x4A, 0xE4, 0x54, 0x0B, 0x47, 0xAF, 0x92, 0xAB, 0x74, 0xDE, 0x34, 0xC9, - 0x26, 0xD2, 0xC3, 0xF0, 0x23, 0x4C, 0xFF, 0x49, 0x6D, 0x0C, 0x0B, 0xE4, 0xB2, - 0xF9, 0x5C, 0xF9, 0x1A, 0x0C, 0xEA, 0x36, 0xA3, 0x8B, 0x4F, 0x0F, 0x40, 0x3D, - 0x25, 0x42, 0xD0, 0xCB, 0x7F, 0x02, 0x89, 0x7A, 0xD7, 0x8A, 0x4C, 0x11, 0xDA, - 0xEA, 0x80, 0xE2, 0xC3, 0x25, 0x0E, 0xDD, 0x45, 0xC8, 0x04, 0x12, 0xFE, 0x40, - 0xEA, 0xCE, 0x17, 0xB5, 0xF5, 0x20, 0x81, 0x91, 0x64, 0xB2, 0x30, 0x86, 0xCD, - 0x12, 0x36, 0x15, 0x94, 0xB9, 0x6D, 0xA0, 0x14, 0xB6, 0x7D, 0x82, 0x4E, 0x48, - 0x11, 0x36, 0xEF, 0xF0, 0xCE, 0x72, 0x87, 0x87, 0x57, 0x7B, 0x4E, 0xF4, 0x6F, - 0x5D, 0x99, 0x89, 0x50, 0xE9, 0x77, 0x14, 0xAE, 0xA4, 0xF3, 0x41, 0xC6, 0xA4, - 0x6B, 0xDB, 0x0A, 0xFC, 0xB4, 0x92, 0xE4, 0x55, 0xA5, 0xED, 0x85, 0x46, 0x06, - 0x0C, 0xAA, 0xE2, 0x42, 0x72, 0x8B, 0x81, 0x6D, 0x55, 0xB8, 0x83, 0xE6, 0x59, - 0xB0, 0xBC, 0xE7, 0x8B, 0xEE, 0x09, 0x92, 0x13, 0x8C, 0xC9, 0x6F, 0xE0, 0xE6, - 0xEC, 0xC3, 0xD8, 0xED, 0x97, 0x5F, 0x53, 0xA1, 0xA4, 0x27, 0xBF, 0xE4, 0xD2, - 0xF7, 0x42, 0x08, 0x6B, 0xFB, 0x67, 0xBD, 0x30, 0x27, 0x85, 0x48, 0xB3, 0xC1, - 0xF6, 0x00, 0xEA, 0x54, 0x4B, 0x2F, 0x0F, 0x80, 0x41, 0x3C, 0xBB, 0x97, 0x50, - 0x5F, 0x92, 0x1F, 0xAE, 0x5A, 0x6D, 0x60, 0xAA, 0x1B, 0xD9, 0x29, 0x8F, 0xAA, - 0xF3, 0x67, 0x0B, 0x31, 0x1C, 0x1A, 0x98, 0x55, 0x3A, 0x76, 0xDE, 0x52, 0xEE, - 0x9B, 0xB9, 0xCE, 0xB7, 0xF3, 0x21, 0x2E, 0x22, 0x7B, 0x11, 0xF2, 0xD8, 0x69, - 0x46, 0x34, 0x05, 0x2C, 0x0B, 0x36, 0xCE, 0x72, 0xDE, 0x98, 0x8E, 0x6F, 0x6C, - 0xE8, 0x98, 0x9B, 0xFD, 0x9D, 0xA3, 0x4E, 0x4E, 0x5D, 0xDD, 0xFF, 0x99, 0x7A, - 0xD6, 0x1C, 0xB2, 0xCF, 0x4E, 0xA4, 0x73, 0x14, 0x43, 0x20, 0x5C, 0x78, 0x3D, - 0x3E, 0xF4, 0xE2, 0xCC, 0x3F, 0x6A, 0x20, 0xFF, 0x35, 0xC4, 0xA8, 0xEA, 0x15, - 0xED, 0x36, 0x99, 0x70, 0xD3, 0x61, 0x1C, 0x76, 0xDE, 0xBE, 0x66, 0x42, 0xFD, - 0xEA, 0x0A, 0x8F, 0x8F, 0x26, 0x54, 0x65, 0x96, 0xB6, 0xD8, 0x14, 0x87, 0xED, - 0x45, 0xC0, 0xAC, 0xE7, 0x40, 0xDE, 0x6E, 0xBE, 0x6E, 0x5A, 0x79, 0xF8, 0xC3, - 0x0B, 0x75, 0x95, 0x33, 0x0A, 0x33, 0x44, 0x7F, 0xE6, 0x3C, 0xED, 0xFA, 0x88, - 0x60, 0xAD, 0x3C, 0x04, 0xC3, 0x07, 0x1D, 0x74, 0x12, 0x99, 0x57, 0x66, 0xF0, - 0xEB, 0x23, 0xE9, 0xA6, 0x84, 0xB9, 0x71, 0x66, 0x58, 0x86, 0xBC, 0x73, 0x01, - 0x73, 0xB8, 0x2B, 0x7E, 0x0C, 0xE0, 0x9D, 0x35, 0x62, 0x62, 0x63, 0x00, 0xDD, - 0x54, 0xAA, 0xB3, 0x44, 0xE0, 0x86, 0x7C, 0x07, 0xB8, 0x9F, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xA3, 0x42, 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, - 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1D, 0x06, - 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x7D, 0x73, 0xCE, 0x0A, 0x3B, - 0x41, 0xA1, 0xA3, 0x52, 0xD2, 0xB1, 0x14, 0x1E, 0xF6, 0xF5, 0xB4, 0xDD, 0x76, - 0xE6, 0xE8, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, - 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x01, 0x0C, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x4E, - 0xE6, 0xD6, 0x55, 0x98, 0x77, 0xF5, 0xCD, 0xD3, 0x49, 0xDB, 0x61, 0x80, 0x90, - 0x63, 0x4C, 0xF1, 0x4C, 0x4D, 0xD0, 0xF5, 0xCC, 0x07, 0x8A, 0x05, 0x37, 0x69, - 0x0F, 0xED, 0x63, 0xED, 0x58, 0x6E, 0xF0, 0x3A, 0xFB, 0x8A, 0xD9, 0xFB, 0x90, - 0x9A, 0x4F, 0xDC, 0x9B, 0xE5, 0x41, 0x4E, 0x3A, 0xBE, 0xEF, 0xE4, 0xE4, 0x84, - 0x7D, 0x13, 0x24, 0xCC, 0xAC, 0x6C, 0xE4, 0xC3, 0x4D, 0x45, 0xAE, 0x95, 0x36, - 0xBF, 0xC1, 0xF5, 0x81, 0xDA, 0xA9, 0x9F, 0xB0, 0x14, 0x3D, 0xBF, 0xA5, 0xFC, - 0x21, 0xE0, 0x04, 0xC3, 0xFC, 0xCD, 0xDB, 0x58, 0x70, 0x25, 0xB0, 0x08, 0x46, - 0x68, 0x5B, 0x3B, 0xCB, 0x44, 0xE3, 0x78, 0x95, 0xC0, 0xD7, 0x8E, 0x06, 0xDD, - 0x4B, 0x4A, 0x91, 0x9D, 0xF1, 0x16, 0xE7, 0x45, 0x3B, 0xB6, 0x1A, 0x8B, 0xC9, - 0x8D, 0xC2, 0x2F, 0x63, 0x0C, 0xCE, 0x85, 0x43, 0x51, 0x1E, 0xE2, 0x27, 0x6E, - 0xBF, 0xCE, 0x08, 0x4E, 0x63, 0xB8, 0xB9, 0x60, 0xD7, 0xD5, 0x59, 0x90, 0x53, - 0x9E, 0x7B, 0xE1, 0x41, 0x61, 0xC9, 0xD8, 0xC7, 0x1B, 0xE6, 0x71, 0xBD, 0x44, - 0x6C, 0xBA, 0x8A, 0x65, 0xB9, 0x90, 0xA0, 0x3D, 0xF7, 0x27, 0xC3, 0x00, 0x50, - 0x48, 0x09, 0xB2, 0x6B, 0x5A, 0x12, 0xA5, 0x3B, 0x8C, 0x57, 0xB6, 0x5F, 0xD6, - 0x58, 0x7A, 0x35, 0x11, 0x2B, 0xAD, 0xDB, 0x97, 0x55, 0xCA, 0xC1, 0x22, 0xC2, - 0x8B, 0xB8, 0x27, 0x02, 0x72, 0x17, 0xA9, 0xD5, 0xEB, 0xCD, 0xE4, 0x50, 0xB1, - 0x37, 0xC4, 0x57, 0x31, 0x19, 0x73, 0x23, 0x4E, 0x55, 0xFB, 0x25, 0x9A, 0xCC, - 0x9A, 0xA5, 0xE7, 0x71, 0x9A, 0x53, 0x9A, 0xC0, 0xE7, 0xBA, 0xB1, 0xFC, 0x2A, - 0x9C, 0x28, 0xA3, 0x79, 0x0D, 0xFA, 0x02, 0xC6, 0xC9, 0x71, 0x09, 0x18, 0xAE, - 0x83, 0x4D, 0xCD, 0x4D, 0xB1, 0xD6, 0xF3, 0x53, 0xFC, 0x29, 0x16, 0xE4, 0x50, - 0x20, 0xB4, 0x2B, 0x8F, 0x52, 0x94, 0x2F, 0xF4, 0x3E, 0xD4, 0x76, 0x9E, 0x23, - 0xA2, 0x3B, 0x7F, 0x6C, 0xC4, 0xE7, 0xE8, 0x94, 0xD1, 0x18, 0xFF, 0xF3, 0x37, - 0xCA, 0xC2, 0x90, 0x2B, 0x35, 0x8C, 0x36, 0xC7, 0x6D, 0xFE, 0x93, 0x0A, 0xDB, - 0xB6, 0x90, 0x73, 0x7C, 0x92, 0x7E, 0x72, 0xF3, 0x2C, 0x18, 0x46, 0xDE, 0x13, - 0x1B, 0x76, 0xB8, 0x38, 0xB8, 0x30, 0x5D, 0x5C, 0xFD, 0x6C, 0xB0, 0x8B, 0xFC, - 0x3A, 0xEA, 0x9B, 0x82, 0x7D, 0x10, 0x82, 0xB0, 0xDB, 0x80, 0xCD, 0xB6, 0xD1, - 0x70, 0x25, 0x4F, 0x52, 0x26, 0xB8, 0x69, 0x80, 0x3D, 0x4A, 0x41, 0x92, 0x02, - 0x6F, 0x3C, 0x0C, 0x16, 0x2F, 0x82, 0x69, 0x76, 0xC3, 0x3A, 0x8F, 0x2E, 0xC7, - 0xBE, 0x35, 0xBF, 0x30, 0xA0, 0x8F, 0x85, 0x0E, 0x3C, 0xF1, 0xFC, 0x0E, 0xF2, - 0xC1, 0xC1, 0x93, 0x92, 0x74, 0xFE, 0xF5, 0xA8, 0xA4, 0x5E, 0x1D, 0x18, 0x3A, - 0x9B, 0xC4, 0xAD, 0x09, 0x16, 0x8F, 0x5F, 0xDC, 0x68, 0x29, 0x73, 0xC8, 0xE4, - 0x76, 0x20, 0xA9, 0x56, 0x2E, 0xD9, 0x85, 0xE5, 0x31, 0xB1, 0xC4, 0xAD, 0xA1, - 0xB2, 0xB1, 0x93, 0x4F, 0x24, 0x38, 0xAB, 0x70, 0xA1, 0x61, 0x43, 0x11, 0x8E, - 0x09, 0x2A, 0x37, 0xCE, 0x64, 0xA0, 0xD0, 0x23, 0x5D, 0x5E, 0xEE, 0x91, 0x2A, - 0xA5, 0x90, 0x8C, 0x82, 0xB9, 0x4B, 0x92, 0x67, 0x56, 0x34, 0xD7, 0x1D, 0x5D, - 0x29, 0x7F, 0x18, 0x19, 0x40, 0xE5, 0xE0, 0x54, 0xDA, 0x77, 0x1D, 0xB2, 0xF2, - 0x48, 0xB2, 0x69, 0x85, 0x1D, 0x11, 0xC5, 0x24, 0x66, 0xAB, 0x61, 0x4B, 0x7F, - 0x45, 0x3F, 0xC7, 0x06, 0x7C, 0x74, 0x2C, 0xDD, 0x2E, 0x95, 0x67, 0x0F, 0x83, - 0x50, 0x52, 0x8B, 0x27, 0x34, 0xEF, 0xC6, 0x79, 0xC9, 0x25, 0x1D, 0x75, 0x02, - 0x66, 0x08, 0x7E, 0x66 -}; - -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN gAppleX86SecureBootRootCaCertSize = - sizeof (gAppleX86SecureBootRootCaCert); diff --git a/Library/OcAppleKeysLib/OcAppleKeysLib.inf b/Library/OcAppleKeysLib/OcAppleKeysLib.inf deleted file mode 100644 index dd279e28a..000000000 --- a/Library/OcAppleKeysLib/OcAppleKeysLib.inf +++ /dev/null @@ -1,42 +0,0 @@ -## @file -# OcAppleVerificationLib -# -# Copyright (c) 2017-2018, savvas -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleKeysLib - FILE_GUID = 1CADD588-89D4-464C-92DC-FA0ABE350B16 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleKeysLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - OcAppleKeysLib.c - ../../Include/Library/OcAppleKeysLib.h - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseLib - diff --git a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c b/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c deleted file mode 100644 index a79430f6c..000000000 --- a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c +++ /dev/null @@ -1,601 +0,0 @@ -/** @file - Apple RAM Disk library. - -Copyright (C) 2019, Download-Fritz. All rights reserved.
-This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define INTERNAL_ASSERT_EXTENT_TABLE_VALID(ExtentTable) \ - ASSERT ((ExtentTable)->Signature == APPLE_RAM_DISK_EXTENT_SIGNATURE); \ - ASSERT ((ExtentTable)->Version == APPLE_RAM_DISK_EXTENT_VERSION); \ - ASSERT ((ExtentTable)->Reserved == 0); \ - ASSERT ((ExtentTable)->Signature2 == APPLE_RAM_DISK_EXTENT_SIGNATURE); \ - ASSERT ((ExtentTable)->ExtentCount > 0); \ - ASSERT ((ExtentTable)->ExtentCount <= ARRAY_SIZE ((ExtentTable)->Extents)) - -/** - Insert allocated area into extent list. If no extent list - was created, then it gets allocated. - - @param[in,out] ExtentTable Extent table, potentially pointing to NULL. - @param[in] AllocatedArea Allocated area of 1 or more pages. - @paran[in] AllocatedAreaSize Actual size of allocated area in bytes. -**/ -STATIC -VOID -InternalAddAllocatedArea ( - IN OUT APPLE_RAM_DISK_EXTENT_TABLE **ExtentTable, - IN EFI_PHYSICAL_ADDRESS AllocatedArea, - IN UINTN AllocatedAreaSize - ) -{ - APPLE_RAM_DISK_EXTENT_TABLE *Table; - - ASSERT (AllocatedArea + AllocatedAreaSize - 1 <= MAX_UINTN); - ASSERT (AllocatedAreaSize >= EFI_PAGE_SIZE); - - ZeroMem ( - (VOID *)(UINTN)AllocatedArea, - EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (AllocatedAreaSize)) - ); - - if (*ExtentTable == NULL) { - *ExtentTable = (APPLE_RAM_DISK_EXTENT_TABLE *)(UINTN)AllocatedArea; - - (*ExtentTable)->Signature = APPLE_RAM_DISK_EXTENT_SIGNATURE; - (*ExtentTable)->Version = APPLE_RAM_DISK_EXTENT_VERSION; - (*ExtentTable)->Signature2 = APPLE_RAM_DISK_EXTENT_SIGNATURE; - - AllocatedArea += EFI_PAGE_SIZE; - AllocatedAreaSize -= EFI_PAGE_SIZE; -/* - STATIC_ASSERT ( - sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == EFI_PAGE_SIZE, - "Extent table different from EFI_PAGE_SIZE is unsupported!" - ); -*/ - if (AllocatedAreaSize == 0) { - return; - } - } - - Table = *ExtentTable; - Table->Extents[Table->ExtentCount].Start = AllocatedArea; - Table->Extents[Table->ExtentCount].Length = AllocatedAreaSize; - ++Table->ExtentCount; -} - -/** - Perform allocation of RemainingSize data with biggest contiguous area - first strategy. Allocation extent map is put to the first allocated - extent. - - @param[in] BaseAddress Starting allocation address. - @param[in] TopAddress Ending allocation address. - @param[in] MemoryType Requested memory type. - @param[in,out] MemoryMap Current memory map modified as we go. - @param[in] MemoryMapSize Current memory map size. - @param[in] DescriptorSize Current memory map descriptor size. - @param[in] RemainingSize Remaining size to allocate. - @param[in,out] ExtentTable Updated pointer to allocated area. - - @retval Size of allocated data. -**/ -STATIC -UINTN -InternalAllocateRemainingSize ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN EFI_PHYSICAL_ADDRESS TopAddress, - IN EFI_MEMORY_TYPE MemoryType, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINTN RemainingSize, - IN OUT APPLE_RAM_DISK_EXTENT_TABLE **ExtentTable - ) -{ - EFI_STATUS Status; - EFI_MEMORY_DESCRIPTOR *EntryWalker; - EFI_MEMORY_DESCRIPTOR *BiggestEntry; - EFI_PHYSICAL_ADDRESS AllocatedArea; - UINT64 BiggestSize; - UINT64 UsedSize; - UINTN FinalUsedSize; - - // - // Require page aligned base and top addresses. - // - ASSERT (BaseAddress == EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BaseAddress))); - ASSERT (TopAddress == EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (TopAddress))); - - while (RemainingSize > 0 && (*ExtentTable == NULL - || (*ExtentTable)->ExtentCount < ARRAY_SIZE ((*ExtentTable)->Extents))) { - - BiggestEntry = NULL; - BiggestSize = 0; - - for ( - EntryWalker = MemoryMap; - (UINT8 *)EntryWalker < ((UINT8 *)MemoryMap + MemoryMapSize); - EntryWalker = NEXT_MEMORY_DESCRIPTOR (EntryWalker, DescriptorSize)) { - - // - // FIXME: This currently skips segments starting before BaseAddress but potentially lasting - // further: 0, PhysicalStart, BaseAddress, PhysicalEnd, infinity. This was done intentionally, - // to avoid splitting one entry into two, when TopAddress is before PhysicalEnd, but can still - // be improved. - // - if (EntryWalker->Type != EfiConventionalMemory - || EntryWalker->PhysicalStart < BaseAddress - || EntryWalker->PhysicalStart >= TopAddress) { - continue; - } - - UsedSize = EFI_PAGES_TO_SIZE (EntryWalker->NumberOfPages); - if (EntryWalker->PhysicalStart + UsedSize > TopAddress) { - // - // Guaranteed to be page aligned as TopAddress is page aligned. - // - UsedSize = TopAddress - EntryWalker->PhysicalStart; - } - - if (BiggestEntry == NULL || UsedSize > BiggestSize) { - BiggestEntry = EntryWalker; - BiggestSize = UsedSize; - } - } - - if (BiggestEntry == NULL || BiggestSize == 0) { - DEBUG (( - DEBUG_INFO, - "OCRAM: No entry for allocation %p / 0x%Lx bytes, rem 0x%Lx in 0x%Lx:0x%Lx\n", - BiggestEntry, - (UINT64) BiggestSize, - (UINT64) RemainingSize, - (UINT64) BaseAddress, - (UINT64) TopAddress - )); - return RemainingSize; - } - - FinalUsedSize = (UINTN) MIN (BiggestSize, RemainingSize); - - AllocatedArea = BiggestEntry->PhysicalStart; - Status = gBS->AllocatePages ( - AllocateAddress, - MemoryType, - EFI_SIZE_TO_PAGES (FinalUsedSize), - &AllocatedArea - ); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCRAM: Broken allocator for 0x%Lx in 0x%Lx bytes, rem 0x%Lx - %r\n", - (UINT64) BiggestEntry->PhysicalStart, - (UINT64) FinalUsedSize, - (UINT64) RemainingSize, - Status - )); - return RemainingSize; - } - - InternalAddAllocatedArea (ExtentTable, AllocatedArea, FinalUsedSize); - - RemainingSize -= FinalUsedSize; - - BiggestEntry->PhysicalStart += EFI_SIZE_TO_PAGES (FinalUsedSize); - BiggestEntry->NumberOfPages -= EFI_SIZE_TO_PAGES (FinalUsedSize); - } - - return RemainingSize; -} - -/** - Request allocation of Size bytes in extents table. - Extents are put to the first allocated page. - - 1. Retrieve actual memory mapping. - 2. Do allocation at BASE_4GB if requested. - 3. Do additional allocation at any address if still have pages to allocate. - - @param[in] Size Requested memory size. - @param[in] MemoryType Requested memory type. - @param[in] PreferHighMem Try to allocate in upper 4GB first. - - @retval Allocated extent table. -**/ -STATIC -CONST APPLE_RAM_DISK_EXTENT_TABLE * -InternalAppleRamDiskAllocate ( - IN UINTN Size, - IN EFI_MEMORY_TYPE MemoryType, - IN BOOLEAN PreferHighMem - ) -{ - BOOLEAN Result; - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN DescriptorSize; - UINTN RemainingSize; - APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable; - - MemoryMap = OcGetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL, NULL, FALSE); - if (MemoryMap == NULL) { - return NULL; - } -/* - STATIC_ASSERT ( - sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == EFI_PAGE_SIZE, - "Extent table different from EFI_PAGE_SIZE is unsupported!" - ); -*/ - Result = OcOverflowAddUN (Size, EFI_PAGE_SIZE, &RemainingSize); - if (Result) { - return NULL; - } - - ExtentTable = NULL; - - // - // We implement PreferHighMem to avoid colliding with the kernel, which sits - // in the lower addresses (see more detail in AptioMemoryFix) depending on - // KASLR offset generated randomly or with slide boot argument. - // - if (PreferHighMem) { - RemainingSize = InternalAllocateRemainingSize ( - BASE_4GB, - BASE_8EB, - MemoryType, - MemoryMap, - MemoryMapSize, - DescriptorSize, - RemainingSize, - &ExtentTable - ); - } - - // - // This may be tried improved when PreferHighMem is FALSE. - // 1. One way is implement a bugtracking algorithm, similar to DF algo originally in place. - // The allocations will go recursively from biggest >= BASE_4G until the strategy fails. - // When it does, last allocation is discarded, and the strategy tries lower in this case. - // memory until success. - // The implementation must be very careful about avoiding recursion and high complexity. - // 2. Another way could be to try to avoid allocating in kernel area specifically, though - // allowing to allocate in lower memory. This has a backdash of allocation failures - // when extent amount exceeds the limit, and may want a third pass. It may also collide - // with firmware pool allocator. - // - // None of those (or any extra) are implemented, as with PreferHighMem = TRUE it should - // always succeed allocating in higher memory on any host with >= 8 GB of RAM, which is - // the requirement for modern macOS. - // - RemainingSize = InternalAllocateRemainingSize ( - 0, - BASE_8EB, - MemoryType, - MemoryMap, - MemoryMapSize, - DescriptorSize, - RemainingSize, - &ExtentTable - ); - - if (RemainingSize > 0 && ExtentTable != NULL) { - OcAppleRamDiskFree (ExtentTable); - - ExtentTable = NULL; - } - - return ExtentTable; -} - -CONST APPLE_RAM_DISK_EXTENT_TABLE * -OcAppleRamDiskAllocate ( - IN UINTN Size, - IN EFI_MEMORY_TYPE MemoryType - ) -{ - CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable; - - // - // Try to allocate preferrably above BASE_4GB to avoid colliding with the kernel. - // - ExtentTable = InternalAppleRamDiskAllocate (Size, MemoryType, TRUE); - - if (ExtentTable == NULL) { - // - // Being here means that we exceeded entry amount in the extent table. - // Retry with any addresses. Should never happen in reality. - // - ExtentTable = InternalAppleRamDiskAllocate (Size, MemoryType, FALSE); - } -/* - DEBUG (( - DEBUG_BULK_INFO, - "OCRAM: Extent allocation of %u bytes (%x) gave %p\n", - (UINT32) Size, - (UINT32) MemoryType, - ExtentTable - )); -*/ - return ExtentTable; -} - -BOOLEAN -OcAppleRamDiskRead ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN Offset, - IN UINTN Size, - OUT VOID *Buffer - ) -{ - UINT8 *BufferBytes; - - UINT32 Index; - CONST APPLE_RAM_DISK_EXTENT *Extent; - - UINTN CurrentOffset; - UINTN LocalOffset; - UINTN LocalSize; - - ASSERT (ExtentTable != NULL); - INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable); - ASSERT (Size > 0); - ASSERT (Buffer != NULL); - - BufferBytes = Buffer; - // - // As per the allocation algorithm, the sum over all Extent->Length must be - // smaller than MAX_UINTN. - // - for ( - Index = 0, CurrentOffset = 0; - Index < ExtentTable->ExtentCount; - ++Index, CurrentOffset += (UINTN)Extent->Length - ) { - Extent = &ExtentTable->Extents[Index]; - ASSERT (Extent->Start <= MAX_UINTN); - ASSERT (Extent->Length <= MAX_UINTN); - - if (Offset >= CurrentOffset && (Offset - CurrentOffset) < Extent->Length) { - LocalOffset = (Offset - CurrentOffset); - LocalSize = (UINTN)MIN ((Extent->Length - LocalOffset), Size); - CopyMem ( - BufferBytes, - (VOID *)((UINTN)Extent->Start + LocalOffset), - LocalSize - ); - - Size -= LocalSize; - if (Size == 0) { - return TRUE; - } - - BufferBytes += LocalSize; - Offset += LocalSize; - } - } - - return FALSE; -} - -BOOLEAN -OcAppleRamDiskWrite ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN UINTN Offset, - IN UINTN Size, - IN CONST VOID *Buffer - ) -{ - CONST UINT8 *BufferBytes; - - UINT32 Index; - CONST APPLE_RAM_DISK_EXTENT *Extent; - - UINTN CurrentOffset; - UINTN LocalOffset; - UINTN LocalSize; - - ASSERT (ExtentTable != NULL); - INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable); - ASSERT (Size > 0); - ASSERT (Buffer != NULL); - - BufferBytes = Buffer; - // - // As per the allocation algorithm, the sum over all Extent->Length must be - // smaller than MAX_UINTN. - // - for ( - Index = 0, CurrentOffset = 0; - Index < ExtentTable->ExtentCount; - ++Index, CurrentOffset += (UINTN)Extent->Length - ) { - Extent = &ExtentTable->Extents[Index]; - ASSERT (Extent->Start <= MAX_UINTN); - ASSERT (Extent->Length <= MAX_UINTN); - - if (Offset >= CurrentOffset && (Offset - CurrentOffset) < Extent->Length) { - LocalOffset = (Offset - CurrentOffset); - LocalSize = (UINTN)MIN ((Extent->Length - LocalOffset), Size); - CopyMem ( - (VOID *)((UINTN)Extent->Start + LocalOffset), - BufferBytes, - LocalSize - ); - - Size -= LocalSize; - if (Size == 0) { - return TRUE; - } - - BufferBytes += LocalSize; - Offset += LocalSize; - } - } - - return FALSE; -} - -BOOLEAN -OcAppleRamDiskLoadFile ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable, - IN EFI_FILE_PROTOCOL *File, - IN UINTN FileSize - ) -{ - EFI_STATUS Status; - UINT64 FilePosition; - UINT32 Index; - UINTN RequestedSize; - UINTN ReadSize; - UINTN ExtentSize; - SHA256_CONTEXT Ctx; - UINT8 Digest[SHA256_DIGEST_SIZE]; - UINT8 *TmpBuffer; - UINT8 *ExtentBuffer; - - ASSERT (ExtentTable != NULL); - INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable); - ASSERT (File != NULL); - ASSERT (FileSize > 0); - - // - // We need a temporary buffer in lower addresses as several motherboards on APTIO IV, - // e.g. GA-Z77P-D3 (rev. 1.1), GA-Z87X-UD4H, etc. fail to read directly to high addresses - // when using FAT filesystem. The original workaround to this was AvoidHighAlloc quirk. - // REF: https://github.com/acidanthera/bugtracker/issues/449 - // - TmpBuffer = AllocatePool (BASE_4MB); - if (TmpBuffer == NULL) { - return FALSE; - } - - DEBUG_CODE_BEGIN (); - Sha256Init (&Ctx); - DEBUG_CODE_END (); - - FilePosition = 0; - - for (Index = 0; Index < ExtentTable->ExtentCount && FileSize > 0; ++Index) { - ASSERT (ExtentTable->Extents[Index].Start <= MAX_UINTN); - ASSERT (ExtentTable->Extents[Index].Length <= MAX_UINTN); - - ExtentBuffer = (VOID *)(UINTN) ExtentTable->Extents[Index].Start; - ExtentSize = (UINTN) ExtentTable->Extents[Index].Length; - - while (FileSize > 0 && ExtentSize > 0) { - Status = File->SetPosition (File, FilePosition); - if (EFI_ERROR(Status)) { - FreePool (TmpBuffer); - return FALSE; - } - - RequestedSize = MIN (MIN (BASE_4MB, FileSize), ExtentSize); - ReadSize = RequestedSize; - Status = File->Read ( - File, - &ReadSize, - TmpBuffer - ); - if (EFI_ERROR(Status) || RequestedSize != ReadSize) { - FreePool (TmpBuffer); - return FALSE; - } - - DEBUG_CODE_BEGIN (); - Sha256Update (&Ctx, TmpBuffer, ReadSize); - DEBUG_CODE_END (); - - CopyMem (ExtentBuffer, TmpBuffer, ReadSize); - - FilePosition += ReadSize; - ExtentBuffer += ReadSize; - ExtentSize -= ReadSize; - FileSize -= ReadSize; - } - } - - FreePool (TmpBuffer); - - // - // Not enough extents. - // - if (FileSize != 0) { - return FALSE; - } - - DEBUG_CODE_BEGIN (); - Sha256Final (&Ctx, Digest); - DEBUG (( - DEBUG_INFO, - "OCRAM: SHA-256 Digest is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", - Digest[0], Digest[1], Digest[2], Digest[3], Digest[4], Digest[5], Digest[6], Digest[7], Digest[8], Digest[9], - Digest[10], Digest[11], Digest[12], Digest[13], Digest[14], Digest[15], Digest[16], Digest[17], Digest[18], Digest[19], - Digest[20], Digest[21], Digest[22], Digest[23], Digest[24], Digest[25], Digest[26], Digest[27], Digest[28], Digest[29], - Digest[30], Digest[31] - )); - DEBUG_CODE_END (); - return TRUE; -} - -VOID -OcAppleRamDiskFree ( - IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable - ) -{ - UINT32 Index; - - ASSERT (ExtentTable != NULL); - INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable); - ASSERT (ExtentTable->Extents[0].Start <= MAX_UINTN); - ASSERT (ExtentTable->Extents[0].Length <= MAX_UINTN); - - // - // Extents are allocated in the first page. - // - for (Index = 1; Index < ExtentTable->ExtentCount; ++Index) { - ASSERT (ExtentTable->Extents[Index].Start <= MAX_UINTN); - ASSERT (ExtentTable->Extents[Index].Length <= MAX_UINTN); - - gBS->FreePages ( - (UINTN)ExtentTable->Extents[Index].Start, - (UINTN)EFI_SIZE_TO_PAGES (ExtentTable->Extents[Index].Length) - ); - } - // - // One page is added to account for the header. - // - gBS->FreePages ( - (UINTN)ExtentTable, - (UINTN)EFI_SIZE_TO_PAGES (ExtentTable->Extents[0].Length) + 1 - ); -} diff --git a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf b/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf deleted file mode 100644 index dc9c6b493..000000000 --- a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf +++ /dev/null @@ -1,37 +0,0 @@ -## @file -# Apple RAM Disk library. -# -# Copyright (C) 2019, Download-Fritz. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcAppleRamDiskLib - FILE_GUID = 57734401-29DB-49C6-816C-BF333A72BBA3 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcAppleRamDiskLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - MemoryAllocationLib - OcMemoryLib - UefiBootServicesTableLib - -[Sources] - OcAppleRamDiskLib.c - ../../Include/Library/OcAppleRamDiskLib.h diff --git a/Library/OcBootManagementLib/AppleHibernate.c b/Library/OcBootManagementLib/AppleHibernate.c deleted file mode 100644 index 4de2600ab..000000000 --- a/Library/OcBootManagementLib/AppleHibernate.c +++ /dev/null @@ -1,271 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_STATUS -OcActivateHibernateWake ( - IN UINT32 HibernateMask - ) -{ - EFI_STATUS Status; - UINTN Size; - UINT32 Attributes; - VOID *Value; - AppleRTCHibernateVars RtcVars; - BOOLEAN HasHibernateInfo; - BOOLEAN HasHibernateInfoInRTC; - UINT8 Index; - UINT8 *RtcRawVars; - EFI_DEVICE_PATH_PROTOCOL *BootImagePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingPath; - INTN NumPatchedNodes; - - if (HibernateMask == HIBERNATE_MODE_NONE) { - return EFI_NOT_FOUND; - } - - HasHibernateInfo = FALSE; - HasHibernateInfoInRTC = FALSE; - - // - // If legacy boot-switch-vars exists (NVRAM working), then use it. - // - Status = GetVariable2 (L"boot-switch-vars", &gEfiAppleBootGuid, &Value, &Size); - if (!EFI_ERROR(Status)) { - // - // Leave it as is. - // - SecureZeroMem (Value, Size); - FreePool (Value); - DEBUG ((DEBUG_INFO, "OCB: Found legacy boot-switch-vars\n")); - return EFI_SUCCESS; - } - - Status = GetVariable3 ( - L"boot-image", - &gEfiAppleBootGuid, - (VOID **)&BootImagePath, - &Size, - &Attributes - ); - if (!EFI_ERROR(Status)) { - if (IsDevicePathValid (BootImagePath, Size)) { - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: boot-image pre-fix", - BootImagePath - ); - - RemainingPath = BootImagePath; - NumPatchedNodes = OcFixAppleBootDevicePath (&RemainingPath); - if (NumPatchedNodes > 0) { - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: boot-image post-fix", - BootImagePath - ); - - Status = gRT->SetVariable ( - L"boot-image", - &gEfiAppleBootGuid, - Attributes, - Size, - BootImagePath - ); - } - if (NumPatchedNodes >= 0) { - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: boot-image post-fix remainder", - RemainingPath - ); - } - } else { - DEBUG ((DEBUG_INFO, "OCB: Invalid boot-image variable\n")); - } - - SecureZeroMem (BootImagePath, Size); - FreePool (BootImagePath); - } - - DEBUG ((DEBUG_INFO, "OCB: boot-image is %u bytes - %r\n", (UINT32) Size, Status)); - - RtcRawVars = (UINT8 *) &RtcVars; - - // - // Work with RTC memory if allowed. - // - if (HibernateMask & HIBERNATE_MODE_RTC) { - for (Index = 0; Index < sizeof (AppleRTCHibernateVars); Index++) { - RtcRawVars[Index] = OcRtcRead (Index + 128); - } - - HasHibernateInfoInRTC = RtcVars.signature[0] == 'A' - && RtcVars.signature[1] == 'A' - && RtcVars.signature[2] == 'P' - && RtcVars.signature[3] == 'L'; - HasHibernateInfo = HasHibernateInfoInRTC; - - DEBUG ((DEBUG_INFO, "OCB: RTC hibernation is %d\n", HasHibernateInfoInRTC)); - } - - if (HibernateMask & HIBERNATE_MODE_NVRAM) { - // - // If RTC variables is still written to NVRAM (and RTC is broken). - // Prior to 10.13.6. - // - Status = GetVariable2 (L"IOHibernateRTCVariables", &gEfiAppleBootGuid, &Value, &Size); - if (!HasHibernateInfo && !EFI_ERROR(Status) && Size == sizeof (RtcVars)) { - CopyMem (RtcRawVars, Value, sizeof (RtcVars)); - HasHibernateInfo = RtcVars.signature[0] == 'A' - && RtcVars.signature[1] == 'A' - && RtcVars.signature[2] == 'P' - && RtcVars.signature[3] == 'L'; - } - - DEBUG (( - DEBUG_INFO, - "OCB: NVRAM hibernation is %d / %r / %u\n", - HasHibernateInfo, - Status, - (UINT32) Size - )); - - // - // Erase RTC variables in NVRAM. - // - if (!EFI_ERROR(Status)) { - Status = gRT->SetVariable ( - L"IOHibernateRTCVariables", - &gEfiAppleBootGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, - NULL - ); - SecureZeroMem (Value, Size); - FreePool (Value); - } - } - - // - // Convert RTC data to boot-key and boot-signature - // - if (HasHibernateInfo) { - gRT->SetVariable ( - L"boot-image-key", - &gEfiAppleBootGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (RtcVars.wiredCryptKey), - RtcVars.wiredCryptKey - ); - gRT->SetVariable ( - L"boot-signature", - &gEfiAppleBootGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (RtcVars.booterSignature), - RtcVars.booterSignature - ); - } - - // - // Erase RTC memory similarly to AppleBds. - // - if (HasHibernateInfoInRTC) { - SecureZeroMem (RtcRawVars, sizeof(AppleRTCHibernateVars)); - RtcVars.signature[0] = 'D'; - RtcVars.signature[1] = 'E'; - RtcVars.signature[2] = 'A'; - RtcVars.signature[3] = 'D'; - - for (Index = 0; Index < sizeof(AppleRTCHibernateVars); Index++) { - OcRtcWrite (Index + 128, RtcRawVars[Index]); - } - } - - // - // We have everything we need now. - // - if (HasHibernateInfo) { - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} - -BOOLEAN -OcIsAppleHibernateWake ( - VOID - ) -{ - EFI_STATUS Status; - UINTN ValueSize; - - // - // This is reverse engineered from boot.efi. - // To cancel hibernate wake it is enough to delete the variables. - // Starting with 10.13.6 boot-switch-vars is no longer supported. - // - ValueSize = 0; - Status = gRT->GetVariable ( - L"boot-signature", - &gEfiAppleBootGuid, - NULL, - &ValueSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - ValueSize = 0; - Status = gRT->GetVariable ( - L"boot-image-key", - &gEfiAppleBootGuid, - NULL, - &ValueSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - return TRUE; - } - } else { - ValueSize = 0; - Status = gRT->GetVariable ( - L"boot-switch-vars", - &gEfiAppleBootGuid, - NULL, - &ValueSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - return TRUE; - } - } - - return FALSE; -} diff --git a/Library/OcBootManagementLib/ApplePanic.c b/Library/OcBootManagementLib/ApplePanic.c deleted file mode 100644 index 3d307f825..000000000 --- a/Library/OcBootManagementLib/ApplePanic.c +++ /dev/null @@ -1,322 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -VOID * -PanicUnpack ( - IN CONST VOID *Packed, - IN UINTN PackedSize, - OUT UINTN *UnpackedSize - ) -{ - VOID *Unpacked; - CONST UINT8 *PackedWalker; - UINT8 *UnpackedWalker; - UINT64 Sequence; - - if (OcOverflowMulUN (PackedSize, 8, UnpackedSize)) { - return NULL; - } - - // - // Source buffer is required to be 8-byte aligned by Apple, - // so we can freely truncate here. - // - *UnpackedSize /= 7; - *UnpackedSize = *UnpackedSize - (*UnpackedSize % 8); - if (*UnpackedSize == 0 || OcOverflowAddUN (*UnpackedSize, 1, UnpackedSize)) { - return NULL; - } - - Unpacked = AllocatePool (*UnpackedSize); - if (Unpacked == NULL) { - return NULL; - } - - Sequence = 0; - PackedWalker = Packed; - UnpackedWalker = Unpacked; - - while (PackedSize >= 7) { - CopyMem (&Sequence, PackedWalker, 7); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 0, 7 * 0 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 1, 7 * 1 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 2, 7 * 2 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 3, 7 * 3 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 4, 7 * 4 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 5, 7 * 5 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 6, 7 * 6 + 6); - *UnpackedWalker++ = (UINT8) BitFieldRead64 (Sequence, 7 * 7, 7 * 7 + 6); - PackedWalker += 7; - PackedSize -= 7; - } - - // - // Ensure null-termination. - // - *UnpackedWalker++ = '\0'; - - return Unpacked; -} - -STATIC -BOOLEAN -PanicExpandPutBuf ( - IN OUT CHAR8 **Buffer, - IN OUT UINTN *AllocatedSize, - IN OUT UINTN *CurrentSize, - IN CONST CHAR8 *NewData, - IN UINTN NewDataSize - ) -{ - CHAR8 *TmpBuffer; - UINTN NewSize; - - if (*AllocatedSize - *CurrentSize <= NewDataSize) { - if (*AllocatedSize > 0) { - NewSize = *AllocatedSize; - } else { - NewSize = NewDataSize; - } - - NewSize = MAX (NewSize, 8192); - - if (OcOverflowMulUN (NewSize, 2, &NewSize)) { - if (*Buffer != NULL) { - FreePool (*Buffer); - } - return FALSE; - } - - TmpBuffer = ReallocatePool (*AllocatedSize, NewSize, *Buffer); - if (TmpBuffer == NULL) { - if (*Buffer != NULL) { - FreePool (*Buffer); - } - return FALSE; - } - - *Buffer = TmpBuffer; - *AllocatedSize = NewSize; - } - - CopyMem (*Buffer + *CurrentSize, NewData, NewDataSize); - *CurrentSize += NewDataSize; - return TRUE; -} - -STATIC -CHAR8 * -PanicExpand ( - IN CONST CHAR8 *Encoded, - IN UINTN EncodedSize, - OUT UINTN *ExpandedSize - ) -{ - CHAR8 *Expanded; - UINTN AllocatedSize; - UINTN CurrentSize; - UINTN TmpSize; - CHAR8 *EncodedStart; - BOOLEAN Success; - - EncodedStart = AsciiStrStr (Encoded, "loaded kext"); - if (EncodedStart == NULL) { - return NULL; ///< Not encoded. - } - - Expanded = NULL; - AllocatedSize = 0; - CurrentSize = 0; - - TmpSize = EncodedStart - EncodedStart; - - if (!PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, Encoded, TmpSize)) { - return NULL; - } - - Encoded += TmpSize; - EncodedSize -= TmpSize; - - while (EncodedSize > 0) { - TmpSize = 1; - - switch (Encoded[0]) { - case '>': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "com.apple.driver.", L_STR_LEN ("com.apple.driver.")); - break; - case '|': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "com.apple.iokit.", L_STR_LEN ("com.apple.iokit.")); - break; - case '$': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "com.apple.security.", L_STR_LEN ("com.apple.security.")); - break; - case '@': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "com.apple.", L_STR_LEN ("com.apple.")); - break; - case '!': - if (EncodedSize >= 2) { - ++TmpSize; - switch (Encoded[1]) { - case 'U': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "AppleUSB", L_STR_LEN ("AppleUSB")); - break; - case 'A': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Apple", L_STR_LEN ("Apple")); - break; - case 'F': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Family", L_STR_LEN ("Family")); - break; - case 'S': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Storage", L_STR_LEN ("Storage")); - break; - case 'C': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Controller", L_STR_LEN ("Controller")); - break; - case 'B': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Bluetooth", L_STR_LEN ("Bluetooth")); - break; - case 'I': - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, "Intel", L_STR_LEN ("Intel")); - break; - default: - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, Encoded, 2); - break; - } - break; - } - /* Fallthrough */ - default: - Success = PanicExpandPutBuf (&Expanded, &AllocatedSize, &CurrentSize, Encoded, 1); - break; - } - - if (!Success) { - return NULL; - } - - Encoded += TmpSize; - EncodedSize -= TmpSize; - } - - *ExpandedSize = CurrentSize; - - // - // One extra byte is always guaranteed. - // - Expanded[CurrentSize] = '\0'; - - return Expanded; -} - -VOID * -OcReadApplePanicLog ( - OUT UINT32 *PanicSize - ) -{ - EFI_STATUS Status; - UINT32 Index; - VOID *Value; - UINTN ValueSize; - CHAR16 VariableName[32]; - VOID *TmpData; - UINTN TmpDataSize; - VOID *PanicData; - - TmpData = NULL; - TmpDataSize = 0; - - for (Index = 0; Index < 1024; ++Index) { - UnicodeSPrint ( - VariableName, - sizeof (VariableName), - APPLE_PANIC_INFO_NO_VARIABLE_NAME, - Index - ); - Status = GetVariable2 (VariableName, &gEfiAppleBootGuid, &Value, &ValueSize); - if (EFI_ERROR(Status)) { - break; - } - - if (ValueSize == 0) { - FreePool (Value); - break; - } - - PanicData = ReallocatePool (TmpDataSize, TmpDataSize + ValueSize, TmpData); - if (PanicData == NULL) { - FreePool (Value); - if (TmpData != NULL) { - FreePool (TmpData); - } - return NULL; - } - TmpData = PanicData; - - CopyMem ( - (UINT8 *) TmpData + TmpDataSize, - Value, - ValueSize - ); - - FreePool (Value); - TmpDataSize += ValueSize; - } - - if (Index == 0) { - // - // We have not advanced past the first variable, there is no panic log. - // - return NULL; - } - - // - // We have a kernel panic now. - // - ASSERT (TmpData != NULL); - ASSERT (TmpDataSize > 0); - - PanicData = PanicUnpack (TmpData, TmpDataSize, &TmpDataSize); - FreePool (TmpData); - - if (PanicData != NULL) { - // - // Truncate trailing zeroes. - // - TmpDataSize = AsciiStrLen (PanicData); - TmpData = PanicExpand (PanicData, TmpDataSize, &TmpDataSize); - if (TmpData != NULL) { - FreePool (PanicData); - PanicData = TmpData; - } - } - - *PanicSize = (UINT32) TmpDataSize; - - return TmpData; -} diff --git a/Library/OcBootManagementLib/BootArguments.c b/Library/OcBootManagementLib/BootArguments.c deleted file mode 100644 index 45da7380c..000000000 --- a/Library/OcBootManagementLib/BootArguments.c +++ /dev/null @@ -1,248 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include - -VOID -OcParseBootArgs ( - OUT OC_BOOT_ARGUMENTS *Arguments, - IN VOID *BootArgs - ) -{ - BootArgs1 *BA1 = (BootArgs1 *) BootArgs; - BootArgs2 *BA2 = (BootArgs2 *) BootArgs; - - ZeroMem (Arguments, sizeof (*Arguments)); - - if (BA1->Version == kBootArgsVersion1) { - // - // Pre Lion - // - Arguments->MemoryMap = &BA1->MemoryMap; - Arguments->MemoryMapSize = &BA1->MemoryMapSize; - Arguments->MemoryMapDescriptorSize = &BA1->MemoryMapDescriptorSize; - Arguments->MemoryMapDescriptorVersion = &BA1->MemoryMapDescriptorVersion; - - Arguments->CommandLine = &BA1->CommandLine[0]; - - Arguments->DeviceTreeP = &BA1->deviceTreeP; - Arguments->DeviceTreeLength = &BA1->deviceTreeLength; - Arguments->SystemTable = (EFI_SYSTEM_TABLE*)(UINTN) BA1->efiSystemTable; - } else { - // - // Lion and newer - // - Arguments->MemoryMap = &BA2->MemoryMap; - Arguments->MemoryMapSize = &BA2->MemoryMapSize; - Arguments->MemoryMapDescriptorSize = &BA2->MemoryMapDescriptorSize; - Arguments->MemoryMapDescriptorVersion = &BA2->MemoryMapDescriptorVersion; - - Arguments->CommandLine = &BA2->CommandLine[0]; - - Arguments->DeviceTreeP = &BA2->deviceTreeP; - Arguments->DeviceTreeLength = &BA2->deviceTreeLength; - Arguments->SystemTable = (EFI_SYSTEM_TABLE*)(UINTN) BA2->efiSystemTable; - - if (BA2->flags & kBootArgsFlagCSRActiveConfig) { - Arguments->CsrActiveConfig = &BA2->csrActiveConfig; - } - } -} - -CONST CHAR8 * -OcGetArgumentFromCmd ( - IN CONST CHAR8 *CommandLine, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ) -{ - CHAR8 *Str; - - Str = AsciiStrStr (CommandLine, Argument); - - // - // Invalidate found boot arg if: - // - it is neither the beginning of Cmd, nor has space prefix -> boot arg is a suffix of another arg - // - it has neither space suffix, nor \0 suffix, and does not end with = -> boot arg is a prefix of another arg - // - if (!Str || (Str != CommandLine && *(Str - 1) != ' ') || - (Str[ArgumentLength] != ' ' && Str[ArgumentLength] != '\0' && - Str[ArgumentLength - 1] != '=')) { - return NULL; - } - - return Str + ArgumentLength; -} - -VOID -OcRemoveArgumentFromCmd ( - IN OUT CHAR8 *CommandLine, - IN CONST CHAR8 *Argument - ) -{ - CHAR8 *Match; - - Match = NULL; - - do { - Match = AsciiStrStr (CommandLine, Argument); - if (Match && (Match == CommandLine || *(Match - 1) == ' ')) { - while (*Match != ' ' && *Match != '\0') { - *Match++ = ' '; - } - } - } while (Match != NULL); - - // - // Write zeroes to reduce data leak - // - CHAR8 *Updated = CommandLine; - - while (CommandLine[0] == ' ') { - CommandLine++; - } - - while (CommandLine[0] != '\0') { - while (CommandLine[0] == ' ' && CommandLine[1] == ' ') { - CommandLine++; - } - - *Updated++ = *CommandLine++; - } - - ZeroMem (Updated, CommandLine - Updated); -} - -BOOLEAN -OcAppendArgumentToCmd ( - IN OUT OC_PICKER_CONTEXT *Context OPTIONAL, - IN OUT CHAR8 *CommandLine, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ) -{ - EFI_STATUS Status; - UINTN Len = AsciiStrLen (CommandLine); - - if (Context != NULL) { - Status = Context->RequestPrivilege ( - Context, - OcPrivilegeAuthorized - ); - if (EFI_ERROR(Status)) { - if (Status != EFI_ABORTED) { - ASSERT (FALSE); - return FALSE; - } - - return TRUE; - } - } - - // - // Account for extra space. - // - if (Len + (Len > 0 ? 1 : 0) + ArgumentLength >= BOOT_LINE_LENGTH) { - DEBUG ((DEBUG_INFO, "OCB: boot-args are invalid, ignoring\n")); - return FALSE; - } - - if (Len > 0) { - CommandLine += Len; - *CommandLine++ = ' '; - } - - AsciiStrnCpyS (CommandLine, ArgumentLength + 1, Argument, ArgumentLength + 1); - return TRUE; -} - -BOOLEAN -OcCheckArgumentFromEnv ( - IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL, - IN EFI_GET_VARIABLE GetVariable OPTIONAL, - IN CONST CHAR8 *Argument, - IN CONST UINTN ArgumentLength - ) -{ - CHAR16 *Options; - UINTN OptionsSize; - CHAR8 BootArgsVar[BOOT_LINE_LENGTH]; - UINTN BootArgsVarLen; - EFI_STATUS Status; - UINTN LastIndex; - CHAR16 Last; - BOOLEAN HasArgument; - - HasArgument = FALSE; - - if (LoadedImage != NULL) { - Options = (CHAR16 *) LoadedImage->LoadOptions; - OptionsSize = LoadedImage->LoadOptionsSize / sizeof (CHAR16); - - if (Options != NULL && OptionsSize > 0) { - // - // Just in case we do not have 0-termination. - // This may cut some data with unexpected options, but it is not like we care. - // - LastIndex = OptionsSize - 1; - Last = Options[LastIndex]; - Options[LastIndex] = '\0'; - - UnicodeStrToAsciiStrS (Options, BootArgsVar, BOOT_LINE_LENGTH); - - if (OcGetArgumentFromCmd (BootArgsVar, Argument, ArgumentLength)) { - HasArgument = TRUE; - } - - // - // Options do not belong to us, restore the changed value. - // - Options[LastIndex] = Last; - } - } - - if (!HasArgument) { - // - // Important to avoid triggering boot-args wrapper too early if we have any. - // - BootArgsVarLen = sizeof (BootArgsVar); - Status = (GetVariable != NULL ? GetVariable : gRT->GetVariable) ( - L"boot-args", - &gEfiAppleBootGuid, - NULL, - &BootArgsVarLen, - BootArgsVar - ); - - if (!EFI_ERROR(Status) && BootArgsVarLen > 0) { - // - // Just in case we do not have 0-termination - // - BootArgsVar[BootArgsVarLen-1] = '\0'; - - if (OcGetArgumentFromCmd (BootArgsVar, Argument, ArgumentLength)) { - HasArgument = TRUE; - } - } - } - - return HasArgument; -} diff --git a/Library/OcBootManagementLib/BootAudio.c b/Library/OcBootManagementLib/BootAudio.c deleted file mode 100644 index 07ad893f3..000000000 --- a/Library/OcBootManagementLib/BootAudio.c +++ /dev/null @@ -1,235 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_STATUS -OcPlayAudioFile ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 File, - IN BOOLEAN Fallback - ) -{ - EFI_STATUS Status; - - if (!Context->PickerAudioAssist) { - return EFI_SUCCESS; - } - - if (Context->OcAudio == NULL) { - Status = gBS->LocateProtocol ( - &gOcAudioProtocolGuid, - NULL, - (VOID **) &Context->OcAudio - ); - if (EFI_ERROR(Status)) { - Context->OcAudio = NULL; - } - } - - if (Context->OcAudio != NULL) { - Status = Context->OcAudio->PlayFile (Context->OcAudio, File, TRUE); - } - - if (Fallback && EFI_ERROR(Status)) { - switch (File) { - case AppleVoiceOverAudioFileBeep: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_NORMAL, - OC_VOICE_OVER_SIGNAL_NORMAL_MS, - OC_VOICE_OVER_SILENCE_NORMAL_MS - ); - break; - case OcVoiceOverAudioFileEnterPassword: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_PASSWORD, - OC_VOICE_OVER_SIGNAL_NORMAL_MS, - OC_VOICE_OVER_SILENCE_NORMAL_MS - ); - break; - case OcVoiceOverAudioFilePasswordAccepted: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_PASSWORD_OK, - OC_VOICE_OVER_SIGNAL_NORMAL_MS, - OC_VOICE_OVER_SILENCE_NORMAL_MS - ); - break; - case OcVoiceOverAudioFilePasswordIncorrect: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_ERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - break; - case OcVoiceOverAudioFilePasswordRetryLimit: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_HWERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - break; - case OcVoiceOverAudioFileExecutionFailure: - Status = OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_ERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SIGNAL_NORMAL_MS - ); - break; - default: - // - // Should we introduce some special code? - // - break; - } - } - - return Status; -} - -EFI_STATUS -OcPlayAudioBeep ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 ToneCount, - IN UINT32 ToneLength, - IN UINT32 SilenceLength - ) -{ - EFI_STATUS Status; - - if (!Context->PickerAudioAssist) { - return EFI_SUCCESS; - } - - if (Context->BeepGen == NULL) { - Status = gBS->LocateProtocol ( - &gAppleBeepGenProtocolGuid, - NULL, - (VOID **) &Context->BeepGen - ); - if (EFI_ERROR(Status)) { - return Status; - } - } - - if (Context->BeepGen->GenBeep == NULL) { - return EFI_UNSUPPORTED; - } - - return Context->BeepGen->GenBeep (ToneCount, ToneLength, SilenceLength); -} - -EFI_STATUS -OcPlayAudioEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *Entry - ) -{ - OcPlayAudioFile (Context, OcVoiceOverAudioFileIndexBase + Entry->EntryIndex, FALSE); - - if (Entry->Type == OC_BOOT_APPLE_OS) { - OcPlayAudioFile (Context, OcVoiceOverAudioFilemacOS, FALSE); - } else if (Entry->Type == OC_BOOT_APPLE_RECOVERY) { - OcPlayAudioFile (Context, OcVoiceOverAudioFilemacOS_Recovery, FALSE); - } else if (Entry->Type == OC_BOOT_APPLE_TIME_MACHINE) { - OcPlayAudioFile (Context, OcVoiceOverAudioFilemacOS_TimeMachine, FALSE); - } else if (Entry->Type == OC_BOOT_APPLE_FW_UPDATE) { - OcPlayAudioFile (Context, OcVoiceOverAudioFilemacOS_UpdateFw, FALSE); - } else if (Entry->Type == OC_BOOT_WINDOWS) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileWindows, FALSE); - } else if (Entry->Type == OC_BOOT_RESET_NVRAM || StrStr (Entry->Name, OC_MENU_RESET_NVRAM_ENTRY) != NULL) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileResetNVRAM, FALSE); - } else if (StrStr (Entry->Name, OC_MENU_UEFI_SHELL_ENTRY) != NULL) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileUEFI_Shell, FALSE); - } else if (Entry->Type == OC_BOOT_EXTERNAL_OS) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileExternalOS, FALSE); - } else if (Entry->Type == OC_BOOT_EXTERNAL_TOOL) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileExternalTool, FALSE); - } else { - OcPlayAudioFile (Context, OcVoiceOverAudioFileOtherOS, FALSE); - } - - if (Entry->IsFolder) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileDiskImage, FALSE); - } - - if (Entry->IsExternal) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileExternal, FALSE); - } - - return EFI_SUCCESS; -} - -VOID -OcToggleVoiceOver ( - IN OC_PICKER_CONTEXT *Context, - IN UINT32 File OPTIONAL - ) -{ - if (!Context->PickerAudioAssist) { - Context->PickerAudioAssist = TRUE; - OcPlayAudioFile (Context, OcVoiceOverAudioFileWelcome, FALSE); - - if (File != 0) { - OcPlayAudioFile (Context, File, TRUE); - } - } else { - OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_ERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - Context->PickerAudioAssist = FALSE; - } -} diff --git a/Library/OcBootManagementLib/BootEntryInfo.c b/Library/OcBootManagementLib/BootEntryInfo.c deleted file mode 100644 index 1da559832..000000000 --- a/Library/OcBootManagementLib/BootEntryInfo.c +++ /dev/null @@ -1,579 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CHAR16 * -InternalGetAppleDiskLabel ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *BootDirectoryName, - IN CONST CHAR16 *LabelFilename - ) -{ - CHAR16 *DiskLabelPath; - UINTN DiskLabelPathSize; - CHAR8 *AsciiDiskLabel; - CHAR16 *UnicodeDiskLabel; - UINT32 DiskLabelLength; - - DiskLabelPathSize = StrSize (BootDirectoryName) + StrSize (LabelFilename) - sizeof (CHAR16); - DiskLabelPath = AllocatePool (DiskLabelPathSize); - - if (DiskLabelPath == NULL) { - return NULL; - } - - UnicodeSPrint (DiskLabelPath, DiskLabelPathSize, L"%s%s", BootDirectoryName, LabelFilename); - DEBUG ((DEBUG_INFO, "OCB: Trying to get label from %s\n", DiskLabelPath)); - - AsciiDiskLabel = (CHAR8 *) ReadFile (FileSystem, DiskLabelPath, &DiskLabelLength, OC_MAX_VOLUME_LABEL_SIZE); - FreePool (DiskLabelPath); - - if (AsciiDiskLabel != NULL) { - UnicodeDiskLabel = AsciiStrCopyToUnicode (AsciiDiskLabel, DiskLabelLength); - if (UnicodeDiskLabel != NULL) { - UnicodeFilterString (UnicodeDiskLabel, TRUE); - } - FreePool (AsciiDiskLabel); - } else { - UnicodeDiskLabel = NULL; - } - - return UnicodeDiskLabel; -} - -EFI_STATUS -InternalGetAppleImage ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *DirectoryName, - IN CONST CHAR16 *LabelFilename, - OUT VOID **ImageData, - OUT UINT32 *DataSize - ) -{ - CHAR16 *ImagePath; - UINTN ImagePathSize; - - ImagePathSize = StrSize (DirectoryName) + StrSize (LabelFilename) - sizeof (CHAR16); - ImagePath = AllocatePool (ImagePathSize); - - if (ImagePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - UnicodeSPrint (ImagePath, ImagePathSize, L"%s%s", DirectoryName, LabelFilename); - DEBUG ((DEBUG_INFO, "OCB: Trying to get image from %s\n", ImagePath)); - - *ImageData = ReadFile (FileSystem, ImagePath, DataSize, BASE_16MB); - - FreePool (ImagePath); - - if (*ImageData == NULL) { - return EFI_NOT_FOUND; - } - - // - // Whether it is disk label or .icns, disk label is always smaller. - // Early abort on obviously small images. - // - if (*DataSize <= sizeof (APPLE_DISK_LABEL)) { - FreePool (*ImageData); - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -STATIC -CHAR16 * -GetAppleRecoveryNameFromPlist ( - IN CHAR8 *SystemVersionData, - IN UINT32 SystemVersionDataSize - ) -{ - XML_DOCUMENT *Document; - XML_NODE *RootDict; - UINT32 DictSize; - UINT32 Index; - CONST CHAR8 *CurrentKey; - XML_NODE *CurrentValue; - CONST CHAR8 *Version; - CHAR16 *RecoveryName; - UINTN RecoveryNameSize; - - Document = XmlDocumentParse (SystemVersionData, SystemVersionDataSize, FALSE); - - if (Document == NULL) { - return NULL; - } - - RootDict = PlistNodeCast (PlistDocumentRoot (Document), PLIST_NODE_TYPE_DICT); - - if (RootDict == NULL) { - XmlDocumentFree (Document); - return NULL; - } - - RecoveryName = NULL; - - DictSize = PlistDictChildren (RootDict); - for (Index = 0; Index < DictSize; Index++) { - CurrentKey = PlistKeyValue (PlistDictChild (RootDict, Index, &CurrentValue)); - - if (CurrentKey == NULL || AsciiStrCmp (CurrentKey, "ProductUserVisibleVersion") != 0) { - continue; - } - - if (PlistNodeCast (CurrentValue, PLIST_NODE_TYPE_STRING) != NULL) { - Version = XmlNodeContent (CurrentValue); - if (Version != NULL) { - RecoveryNameSize = L_STR_SIZE(L"Recovery ") + AsciiStrLen (Version) * sizeof (CHAR16); - RecoveryName = AllocatePool (RecoveryNameSize); - if (RecoveryName != NULL) { - UnicodeSPrint (RecoveryName, RecoveryNameSize, L"Recovery %a", Version); - UnicodeFilterString (RecoveryName, TRUE); - } - } - } - - break; - } - - XmlDocumentFree (Document); - return RecoveryName; -} - -CHAR16 * -InternalGetAppleRecoveryName ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *BootDirectoryName - ) -{ - CHAR16 *SystemVersionPath; - UINTN SystemVersionPathSize; - CHAR8 *SystemVersionData; - CHAR16 *UnicodeDiskLabel; - UINT32 SystemVersionDataSize; - - SystemVersionPathSize = StrSize (BootDirectoryName) + L_STR_SIZE_NT (L"SystemVersion.plist"); - SystemVersionPath = AllocatePool (SystemVersionPathSize); - - if (SystemVersionPath == NULL) { - return NULL; - } - - UnicodeSPrint (SystemVersionPath, SystemVersionPathSize, L"%sSystemVersion.plist", BootDirectoryName); - DEBUG ((DEBUG_INFO, "OCB: Trying to get recovery from %s\n", SystemVersionPath)); - SystemVersionData = (CHAR8 *) ReadFile (FileSystem, SystemVersionPath, &SystemVersionDataSize, BASE_1MB); - FreePool (SystemVersionPath); - - if (SystemVersionData != NULL) { - UnicodeDiskLabel = GetAppleRecoveryNameFromPlist (SystemVersionData, SystemVersionDataSize); - FreePool (SystemVersionData); - } else { - UnicodeDiskLabel = NULL; - } - - return UnicodeDiskLabel; -} - -EFI_STATUS -InternalGetRecoveryOsBooter ( - IN EFI_HANDLE Device, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, - IN BOOLEAN Basic - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *Root; - EFI_FILE_PROTOCOL *Recovery; - UINTN FilePathSize; - EFI_DEVICE_PATH_PROTOCOL *TmpPath; - UINTN TmpPathSize; - CHAR16 *DevicePathText; - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = FileSystem->OpenVolume (FileSystem, &Root); - if (EFI_ERROR(Status)) { - return Status; - } - - FilePathSize = 0; - - if (!Basic) { - *FilePath = (EFI_DEVICE_PATH_PROTOCOL *) GetFileInfo ( - Root, - &gAppleBlessedOsxFolderInfoGuid, - sizeof (EFI_DEVICE_PATH_PROTOCOL), - &FilePathSize - ); - } else { - // - // Requested basic recovery support, i.e. only com.apple.recovery.boot folder check. - // This is useful for locating empty USB sticks with just a dmg in them. - // - *FilePath = NULL; - } - - if (*FilePath != NULL) { - if (IsDevicePathValid (*FilePath, FilePathSize)) { - // - // We skip alternate entry when current one is the same. - // This is to prevent recovery and volume duplicates on HFS+ systems. - // - - TmpPath = (EFI_DEVICE_PATH_PROTOCOL *) GetFileInfo ( - Root, - &gAppleBlessedSystemFolderInfoGuid, - sizeof (EFI_DEVICE_PATH_PROTOCOL), - &TmpPathSize - ); - - if (TmpPath != NULL) { - if (IsDevicePathValid (TmpPath, TmpPathSize) - && IsDevicePathEqual (TmpPath, *FilePath)) { - DEBUG ((DEBUG_INFO, "Skipping equal alternate device path %p\n", Device)); - Status = EFI_ALREADY_STARTED; - FreePool (*FilePath); - *FilePath = NULL; - } - FreePool (TmpPath); - } - - if (!EFI_ERROR(Status)) { - // - // This entry should point to a folder with recovery. - // Apple never adds trailing slashes to blessed folder paths. - // However, we do rely on trailing slashes in folder paths and add them here. - // - TmpPath = TrailedBooterDevicePath (*FilePath); - if (TmpPath != NULL) { - FreePool (*FilePath); - *FilePath = TmpPath; - } - } - } else { - FreePool (*FilePath); - *FilePath = NULL; - Status = EFI_NOT_FOUND; - } - } else { - // - // Ok, this one can still be FileVault 2 HFS+ recovery or just a hardcoded basic recovery. - // Apple does add its path to so called "Alternate OS blessed file/folder", but this - // path is not accessible from HFSPlus.efi driver. Just why??? - // Their SlingShot.efi app just bruteforces com.apple.recovery.boot directory existence, - // and we have to copy. - // - Status = SafeFileOpen (Root, &Recovery, L"\\com.apple.recovery.boot", EFI_FILE_MODE_READ, 0); - if (!EFI_ERROR(Status)) { - // - // Do not do any extra checks for simplicity, as they will be done later either way. - // - Root->Close (Recovery); - Status = EFI_NOT_FOUND; - TmpPath = DevicePathFromHandle (Device); - - if (TmpPath != NULL) { - *FilePath = AppendFileNameDevicePath (TmpPath, L"\\com.apple.recovery.boot\\"); - if (*FilePath != NULL) { - DEBUG_CODE_BEGIN (); - DevicePathText = ConvertDevicePathToText (*FilePath, FALSE, FALSE); - if (DevicePathText != NULL) { - DEBUG ((DEBUG_INFO, "OCB: Got recovery dp %s\n", DevicePathText)); - FreePool (DevicePathText); - } - DEBUG_CODE_END (); - Status = EFI_SUCCESS; - } - } - } else { - Status = EFI_NOT_FOUND; - } - } - - Root->Close (Root); - - return Status; -} - -EFI_STATUS -OcGetBootEntryLabelImage ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN UINT8 Scale, - OUT VOID **ImageData, - OUT UINT32 *DataLength - ) -{ - EFI_STATUS Status; - CHAR16 *BootDirectoryName; - EFI_HANDLE Device; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - - *ImageData = NULL; - *DataLength = 0; - - if (BootEntry->Type == OC_BOOT_EXTERNAL_TOOL || BootEntry->Type == OC_BOOT_RESET_NVRAM) { - ASSERT (Context->CustomDescribe != NULL); - - Status = Context->CustomDescribe ( - Context->CustomEntryContext, - BootEntry, - Scale, - NULL, - NULL, - ImageData, - DataLength - ); - - DEBUG ((DEBUG_INFO, "OCB: Get custom label %s - %r\n", BootEntry->Name, Status)); - return Status; - } - - ASSERT (BootEntry->DevicePath != NULL); - - Status = OcBootPolicyDevicePathToDirPath ( - BootEntry->DevicePath, - &BootDirectoryName, - &Device - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - FreePool (BootDirectoryName); - return Status; - } - - Status = InternalGetAppleImage ( - FileSystem, - BootDirectoryName, - Scale == 2 ? L".disk_label_2x" : L".disk_label", - ImageData, - DataLength - ); - - DEBUG ((DEBUG_INFO, "OCB: Get normal label %s - %r\n", BootEntry->Name, Status)); - FreePool (BootDirectoryName); - - return Status; -} - -EFI_STATUS -OcGetBootEntryIcon ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - OUT VOID **ImageData, - OUT UINT32 *DataLength - ) -{ - EFI_STATUS Status; - CHAR16 *BootDirectoryName; - EFI_HANDLE Device; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - - *ImageData = NULL; - *DataLength = 0; - - if (BootEntry->Type == OC_BOOT_EXTERNAL_TOOL || BootEntry->Type == OC_BOOT_RESET_NVRAM) { - ASSERT (Context->CustomDescribe != NULL); - - Status = Context->CustomDescribe ( - Context->CustomEntryContext, - BootEntry, - 0, - ImageData, - DataLength, - NULL, - NULL - ); - - DEBUG ((DEBUG_INFO, "Get custom icon %s - %r\n", BootEntry->Name, Status)); - return Status; - } - - ASSERT (BootEntry->DevicePath != NULL); - - Status = OcBootPolicyDevicePathToDirPath ( - BootEntry->DevicePath, - &BootDirectoryName, - &Device - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - FreePool (BootDirectoryName); - return Status; - } - - Status = InternalGetAppleImage ( - FileSystem, - L"", - L".VolumeIcon.icns", - ImageData, - DataLength - ); - - DEBUG ((DEBUG_INFO, "OCB: Get normal icon %s - %r\n", BootEntry->Name, Status)); - - FreePool (BootDirectoryName); - - return Status; -} - -EFI_STATUS -InternalDescribeBootEntry ( - IN OUT OC_BOOT_ENTRY *BootEntry - ) -{ - EFI_STATUS Status; - CHAR16 *BootDirectoryName; - CHAR16 *RecoveryBootName; - EFI_HANDLE Device; - UINT32 BcdSize; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - - // - // Custom entries need no special description. - // - if (BootEntry->Type == OC_BOOT_EXTERNAL_OS || BootEntry->Type == OC_BOOT_EXTERNAL_TOOL) { - return EFI_SUCCESS; - } - - Status = OcBootPolicyDevicePathToDirPath ( - BootEntry->DevicePath, - &BootDirectoryName, - &Device - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - FreePool (BootDirectoryName); - return Status; - } - - // - // Try to use APFS-style label or legacy HFS one. - // - BootEntry->Name = InternalGetAppleDiskLabel (FileSystem, BootDirectoryName, L".contentDetails"); - if (BootEntry->Name == NULL) { - BootEntry->Name = InternalGetAppleDiskLabel (FileSystem, BootDirectoryName, L".disk_label.contentDetails"); - } - - // - // With FV2 encryption on HFS+ the actual boot happens from "Recovery HD/S/L/CoreServices". - // For some reason "Recovery HD/S/L/CoreServices/.disk_label" may not get updated immediately, - // and will contain "Recovery HD" despite actually pointing to "Macintosh HD". - // This also spontaneously happens with renamed APFS volumes. The workaround is to manually - // edit the file or sometimes choose the boot volume once more in preferences. - // - // TODO: Bugreport this to Apple, as this is clearly their bug, which should be reproducible - // on original hardware. - // - // There exists .root_uuid, which contains real partition UUID in ASCII, however, Apple - // BootPicker only uses it for entry deduplication, and we cannot figure out the name - // on an encrypted volume anyway. - // - - // - // Windows boot entry may have a custom name, so ensure OC_BOOT_WINDOWS is set correctly. - // - if (BootEntry->Type == OC_BOOT_UNKNOWN && BootEntry->IsGeneric) { - DEBUG ((DEBUG_INFO, "OCB: Trying to detect Microsoft BCD\n")); - Status = ReadFileSize (FileSystem, L"\\EFI\\Microsoft\\Boot\\BCD", &BcdSize); - if (!EFI_ERROR(Status)) { - BootEntry->Type = OC_BOOT_WINDOWS; - } - } - - if (BootEntry->Type == OC_BOOT_WINDOWS && BootEntry->Name == NULL) { - BootEntry->Name = AllocateCopyPool (sizeof (L"Windows"), L"Windows"); - } - - if (BootEntry->Name == NULL) { - BootEntry->Name = GetVolumeLabel (FileSystem); - if (BootEntry->Name != NULL - && (!StrCmp (BootEntry->Name, L"Recovery HD") - || !StrCmp (BootEntry->Name, L"Recovery"))) { - if (BootEntry->Type == OC_BOOT_UNKNOWN || BootEntry->Type == OC_BOOT_APPLE_OS) { - BootEntry->Type = OC_BOOT_APPLE_RECOVERY; - } - RecoveryBootName = InternalGetAppleRecoveryName (FileSystem, BootDirectoryName); - if (RecoveryBootName != NULL) { - FreePool (BootEntry->Name); - BootEntry->Name = RecoveryBootName; - } - } - } - - if (BootEntry->Name == NULL) { - FreePool (BootDirectoryName); - return EFI_NOT_FOUND; - } - - BootEntry->PathName = BootDirectoryName; - - return EFI_SUCCESS; -} diff --git a/Library/OcBootManagementLib/BootEntryManagement.c b/Library/OcBootManagementLib/BootEntryManagement.c deleted file mode 100644 index b2fb0e350..000000000 --- a/Library/OcBootManagementLib/BootEntryManagement.c +++ /dev/null @@ -1,1811 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - Expands DevicePath from short-form to full-form. - The only valid expansions are full Device Paths refering to a file or a - volume root. Latter type may be used with custom policies to determine a - bootable file. - - @param[in] BootContext Context of filesystems. - @param[in] DevicePath The Device Path to expand. - @param[in] LazyScan Lazy filesystem scanning. - @param[out] FileSystem Resulting filesystem. - @param[out] IsRoot Whether DevicePath refers to the root of a volume. - - @returns DevicePath expansion or NULL on failure. -*/ -STATIC -EFI_DEVICE_PATH_PROTOCOL * -ExpandShortFormBootPath ( - IN OC_BOOT_CONTEXT *BootContext, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN BOOLEAN LazyScan, - OUT OC_BOOT_FILESYSTEM **FileSystem, - OUT BOOLEAN *IsRoot - ) -{ - EFI_STATUS Status; - - EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_DEVICE_PATH_PROTOCOL *PrevDevicePath; - - EFI_HANDLE FileSystemHandle; - EFI_FILE_PROTOCOL *File; - EFI_FILE_INFO *FileInfo; - BOOLEAN IsRootPath; - BOOLEAN IsDirectory; - - ASSERT (BootContext != NULL); - ASSERT (DevicePath != NULL); - ASSERT (FileSystem != NULL); - ASSERT (IsRoot != NULL); - - // - // Iteratively expand the short-form Device Path to its possible full forms. - // A valid Device Path will either refer to a valid file or to a valid root - // volume. - // - PrevDevicePath = NULL; - IsDirectory = FALSE; - do { - FullDevicePath = OcGetNextLoadOptionDevicePath ( - DevicePath, - PrevDevicePath - ); - - if (PrevDevicePath != NULL) { - FreePool (PrevDevicePath); - } - - // - // When no more full representations can be built, the Device Path is - // not bootable. - // - if (FullDevicePath == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Short-form DP could not be expanded\n")); - return NULL; - } - - PrevDevicePath = FullDevicePath; - - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: Expanded DP", - FullDevicePath - ); - - // - // Retrieve the filesystem handle. - // - RemainingDevicePath = FullDevicePath; - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - &RemainingDevicePath, - &FileSystemHandle - ); - if (EFI_ERROR(Status)) { - continue; - } - - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: Expanded DP remainder", - RemainingDevicePath - ); - - // - // Check whether we are allowed to boot from this filesystem. - // - *FileSystem = InternalFileSystemForHandle (BootContext, FileSystemHandle, LazyScan); - if (*FileSystem == NULL) { - continue; - } - - // - // Check whether the Device Path refers to a valid file handle. - // - Status = OcOpenFileByRemainingDevicePath ( - FileSystemHandle, - RemainingDevicePath, - &File, - EFI_FILE_MODE_READ, - 0 - ); - if (EFI_ERROR(Status)) { - continue; - } - - // - // Retrieve file info to determine potentially bootable state. - // - FileInfo = GetFileInfo ( - File, - &gEfiFileInfoGuid, - sizeof (EFI_FILE_INFO), - NULL - ); - // - // When File Info cannot be retrieved, assume the worst case but don't - // skip the Device Path expansion as it is valid. - // - IsDirectory = TRUE; - if (FileInfo != NULL) { - IsDirectory = (FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0; - FreePool (FileInfo); - } - - File->Close (File); - - // - // Return only Device Paths that either refer to a file or a volume root. - // Root Device Paths may be expanded by custom policies (such as Apple Boot - // Policy) later. - // - IsRootPath = IsDevicePathEnd (RemainingDevicePath); - if (IsRootPath || !IsDirectory) { - ASSERT (FullDevicePath != NULL); - ASSERT (*FileSystem != NULL); - - *IsRoot = IsDirectory; - return FullDevicePath; - } - - // - // Request a new device path expansion. - // - } while (TRUE); -} - -/** - Check whether device path points to OpenCore bootloader. - - @param[in] DevicePath Device path of the entry. - - @retval TRUE Entry represents OpenCore bootloader. - @retval FALSE Entry is not necessarily OpenCore bootloader. -**/ -STATIC -BOOLEAN -IsOpenCoreBootloader ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - STATIC CONST UINT32 OpenCoreMagicOffset = 0x40; - STATIC CONST UINT8 OpenCoreMagic[] = { - 0x0E, 0x1F, 0xBA, 0x10, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x0F, 0x0B, - 0x4F, 0x70, 0x65, 0x6E, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x42, 0x6F, 0x6F, 0x74, 0x6C, 0x6F, 0x61, - 0x64, 0x65, 0x72, 0x20, 0x28, 0x63, 0x29, 0x20, 0x41, 0x63, 0x69, 0x64, 0x61, 0x6E, 0x74, 0x68, - 0x65, 0x72, 0x61, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x0D, 0x0A, 0x24, 0x00 - }; - - EFI_STATUS Status; - - EFI_FILE_PROTOCOL *File; - UINT8 FileReadMagic[sizeof (OpenCoreMagic)]; - - Status = OcOpenFileByDevicePath ( - &DevicePath, - &File, - EFI_FILE_MODE_READ, - 0 - ); - if (EFI_ERROR(Status)) { - return FALSE; - } - - Status = GetFileData ( - File, - OpenCoreMagicOffset, - sizeof (FileReadMagic), - FileReadMagic - ); - if (EFI_ERROR(Status)) { - return FALSE; - } - - return CompareMem (FileReadMagic, OpenCoreMagic, sizeof (OpenCoreMagic)) == 0; -} - -/** - Register bootable entry on the filesystem. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem for creation. - @param[in] BootEntry Entry to register. -**/ -STATIC -VOID -RegisterBootOption ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem, - IN OC_BOOT_ENTRY *BootEntry - ) -{ - CHAR16 *TextDevicePath; - - DEBUG_CODE_BEGIN (); - - if (BootEntry->DevicePath != NULL) { - TextDevicePath = ConvertDevicePathToText (BootEntry->DevicePath, TRUE, FALSE); - } else { - TextDevicePath = NULL; - } - - DEBUG (( - DEBUG_INFO, - "OCB: Registering entry %s (T:%d|F:%d|G:%d|E:%d) - %s\n", - BootEntry->Name, - BootEntry->Type, - BootEntry->IsFolder, - BootEntry->IsGeneric, - BootEntry->IsExternal, - OC_HUMAN_STRING (TextDevicePath) - )); - - if (TextDevicePath != NULL) { - FreePool (TextDevicePath); - } - - DEBUG_CODE_END (); - - // - // Register boot entry. - // Not using RecoveryFs is intended for correct order. - // - InsertTailList (&FileSystem->BootEntries, &BootEntry->Link); - ++BootContext->BootEntryCount; - - // - // For tools and system options we are done. - // - if ((BootEntry->Type & (OC_BOOT_SYSTEM | OC_BOOT_EXTERNAL_TOOL)) != 0) { - return; - } - - // - // If no options were previously found this is the default one. - // - if (BootContext->DefaultEntry == NULL) { - BootContext->DefaultEntry = BootEntry; - } - - // - // Set override picker commands. - // - if (BootContext->PickerContext->PickerCommand == OcPickerBootApple) { - if (BootContext->DefaultEntry->Type != OC_BOOT_APPLE_OS - && BootEntry->Type == OC_BOOT_APPLE_OS) { - BootContext->DefaultEntry = BootEntry; - } - } else if (BootContext->PickerContext->PickerCommand == OcPickerBootAppleRecovery) { - if (BootContext->DefaultEntry->Type != OC_BOOT_APPLE_RECOVERY - && BootEntry->Type == OC_BOOT_APPLE_RECOVERY) { - BootContext->DefaultEntry = BootEntry; - } - } -} - -/** - Create single bootable entry from device path. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem for creation. - @param[in] DevicePath Device path of the entry. - @param[in] RecoveryPart Device path is on recovery partition. - @param[in] Deduplicate Ensure that duplicated entries are not added. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -AddBootEntryOnFileSystem ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN BOOLEAN RecoveryPart, - IN BOOLEAN Deduplicate - ) -{ - EFI_STATUS Status; - OC_BOOT_ENTRY *BootEntry; - OC_BOOT_ENTRY_TYPE EntryType; - LIST_ENTRY *Link; - OC_BOOT_ENTRY *ExistingEntry; - CHAR16 *TextDevicePath; - BOOLEAN IsFolder; - BOOLEAN IsGeneric; - - EntryType = OcGetBootDevicePathType (DevicePath, &IsFolder, &IsGeneric); - - DEBUG_CODE_BEGIN (); - - TextDevicePath = ConvertDevicePathToText (DevicePath, TRUE, FALSE); - - DEBUG (( - DEBUG_INFO, - "OCB: Adding entry type (T:%u|F:%d|G:%d) - %s\n", - EntryType, - IsFolder, - IsGeneric, - OC_HUMAN_STRING (TextDevicePath) - )); - - if (TextDevicePath != NULL) { - FreePool (TextDevicePath); - } - - DEBUG_CODE_END (); - - // - // Mark self recovery presence. - // - if (!RecoveryPart && EntryType == OC_BOOT_APPLE_RECOVERY) { - FileSystem->HasSelfRecovery = TRUE; - } - - // - // Do not add recoveries when not requested (e.g. can be HFS+ recovery). - // - if (BootContext->PickerContext->HideAuxiliary && EntryType == OC_BOOT_APPLE_RECOVERY) { - DEBUG ((DEBUG_INFO, "OCB: Discarding recovery entry due to auxiliary\n")); - return EFI_UNSUPPORTED; - } - - // - // Do not add Time Machine when not requested. - // - if (BootContext->PickerContext->HideAuxiliary && EntryType == OC_BOOT_APPLE_TIME_MACHINE) { - DEBUG ((DEBUG_INFO, "OCB: Discarding time machine entry due to auxiliary\n")); - return EFI_UNSUPPORTED; - } - - // - // Skip OpenCore bootloaders on own entry. - // We do not waste time doing this for other entries. - // - if (RecoveryPart ? FileSystem->RecoveryFs->LoaderFs : FileSystem->LoaderFs - && IsOpenCoreBootloader (DevicePath)) { - DEBUG ((DEBUG_INFO, "OCB: Discarding discovered OpenCore bootloader\n")); - return EFI_UNSUPPORTED; - } - - // - // Skip duplicated entries, which may happen in BootOrder. - // For example, macOS during hibernation may leave Boot0082 in BootNext and Boot0080 in BootOrder, - // and they will have exactly the same boot entry. - // - if (Deduplicate) { - for ( - Link = GetFirstNode (&FileSystem->BootEntries); - !IsNull (&FileSystem->BootEntries, Link); - Link = GetNextNode (&FileSystem->BootEntries, Link)) { - ExistingEntry = BASE_CR (Link, OC_BOOT_ENTRY, Link); - // - // All non-custom entries have DPs. - // - ASSERT (ExistingEntry->DevicePath != NULL); - if (IsDevicePathEqual (ExistingEntry->DevicePath, DevicePath)) { - DEBUG ((DEBUG_INFO, "OCB: Discarding already present DP\n")); - // - // We may have more than one macOS installation in APFS container. - // Boot policy returns them in a defined (constant) order, and we want - // to preserve this order regardless of the BootOrder. - // - // When an operating system is present in BootOrder it will be put to - // the front of FileSystem boot entries. As a result instead of: - // [OS1], [REC1], [OS2], [REC2] we may get [OS2], [OS1], [REC1], [REC2]. - // The latter happens because after [REC1] discovered [OS1] is skipped - // due to being already present. The code below moves [OS2] to the end - // of list at [REC1] stage to fix the order. - // - // This change assumes that only one operating system from the container - // can be present as a boot option. For now this appears to be true. - // - RemoveEntryList (Link); - InsertTailList (&FileSystem->BootEntries, Link); - return EFI_ALREADY_STARTED; - } - } - } - - // - // Allocate, initialise, and describe boot entry. - // - BootEntry = AllocateZeroPool (sizeof (*BootEntry)); - if (BootEntry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BootEntry->DevicePath = DevicePath; - BootEntry->Type = EntryType; - BootEntry->IsFolder = IsFolder; - BootEntry->IsGeneric = IsGeneric; - BootEntry->IsExternal = RecoveryPart ? FileSystem->RecoveryFs->External : FileSystem->External; - - Status = InternalDescribeBootEntry (BootEntry); - if (EFI_ERROR(Status)) { - FreePool (BootEntry); - return Status; - } - - RegisterBootOption ( - BootContext, - FileSystem, - BootEntry - ); - - return EFI_SUCCESS; -} - -/** - Create bootable entry from custom entry. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem to add custom entry. - @param[in] CustomEntry Custom entry. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -AddBootEntryFromCustomEntry ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem, - IN OC_PICKER_ENTRY *CustomEntry - ) -{ - OC_BOOT_ENTRY *BootEntry; - CHAR16 *PathName; - FILEPATH_DEVICE_PATH *FilePath; - - if (CustomEntry->Auxiliary && BootContext->PickerContext->HideAuxiliary) { - return EFI_UNSUPPORTED; - } - - // - // Allocate, initialise, and describe boot entry. - // - BootEntry = AllocateZeroPool (sizeof (*BootEntry)); - if (BootEntry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BootEntry->Name = AsciiStrCopyToUnicode (CustomEntry->Name, 0); - if (BootEntry->Name == NULL) { - FreePool (BootEntry); - return EFI_OUT_OF_RESOURCES; - } - - PathName = AsciiStrCopyToUnicode (CustomEntry->Path, 0); - if (PathName == NULL) { - FreePool (BootEntry->Name); - FreePool (BootEntry); - return EFI_OUT_OF_RESOURCES; - } - - DEBUG (( - DEBUG_INFO, - "OCB: Adding custom entry %s (%a) -> %a\n", - BootEntry->Name, - CustomEntry->Tool ? "tool" : "os", - CustomEntry->Path - )); - - if (CustomEntry->Tool) { - BootEntry->Type = OC_BOOT_EXTERNAL_TOOL; - UnicodeUefiSlashes (PathName); - BootEntry->PathName = PathName; - } else { - BootEntry->Type = OC_BOOT_EXTERNAL_OS; - - BootEntry->DevicePath = ConvertTextToDevicePath (PathName); - FreePool (PathName); - if (BootEntry->DevicePath == NULL) { - FreePool (BootEntry->Name); - FreePool (BootEntry); - return EFI_OUT_OF_RESOURCES; - } - - FilePath = (FILEPATH_DEVICE_PATH *) ( - FindDevicePathNodeWithType ( - BootEntry->DevicePath, - MEDIA_DEVICE_PATH, - MEDIA_FILEPATH_DP - ) - ); - if (FilePath == NULL) { - FreePool (BootEntry->Name); - FreePool (BootEntry->DevicePath); - FreePool (BootEntry); - return EFI_UNSUPPORTED; - } - - BootEntry->PathName = AllocateCopyPool ( - OcFileDevicePathNameSize (FilePath), - FilePath->PathName - ); - if (BootEntry->PathName == NULL) { - FreePool (BootEntry->Name); - FreePool (BootEntry->DevicePath); - FreePool (BootEntry); - return EFI_OUT_OF_RESOURCES; - } - } - - BootEntry->LoadOptionsSize = (UINT32) AsciiStrLen (CustomEntry->Arguments); - if (BootEntry->LoadOptionsSize > 0) { - BootEntry->LoadOptions = AllocateCopyPool ( - BootEntry->LoadOptionsSize + 1, - CustomEntry->Arguments - ); - if (BootEntry->LoadOptions == NULL) { - BootEntry->LoadOptionsSize = 0; - } - } - - RegisterBootOption ( - BootContext, - FileSystem, - BootEntry - ); - - return EFI_SUCCESS; -} - -/** - Create bootable entry from system entry. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem to add custom entry. - @param[in] Name System entry name. - @param[in] Action System entry action. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -AddBootEntryFromSystemEntry ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem, - IN CONST CHAR16 *Name, - IN OC_BOOT_SYSTEM_ACTION Action - ) -{ - OC_BOOT_ENTRY *BootEntry; - - if (BootContext->PickerContext->HideAuxiliary) { - return EFI_UNSUPPORTED; - } - - DEBUG ((DEBUG_INFO, "OCB: Adding system entry %s\n", Name)); - - // - // Allocate, initialise, and describe boot entry. - // - BootEntry = AllocateZeroPool (sizeof (*BootEntry)); - if (BootEntry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BootEntry->Name = AllocateCopyPool (StrSize (Name), Name); - if (BootEntry->Name == NULL) { - FreePool (BootEntry); - return EFI_OUT_OF_RESOURCES; - } - - BootEntry->Type = OC_BOOT_RESET_NVRAM; - BootEntry->SystemAction = Action; - - RegisterBootOption ( - BootContext, - FileSystem, - BootEntry - ); - - return EFI_SUCCESS; -} - -/** - Create bootable entries from bless policy. - This function may create more than one entry, and for APFS - it will likely produce a sequence of 'OS, RECOVERY' entry pairs. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem to scan for bless. - @param[in] PredefinedPaths The predefined boot file locations to scan. - @param[in] NumPredefinedPaths The number of elements in PredefinedPaths. - @param[in] LazyScan Lazy filesystem scanning. - @param[in] Deduplicate Ensure that duplicated entries are not added. - - @retval EFI_STATUS for last created option. -**/ -STATIC -EFI_STATUS -AddBootEntryFromBless ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem, - IN CONST CHAR16 **PredefinedPaths, - IN UINTN NumPredefinedPaths, - IN BOOLEAN LazyScan, - IN BOOLEAN Deduplicate - ) -{ - EFI_STATUS Status; - EFI_STATUS PrimaryStatus; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - UINTN NewDevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *HdDevicePath; - UINTN HdPrefixSize; - INTN CmpResult; - EFI_FILE_PROTOCOL *Root; - CHAR16 *RecoveryPath; - EFI_FILE_PROTOCOL *RecoveryRoot; - EFI_HANDLE RecoveryDeviceHandle; - - // - // We need to ensure that blessed device paths are on the same filesystem. - // Read the prefix path. - // - Status = gBS->HandleProtocol ( - FileSystem->Handle, - &gEfiDevicePathProtocolGuid, - (VOID **) &HdDevicePath - ); - if (EFI_ERROR(Status)) { - return EFI_UNSUPPORTED; - } - - DebugPrintDevicePath (DEBUG_INFO, "OCB: Adding bless entry on disk", HdDevicePath); - - HdPrefixSize = GetDevicePathSize (HdDevicePath) - END_DEVICE_PATH_LENGTH; - - // - // Custom bless paths have the priority, try to look them up first. - // - if (BootContext->PickerContext->NumCustomBootPaths > 0) { - Status = gBS->HandleProtocol ( - FileSystem->Handle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &SimpleFs - ); - - if (!EFI_ERROR(Status)) { - Status = SimpleFs->OpenVolume (SimpleFs, &Root); - if (!EFI_ERROR(Status)) { - Status = OcGetBooterFromPredefinedPathList ( - FileSystem->Handle, - Root, - (CONST CHAR16 **) BootContext->PickerContext->CustomBootPaths, - BootContext->PickerContext->NumCustomBootPaths, - &DevicePath, - NULL - ); - - Root->Close (Root); - } - } - } else { - Status = EFI_NOT_FOUND; - } - - // - // On failure obtain normal bless paths. - // - if (EFI_ERROR(Status)) { - Status = OcBootPolicyGetBootFileEx ( - FileSystem->Handle, - PredefinedPaths, - NumPredefinedPaths, - &DevicePath - ); - } - - // - // If both custom and normal found nothing, then nothing is blessed. - // - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Since blessed paths can be multiple (e.g. when more than one macOS is present in the container). - // - Status = EFI_NOT_FOUND; - DevicePathWalker = DevicePath; - while (TRUE) { - NewDevicePath = GetNextDevicePathInstance (&DevicePathWalker, &NewDevicePathSize); - if (NewDevicePath == NULL) { - break; - } - - // - // Blessed path is obviously too short. - // - if (NewDevicePathSize - END_DEVICE_PATH_LENGTH < HdPrefixSize) { - FreePool (NewDevicePath); - continue; - } - - // - // Blessed path does not prefix filesystem path. - // - CmpResult = CompareMem ( - NewDevicePath, - HdDevicePath, - HdPrefixSize - ); - if (CmpResult != 0) { - DEBUG (( - DEBUG_INFO, - "OCB: Skipping handle %p instance due to self trust violation\n", - FileSystem->Handle - )); - - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: Disk DP", - HdDevicePath - ); - DebugPrintDevicePath ( - DEBUG_INFO, - "OCB: Instance DP", - NewDevicePath - ); - - FreePool (NewDevicePath); - continue; - } - - // - // Add blessed device path. - // - PrimaryStatus = AddBootEntryOnFileSystem ( - BootContext, - FileSystem, - NewDevicePath, - FALSE, - Deduplicate - ); - // - // Cannot free the failed device path now as it may have recovery. - // - - // - // If the partition contains recovery on itself or recoveries are not requested, - // proceed to next entry. - // - // First part means that APFS recovery is irrelevant, these recoveries are actually - // on a different partition, but can only be pointed from Preboot. - // This way we will show any 'com.apple.recovery.boot' recovery physically present - // on the partition no more than once. - // - if (FileSystem->HasSelfRecovery || BootContext->PickerContext->HideAuxiliary) { - if (EFI_ERROR (PrimaryStatus)) { - FreePool (NewDevicePath); - } - Status = PrimaryStatus; - continue; - } - - // - // Now add APFS recovery (from Recovery partition) right afterwards if present. - // - Status = OcBootPolicyGetApfsRecoveryFilePath ( - NewDevicePath, - L"\\", - PredefinedPaths, - NumPredefinedPaths, - &RecoveryPath, - &RecoveryRoot, - &RecoveryDeviceHandle - ); - - // - // Can free the failed primary device path now. - // - if (EFI_ERROR (PrimaryStatus)) { - FreePool (NewDevicePath); - } - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCB: APFS recovery is not present - %r\n", Status)); - continue; - } - - RecoveryRoot->Close (RecoveryRoot); - - // - // Obtain recovery file system and ensure scan policy if it was not done before. - // - if (FileSystem->RecoveryFs == NULL) { - FileSystem->RecoveryFs = InternalFileSystemForHandle (BootContext, RecoveryDeviceHandle, LazyScan); - } - - // - // If new recovery is not on the same volume or not allowed, then something went wrong, skip it. - // This is technically also a performance optimisation allowing us not to lookup recovery fs every time. - // - if (FileSystem->RecoveryFs == NULL || FileSystem->RecoveryFs->Handle != RecoveryDeviceHandle) { - FreePool (RecoveryPath); - continue; - } - - NewDevicePath = FileDevicePath (RecoveryDeviceHandle, RecoveryPath); - FreePool (RecoveryPath); - if (NewDevicePath == NULL) { - continue; - } - - // - // Add blessed device path. - // - Status = AddBootEntryOnFileSystem ( - BootContext, - FileSystem, - NewDevicePath, - TRUE, - Deduplicate - ); - if (EFI_ERROR(Status)) { - FreePool (NewDevicePath); - } - } - - FreePool (DevicePath); - - return Status; -} - -/** - Create bootable entries from recovery files (com.apple.boot.recovery) on the volume. - - @param[in,out] BootContext Context of filesystems. - @param[in,out] FileSystem Filesystem to scan for recovery. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -AddBootEntryFromSelfRecovery ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OUT OC_BOOT_FILESYSTEM *FileSystem - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - // - // If there is already one recovery (it may not be registered due to HideAuxiliary) - // or if there is HideAuxiliary, do not add recoveries at all. - // - if (FileSystem->HasSelfRecovery || BootContext->PickerContext->HideAuxiliary) { - return EFI_UNSUPPORTED; - } - - Status = InternalGetRecoveryOsBooter ( - FileSystem->Handle, - &DevicePath, - FALSE - ); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Returned device path is always on the same partition, thus no scan check. - // - Status = AddBootEntryOnFileSystem ( - BootContext, - FileSystem, - DevicePath, - FALSE, - FALSE - ); - - if (EFI_ERROR(Status)) { - FreePool (DevicePath); - } - - return Status; -} - -/** - Create bootable entries from boot options. - - @param[in,out] BootContext Context of filesystems. - @param[in] BootOption Boot option number. - @param[in] LazyScan Lazy filesystem scanning. - - @retval EFI_SUCCESS if at least one option was added. -**/ -STATIC -EFI_STATUS -AddBootEntryFromBootOption ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN UINT16 BootOption, - IN BOOLEAN LazyScan - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_HANDLE FileSystemHandle; - OC_BOOT_FILESYSTEM *FileSystem; - UINTN DevicePathSize; - INTN NumPatchedNodes; - BOOLEAN IsAppleLegacy; - BOOLEAN IsRoot; - - DEBUG ((DEBUG_INFO, "OCB: Building entry from Boot%04x\n", BootOption)); - - // - // Obtain original device path. - // Discard load options for security reasons. - // Also discard boot name to avoid confusion. - // - DevicePath = InternalGetBootOptionData ( - BootOption, - BootContext->BootVariableGuid, - NULL, - NULL, - NULL - ); - if (DevicePath == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get BootCamp device path stored in special variable. - // BootCamp device path will point to disk instead of partition. - // - IsAppleLegacy = InternalIsAppleLegacyLoadApp (DevicePath); - if (IsAppleLegacy) { - FreePool (DevicePath); - Status = GetVariable2 ( - APPLE_BOOT_CAMP_HD_VARIABLE_NAME, - &gEfiAppleBootGuid, - (VOID **) &DevicePath, - &DevicePathSize - ); - - if (EFI_ERROR(Status) || !IsDevicePathValid (DevicePath, DevicePathSize)) { - DEBUG ((DEBUG_INFO, "OCB: Legacy DP invalid - %r\n", Status)); - if (!EFI_ERROR(Status)) { - FreePool (DevicePath); - } - return EFI_NOT_FOUND; - } else { - DebugPrintDevicePath (DEBUG_INFO, "OCB: Solved legacy DP", DevicePath); - } - } - - FileSystem = NULL; - IsRoot = FALSE; - - // - // Fixup device path if necessary. - // - RemainingDevicePath = DevicePath; - NumPatchedNodes = OcFixAppleBootDevicePath (&RemainingDevicePath); - if (NumPatchedNodes > 0) { - DebugPrintDevicePath (DEBUG_INFO, "OCB: Fixed DP", DevicePath); - } - - // - // Expand BootCamp device path to EFI partition device path. - // - if (IsAppleLegacy) { - // - // BootCampHD always refers to a full Device Path. Failure to patch - // indicates an invalid Device Path. - // - if (NumPatchedNodes == -1) { - DEBUG ((DEBUG_INFO, "OCB: Ignoring broken legacy DP\n")); - FreePool (DevicePath); - return EFI_NOT_FOUND; - } - - RemainingDevicePath = DevicePath; - DevicePath = OcDiskFindSystemPartitionPath ( - DevicePath, - &DevicePathSize, - &FileSystemHandle - ); - - FreePool (RemainingDevicePath); - - // - // This is obviously always a Root Device Path. - // - IsRoot = TRUE; - - // - // Ensure that we are allowed to boot from this filesystem. - // - if (DevicePath != NULL) { - FileSystem = InternalFileSystemForHandle (BootContext, FileSystemHandle, LazyScan); - if (FileSystem == NULL) { - DevicePath = NULL; - } - } - - // - // The Device Path returned by OcDiskFindSystemPartitionPath() is a pointer - // to an installed protocol. Duplicate it so we own the memory. - // - if (DevicePath != NULL) { - DevicePath = AllocateCopyPool (DevicePathSize, DevicePath); - } - - if (DevicePath == NULL) { - return EFI_NOT_FOUND; - } - - // - // The Device Path must be entirely locatable (and hence full-form) as - // OcDiskFindSystemPartitionPath() guarantees to only return valid paths. - // - ASSERT (DevicePathSize > END_DEVICE_PATH_LENGTH); - DevicePathSize -= END_DEVICE_PATH_LENGTH; - RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) DevicePath + DevicePathSize); - } else if (DevicePath == RemainingDevicePath) { - // - // OcFixAppleBootDevicePath() did not advance the Device Path node, hence - // it cannot be located at all and may be a short-form Device Path. - // DevicePath has not been changed no matter success or failure. - // - DEBUG ((DEBUG_INFO, "OCB: Assuming DP is short-form (prefix)\n")); - - // - // Expand and on failure fix the Device Path till both yields no new result. - // - RemainingDevicePath = DevicePath; - do { - // - // Expand the short-form Device Path. - // - DevicePath = ExpandShortFormBootPath ( - BootContext, - RemainingDevicePath, - LazyScan, - &FileSystem, - &IsRoot - ); - if (DevicePath != NULL) { - break; - } - - // - // If short-form expansion failed, try to fix the short-form and re-try. - // - NumPatchedNodes = OcFixAppleBootDevicePathNode (RemainingDevicePath, NULL); - } while (NumPatchedNodes > 0); - - FreePool (RemainingDevicePath); - - if (DevicePath == NULL) { - return EFI_NOT_FOUND; - } - } else if (NumPatchedNodes == -1) { - // - // OcFixAppleBootDevicePath() advanced the Device Path node and yet failed - // to locate the path, it is invalid. - // - DEBUG ((DEBUG_INFO, "OCB: Ignoring broken normal DP\n")); - FreePool (DevicePath); - return EFI_NOT_FOUND; - } else { - // - // OcFixAppleBootDevicePath() advanced the Device Path node and succeeded - // to locate the path, but it may still be a shot-form Device Path (lacking - // a suffix rather than prefix). - // - DEBUG ((DEBUG_INFO, "OCB: Assuming DP is full-form or lacks suffix\n")); - - RemainingDevicePath = DevicePath; - DevicePath = ExpandShortFormBootPath ( - BootContext, - RemainingDevicePath, - LazyScan, - &FileSystem, - &IsRoot - ); - - FreePool (RemainingDevicePath); - - if (DevicePath == NULL) { - return EFI_NOT_FOUND; - } - } - - // - // If we reached here we have a filesystem and device path. - // - ASSERT (FileSystem != NULL); - ASSERT (DevicePath != NULL); - - // - // We have a complete device path, just add this entry. - // - if (!IsRoot) { - Status = AddBootEntryOnFileSystem ( - BootContext, - FileSystem, - DevicePath, - FALSE, - TRUE - ); - } else { - Status = EFI_UNSUPPORTED; - } - - if (EFI_ERROR(Status)) { - FreePool (DevicePath); - } - - // - // We may have a Boot#### entry pointing to macOS with full DP (up to boot.efi), - // so IsRoot will be true. However, if this is APFS, we may still have: - // - Recovery for this macOS. - // - Another macOS installation. - // We can only detect them with bless, so we invoke bless in deduplication mode. - // We also detect only the Core Apple Boot Policy predefined booter paths to - // avoid detection of e.g. generic booters (such as BOOTx64) to avoid - // duplicates. - // - // The amount of paths depends on the kind of the entry. - // - If this is a root entry (i.e. it points to the partition) - // we invoke full bless, as it may be Windows entry created by legacy NVRAM script. - // - If this is a full entry (i.e. it points to the bootloader) - // we invoke partial bless, which ignores BOOTx64.efi. - // Ignoring BOOTx64.efi is important as we may already have bootmgfw.efi as our entry, - // and we do not want to see Windows added twice. - // - Status = AddBootEntryFromBless ( - BootContext, - FileSystem, - gAppleBootPolicyPredefinedPaths, - IsRoot ? gAppleBootPolicyNumPredefinedPaths : gAppleBootPolicyCoreNumPredefinedPaths, - LazyScan, - TRUE - ); - - return Status; -} - -/** - Release boot entry contents allocated from pool. - - @param[in,out] BootEntry Located boot entry. -**/ -STATIC -VOID -FreeBootEntry ( - IN OC_BOOT_ENTRY *BootEntry - ) -{ - if (BootEntry->DevicePath != NULL) { - FreePool (BootEntry->DevicePath); - BootEntry->DevicePath = NULL; - } - - if (BootEntry->Name != NULL) { - FreePool (BootEntry->Name); - BootEntry->Name = NULL; - } - - if (BootEntry->PathName != NULL) { - FreePool (BootEntry->PathName); - BootEntry->PathName = NULL; - } - - if (BootEntry->LoadOptions != NULL) { - FreePool (BootEntry->LoadOptions); - BootEntry->LoadOptions = NULL; - BootEntry->LoadOptionsSize = 0; - } - - FreePool (BootEntry); -} - -/** - Allocate a new filesystem entry in boot entries - in case it can be used according to current ScanPolicy. - - @param[in,out] BootContext Context of filesystems. - @param[in] FileSystemHandle Filesystem handle. - @param[in] FileSystemEntry Resulting filesystem, optional. - - @retval EFI_SUCCESS on success. -**/ -STATIC -EFI_STATUS -AddFileSystemEntry ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN EFI_HANDLE FileSystemHandle, - OUT OC_BOOT_FILESYSTEM **FileSystemEntry OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_STATUS TmpStatus; - BOOLEAN IsExternal; - BOOLEAN LoaderFs; - OC_BOOT_FILESYSTEM *Entry; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - CHAR16 *TextDevicePath; - - Status = InternalCheckScanPolicy ( - FileSystemHandle, - BootContext->PickerContext->ScanPolicy, - &IsExternal - ); - - LoaderFs = BootContext->PickerContext->LoaderHandle == FileSystemHandle; - - DEBUG_CODE_BEGIN (); - - TmpStatus = gBS->HandleProtocol ( - FileSystemHandle, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath - ); - if (!EFI_ERROR (TmpStatus)) { - TextDevicePath = ConvertDevicePathToText (DevicePath, TRUE, FALSE); - } else { - TextDevicePath = NULL; - } - - DEBUG (( - DEBUG_INFO, - "OCB: Adding fs %p (E:%d|L:%d|P:%r) - %s\n", - FileSystemHandle, - IsExternal, - LoaderFs, - Status, - OC_HUMAN_STRING (TextDevicePath) - )); - - if (TextDevicePath != NULL) { - FreePool (TextDevicePath); - } - - DEBUG_CODE_END (); - - if (EFI_ERROR(Status)) { - return Status; - } - - Entry = AllocatePool (sizeof (*Entry)); - if (Entry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Entry->Handle = FileSystemHandle; - InitializeListHead (&Entry->BootEntries); - Entry->RecoveryFs = NULL; - Entry->External = IsExternal; - Entry->LoaderFs = LoaderFs; - Entry->HasSelfRecovery = FALSE; - InsertTailList (&BootContext->FileSystems, &Entry->Link); - ++BootContext->FileSystemCount; - - if (FileSystemEntry != NULL) { - *FileSystemEntry = Entry; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -AddFileSystemEntryForCustom ( - IN OUT OC_BOOT_CONTEXT *BootContext - ) -{ - EFI_STATUS Status; - OC_BOOT_FILESYSTEM *FileSystem; - UINTN Index; - - // - // When there are no custom entries and NVRAM reset is hidden - // we have no work to do. - // - if (BootContext->PickerContext->AllCustomEntryCount == 0 - && (!BootContext->PickerContext->ShowNvramReset - || BootContext->PickerContext->HideAuxiliary)) { - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_INFO, - "OCB: Adding fs %p for %u custom entries%a%a\n", - OC_CUSTOM_FS_HANDLE, - BootContext->PickerContext->AllCustomEntryCount, - BootContext->PickerContext->ShowNvramReset ? " and nvram reset" : "", - BootContext->PickerContext->HideAuxiliary ? " (aux hidden)" : " (aux shown)" - )); - - FileSystem = AllocateZeroPool (sizeof (*FileSystem)); - if (FileSystem == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - FileSystem->Handle = OC_CUSTOM_FS_HANDLE; - InitializeListHead (&FileSystem->BootEntries); - InsertTailList (&BootContext->FileSystems, &FileSystem->Link); - ++BootContext->FileSystemCount; - - Status = EFI_NOT_FOUND; - for (Index = 0; Index < BootContext->PickerContext->AllCustomEntryCount; ++Index) { - Status = AddBootEntryFromCustomEntry ( - BootContext, - FileSystem, - &BootContext->PickerContext->CustomEntries[Index] - ); - } - - if (BootContext->PickerContext->ShowNvramReset) { - Status = AddBootEntryFromSystemEntry ( - BootContext, - FileSystem, - OC_MENU_RESET_NVRAM_ENTRY, - InternalSystemActionResetNvram - ); - } - - return Status; -} - -STATIC -VOID -FreeFileSystemEntry ( - IN OUT OC_BOOT_CONTEXT *BootContext, - IN OC_BOOT_FILESYSTEM *FileSystemEntry - ) -{ - LIST_ENTRY *Link; - OC_BOOT_ENTRY *BootEntry; - - RemoveEntryList (&FileSystemEntry->Link); - --BootContext->FileSystemCount; - - while (!IsListEmpty (&FileSystemEntry->BootEntries)) { - Link = GetFirstNode (&FileSystemEntry->BootEntries); - BootEntry = BASE_CR (Link, OC_BOOT_ENTRY, Link); - RemoveEntryList (Link); - FreeBootEntry (BootEntry); - } - - FreePool (FileSystemEntry); -} - -OC_BOOT_FILESYSTEM * -InternalFileSystemForHandle ( - IN OC_BOOT_CONTEXT *BootContext, - IN EFI_HANDLE FileSystemHandle, - IN BOOLEAN LazyScan - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - OC_BOOT_FILESYSTEM *FileSystem; - - for ( - Link = GetFirstNode (&BootContext->FileSystems); - !IsNull (&BootContext->FileSystems, Link); - Link = GetNextNode (&BootContext->FileSystems, Link)) { - FileSystem = BASE_CR (Link, OC_BOOT_FILESYSTEM, Link); - - if (FileSystem->Handle == FileSystemHandle) { - DEBUG ((DEBUG_INFO, "OCB: Matched fs %p%a\n", FileSystemHandle, LazyScan ? " (lazy)" : "")); - return FileSystem; - } - } - - // - // Lazily check filesystem scan policy and add it in case it is ok. - // - if (!LazyScan) { - DEBUG ((DEBUG_INFO, "OCB: Restricted fs %p access\n", FileSystemHandle)); - return NULL; - } - - Status = AddFileSystemEntry (BootContext, FileSystemHandle, &FileSystem); - if (!EFI_ERROR(Status)) { - return FileSystem; - } - - return NULL; -} - -STATIC -OC_BOOT_CONTEXT * -BuildFileSystemList ( - IN OC_PICKER_CONTEXT *Context, - IN BOOLEAN Empty - ) -{ - OC_BOOT_CONTEXT *BootContext; - EFI_STATUS Status; - UINTN NoHandles; - EFI_HANDLE *Handles; - UINTN Index; - - BootContext = AllocatePool (sizeof (*Context)); - if (BootContext == NULL) { - return NULL; - } - - BootContext->BootEntryCount = 0; - BootContext->FileSystemCount = 0; - InitializeListHead (&BootContext->FileSystems); - if (Context->CustomBootGuid) { - BootContext->BootVariableGuid = &gOcVendorVariableGuid; - } else { - BootContext->BootVariableGuid = &gEfiGlobalVariableGuid; - } - BootContext->DefaultEntry = NULL; - BootContext->PickerContext = Context; - - if (Empty) { - return BootContext; - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NoHandles, - &Handles - ); - if (EFI_ERROR(Status)) { - return BootContext; - } - - for (Index = 0; Index < NoHandles; ++Index) { - AddFileSystemEntry ( - BootContext, - Handles[Index], - NULL - ); - } - - FreePool (Handles); - return BootContext; -} - -VOID -OcFreeBootContext ( - IN OUT OC_BOOT_CONTEXT *Context - ) -{ - LIST_ENTRY *Link; - OC_BOOT_FILESYSTEM *FileSystem; - - while (!IsListEmpty (&Context->FileSystems)) { - Link = GetFirstNode (&Context->FileSystems); - FileSystem = BASE_CR (Link, OC_BOOT_FILESYSTEM, Link); - FreeFileSystemEntry (Context, FileSystem); - } - - FreePool (Context); -} - -OC_BOOT_CONTEXT * -OcScanForBootEntries ( - IN OC_PICKER_CONTEXT *Context - ) -{ - OC_BOOT_CONTEXT *BootContext; - UINTN Index; - LIST_ENTRY *Link; - OC_BOOT_FILESYSTEM *FileSystem; - - // - // Obtain the list of filesystems filtered by scan policy. - // - BootContext = BuildFileSystemList ( - Context, - FALSE - ); - if (BootContext == NULL) { - return NULL; - } - - DEBUG ((DEBUG_INFO, "OCB: Found %u potentially bootable filesystems\n", (UINT32) BootContext->FileSystemCount)); - - // - // Create primary boot options from BootOrder. - // - if (Context->BootOrder == NULL) { - Context->BootOrder = InternalGetBootOrderForBooting ( - BootContext->BootVariableGuid, - &Context->BootOrderCount - ); - } - - if (Context->BootOrder != NULL) { - for (Index = 0; Index < Context->BootOrderCount; ++Index) { - AddBootEntryFromBootOption (BootContext, Context->BootOrder[Index], FALSE); - } - } - - DEBUG ((DEBUG_INFO, "OCB: Processing blessed list\n")); - - // - // Create primary boot options on filesystems without options - // and alternate boot options on all filesystems. - // - for ( - Link = GetFirstNode (&BootContext->FileSystems); - !IsNull (&BootContext->FileSystems, Link); - Link = GetNextNode (&BootContext->FileSystems, Link)) { - FileSystem = BASE_CR (Link, OC_BOOT_FILESYSTEM, Link); - - // - // No entries, so we process this directory with Apple Bless. - // - if (IsListEmpty (&FileSystem->BootEntries)) { - AddBootEntryFromBless ( - BootContext, - FileSystem, - gAppleBootPolicyPredefinedPaths, - gAppleBootPolicyNumPredefinedPaths, - FALSE, - FALSE - ); - } - - // - // Record predefined recoveries. - // - AddBootEntryFromSelfRecovery (BootContext, FileSystem); - } - - // - // Build custom and system options. - // - AddFileSystemEntryForCustom (BootContext); - - if (BootContext->BootEntryCount == 0) { - OcFreeBootContext (BootContext); - return NULL; - } - - return BootContext; -} - -OC_BOOT_CONTEXT * -OcScanForDefaultBootEntry ( - IN OC_PICKER_CONTEXT *Context - ) -{ - OC_BOOT_CONTEXT *BootContext; - UINTN Index; - OC_BOOT_FILESYSTEM *FileSystem; - EFI_STATUS Status; - UINTN NoHandles; - EFI_HANDLE *Handles; - - // - // Obtain empty list of filesystems. - // - BootContext = BuildFileSystemList (Context, TRUE); - if (BootContext == NULL) { - return NULL; - } - - DEBUG ((DEBUG_INFO, "OCB: Looking up for default entry\n")); - - // - // Create primary boot options from BootOrder. - // - if (Context->BootOrder == NULL) { - Context->BootOrder = InternalGetBootOrderForBooting ( - BootContext->BootVariableGuid, - &Context->BootOrderCount - ); - } - - if (Context->BootOrder != NULL) { - for (Index = 0; Index < Context->BootOrderCount; ++Index) { - AddBootEntryFromBootOption (BootContext, Context->BootOrder[Index], TRUE); - - // - // Return as long as we are good. - // - if (BootContext->DefaultEntry != NULL) { - return BootContext; - } - } - } - - // - // Obtain filesystems and try processing the remainings. - // - NoHandles = 0; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NoHandles, - &Handles - ); - - DEBUG ((DEBUG_INFO, "OCB: Processing %u blessed list - %r\n", (UINT32) NoHandles, Status)); - - if (!EFI_ERROR(Status)) { - for (Index = 0; Index < NoHandles; ++Index) { - // - // Do not add filesystems twice. - // - if (InternalFileSystemForHandle (BootContext, Handles[Index], FALSE) != NULL) { - continue; - } - - Status = AddFileSystemEntry ( - BootContext, - Handles[Index], - &FileSystem - ); - if (EFI_ERROR(Status)) { - continue; - } - - AddBootEntryFromBless ( - BootContext, - FileSystem, - gAppleBootPolicyPredefinedPaths, - gAppleBootPolicyNumPredefinedPaths, - FALSE, - FALSE - ); - if (BootContext->DefaultEntry != NULL) { - FreePool (Handles); - return BootContext; - } - - AddBootEntryFromSelfRecovery (BootContext, FileSystem); - if (BootContext->DefaultEntry != NULL) { - FreePool (Handles); - return BootContext; - } - } - - FreePool (Handles); - } - - // - // Build custom and system options. - // - AddFileSystemEntryForCustom (BootContext); - - if (BootContext->DefaultEntry == NULL) { - OcFreeBootContext (BootContext); - return NULL; - } - - ASSERT (BootContext->BootEntryCount > 0); - - return BootContext; -} - -OC_BOOT_ENTRY ** -OcEnumerateEntries ( - IN OC_BOOT_CONTEXT *BootContext - ) -{ - OC_BOOT_ENTRY **Entries; - UINT32 EntryIndex; - LIST_ENTRY *FsLink; - OC_BOOT_FILESYSTEM *FileSystem; - LIST_ENTRY *EnLink; - OC_BOOT_ENTRY *BootEntry; - - Entries = AllocatePool (sizeof (*Entries) * BootContext->BootEntryCount); - if (Entries == NULL) { - return NULL; - } - - EntryIndex = 0; - for ( - FsLink = GetFirstNode (&BootContext->FileSystems); - !IsNull (&BootContext->FileSystems, FsLink); - FsLink = GetNextNode (&BootContext->FileSystems, FsLink)) { - FileSystem = BASE_CR (FsLink, OC_BOOT_FILESYSTEM, Link); - - for ( - EnLink = GetFirstNode (&FileSystem->BootEntries); - !IsNull (&FileSystem->BootEntries, EnLink); - EnLink = GetNextNode (&FileSystem->BootEntries, EnLink)) { - BootEntry = BASE_CR (EnLink, OC_BOOT_ENTRY, Link); - - ASSERT (EntryIndex < BootContext->BootEntryCount); - Entries[EntryIndex] = BootEntry; - BootEntry->EntryIndex = ++EntryIndex; - } - } - - ASSERT (EntryIndex == BootContext->BootEntryCount); - ASSERT (BootContext->DefaultEntry == NULL || BootContext->DefaultEntry->EntryIndex > 0); - return Entries; -} - -EFI_STATUS -OcLoadBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN EFI_HANDLE ParentHandle - ) -{ - EFI_STATUS Status; - EFI_HANDLE EntryHandle; - INTERNAL_DMG_LOAD_CONTEXT DmgLoadContext; - - if ((BootEntry->Type & OC_BOOT_SYSTEM) != 0) { - ASSERT (BootEntry->SystemAction != NULL); - return BootEntry->SystemAction (); - } - - Status = InternalLoadBootEntry ( - Context, - BootEntry, - ParentHandle, - &EntryHandle, - &DmgLoadContext - ); - if (!EFI_ERROR(Status)) { - Status = Context->StartImage (BootEntry, EntryHandle, NULL, NULL); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCB: StartImage failed - %r\n", Status)); - // - // Unload dmg if any. - // - InternalUnloadDmg (&DmgLoadContext); - } - } else { - DEBUG ((DEBUG_WARN, "OCB: LoadImage failed - %r\n", Status)); - } - - return Status; -} diff --git a/Library/OcBootManagementLib/BootManagementInternal.h b/Library/OcBootManagementLib/BootManagementInternal.h deleted file mode 100644 index 84f217bd9..000000000 --- a/Library/OcBootManagementLib/BootManagementInternal.h +++ /dev/null @@ -1,178 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef BOOT_MANAGEMENET_INTERNAL_H -#define BOOT_MANAGEMENET_INTERNAL_H - -#include - -#include -#include - -#include -#include -#include - -#define OC_CUSTOM_FS_HANDLE ((EFI_HANDLE)(UINTN) 0x2007C5F5U) - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - OC_APPLE_DISK_IMAGE_CONTEXT *DmgContext; - EFI_HANDLE BlockIoHandle; -} INTERNAL_DMG_LOAD_CONTEXT; - -typedef struct { - EFI_HANDLE Device; - UINTN NumBootInstances; - UINTN HdPrefixSize; - EFI_DEVICE_PATH_PROTOCOL *HdDevicePath; - EFI_DEVICE_PATH_PROTOCOL *BootDevicePath; - BOOLEAN IsExternal; - BOOLEAN SkipRecovery; -} INTERNAL_DEV_PATH_SCAN_INFO; - -EFI_STATUS -InternalCheckScanPolicy ( - IN EFI_HANDLE Handle, - IN UINT32 Policy, - OUT BOOLEAN *External OPTIONAL - ); - -EFI_DEVICE_PATH_PROTOCOL * -InternalLoadDmg ( - IN OUT INTERNAL_DMG_LOAD_CONTEXT *Context, - IN UINT32 Policy - ); - -VOID -InternalUnloadDmg ( - IN INTERNAL_DMG_LOAD_CONTEXT *DmgLoadContext - ); - -CHAR16 * -InternalGetAppleDiskLabel ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *BootDirectoryName, - IN CONST CHAR16 *LabelFilename - ); - -EFI_STATUS -InternalGetAppleImage ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *DirectoryName, - IN CONST CHAR16 *LabelFilename, - OUT VOID **ImageData, - OUT UINT32 *DataSize - ); - -CHAR16 * -InternalGetAppleRecoveryName ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *BootDirectoryName - ); - -EFI_STATUS -InternalGetRecoveryOsBooter ( - IN EFI_HANDLE Device, - OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, - IN BOOLEAN Basic - ); - -EFI_STATUS -InternalLoadBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN EFI_HANDLE ParentHandle, - OUT EFI_HANDLE *EntryHandle, - OUT INTERNAL_DMG_LOAD_CONTEXT *DmgLoadContext - ); - -UINT16 * -InternalGetBootOrderForBooting ( - IN EFI_GUID *BootVariableGuid, - OUT UINTN *BootOrderCount - ); - -VOID -InternalDebugBootEnvironment ( - IN CONST UINT16 *BootOrder, - IN EFI_GUID *BootGuid, - IN UINTN BootOrderCount - ); - -/** - Retrieves booting relevant data from an UEFI Boot#### option. - If BootName is NULL, a BDS-style process is assumed and inactive as well as - non-Boot type applications are ignored. - - @param[in] BootOption The boot option's index. - @param[out] BootName On output, the boot option's description. - @param[out] OptionalDataSize On output, the optional data size. - @param[out] OptionalData On output, a pointer to the optional data. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -InternalGetBootOptionData ( - IN UINT16 BootOption, - IN EFI_GUID *BootGuid, - OUT CHAR16 **BootName OPTIONAL, - OUT UINT32 *OptionalDataSize OPTIONAL, - OUT VOID **OptionalData OPTIONAL - ); - -/** - Describe boot entry contents by setting fields other than DevicePath. - - @param[in] BootEntry Located boot entry. - - @retval EFI_SUCCESS The entry point is described successfully. -**/ -EFI_STATUS -InternalDescribeBootEntry ( - IN OUT OC_BOOT_ENTRY *BootEntry - ); - -BOOLEAN -InternalIsAppleLegacyLoadApp ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Finds filesystem for discovered filesystem handle. - This solves the problem of checking scan policy multiple times - as well as the problem of finding the filesystem to add entries too. - - @param[in] BootContext Context of filesystems. - @param[in] FileSystemHandle Partition handle. - @param[in] LazyScan Lazy filesystem scanning. - - @retval discovered filesystem (legit). - @retcal NULL when booting is not allowed from this filesystem. -**/ -OC_BOOT_FILESYSTEM * -InternalFileSystemForHandle ( - IN OC_BOOT_CONTEXT *BootContext, - IN EFI_HANDLE FileSystemHandle, - IN BOOLEAN LazyScan - ); - -/** - Resets selected NVRAM variables and reboots the system. -**/ -EFI_STATUS -InternalSystemActionResetNvram ( - VOID - ); - -#endif // BOOT_MANAGEMENET_INTERNAL_H diff --git a/Library/OcBootManagementLib/BootSignature.bin b/Library/OcBootManagementLib/BootSignature.bin deleted file mode 100644 index 3cd48ecf4..000000000 Binary files a/Library/OcBootManagementLib/BootSignature.bin and /dev/null differ diff --git a/Library/OcBootManagementLib/DefaultEntryChoice.c b/Library/OcBootManagementLib/DefaultEntryChoice.c deleted file mode 100644 index 80a1bdffa..000000000 --- a/Library/OcBootManagementLib/DefaultEntryChoice.c +++ /dev/null @@ -1,1103 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_DEVICE_PATH_PROTOCOL * -InternalGetBootOptionData ( - IN UINT16 BootOption, - IN EFI_GUID *BootGuid, - OUT CHAR16 **BootName OPTIONAL, - OUT UINT32 *OptionalDataSize OPTIONAL, - OUT VOID **OptionalData OPTIONAL - ) -{ - EFI_STATUS Status; - CHAR16 BootVarName[L_STR_LEN (L"Boot####") + 1]; - - UINTN LoadOptionSize; - EFI_LOAD_OPTION *LoadOption; - UINT8 *LoadOptionPtr; - - UINT32 Attributes; - CONST CHAR16 *Description; - UINTN DescriptionSize; - UINT16 FilePathListSize; - EFI_DEVICE_PATH_PROTOCOL *FilePathList; - - CHAR16 *BootOptionName; - VOID *OptionalDataBuffer; - - UnicodeSPrint (BootVarName, sizeof (BootVarName), L"Boot%04x", BootOption); - - Status = GetVariable2 ( - BootVarName, - BootGuid, - (VOID **)&LoadOption, - &LoadOptionSize - ); - if (EFI_ERROR(Status) || (LoadOptionSize < sizeof (*LoadOption))) { - return NULL; - } - - Attributes = LoadOption->Attributes; - if ((BootName == NULL) - && (((Attributes & LOAD_OPTION_ACTIVE) == 0) - || ((Attributes & LOAD_OPTION_CATEGORY) != LOAD_OPTION_CATEGORY_BOOT))) { - FreePool (LoadOption); - return NULL; - } - - FilePathListSize = LoadOption->FilePathListLength; - - LoadOptionPtr = (UINT8 *)(LoadOption + 1); - LoadOptionSize -= sizeof (*LoadOption); - - if (FilePathListSize > LoadOptionSize) { - FreePool (LoadOption); - return NULL; - } - - LoadOptionSize -= FilePathListSize; - - Description = (CHAR16 *)LoadOptionPtr; - DescriptionSize = StrnSizeS (Description, (LoadOptionSize / sizeof (CHAR16))); - if (DescriptionSize > LoadOptionSize) { - FreePool (LoadOption); - return NULL; - } - - LoadOptionPtr += DescriptionSize; - LoadOptionSize -= DescriptionSize; - - FilePathList = (EFI_DEVICE_PATH_PROTOCOL *)LoadOptionPtr; - if (!IsDevicePathValid (FilePathList, FilePathListSize)) { - FreePool (LoadOption); - return NULL; - } - - LoadOptionPtr += FilePathListSize; - - BootOptionName = NULL; - - if (BootName != NULL) { - BootOptionName = AllocateCopyPool (DescriptionSize, Description); - } - - OptionalDataBuffer = NULL; - - if (OptionalDataSize != NULL) { - ASSERT (OptionalData != NULL); - if (LoadOptionSize > 0) { - OptionalDataBuffer = AllocateCopyPool (LoadOptionSize, LoadOptionPtr); - if (OptionalDataBuffer == NULL) { - LoadOptionSize = 0; - } - } - - *OptionalDataSize = (UINT32)LoadOptionSize; - } - // - // Use the allocated Load Option buffer for the Device Path. - // - CopyMem (LoadOption, FilePathList, FilePathListSize); - FilePathList = (EFI_DEVICE_PATH_PROTOCOL *)LoadOption; - - if (BootName != NULL) { - *BootName = BootOptionName; - } - - if (OptionalData != NULL) { - *OptionalData = OptionalDataBuffer; - } - - return FilePathList; -} - -VOID -InternalDebugBootEnvironment ( - IN CONST UINT16 *BootOrder, - IN EFI_GUID *BootGuid, - IN UINTN BootOrderCount - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *UefiDevicePath; - UINTN UefiDevicePathSize; - CHAR16 *DevicePathText; - UINTN Index; - INT32 Predefined; - - STATIC CONST CHAR16 *AppleDebugVariables[] = { - L"efi-boot-device-data", - L"efi-backup-boot-device-data", - L"efi-apple-recovery-data" - }; - - STATIC CONST UINT16 ApplePredefinedVariables[] = { - 0x80, 0x81, 0x82 - }; - - for (Index = 0; Index < ARRAY_SIZE (AppleDebugVariables); ++Index) { - Status = GetVariable2 ( - AppleDebugVariables[Index], - &gEfiAppleBootGuid, - (VOID **)&UefiDevicePath, - &UefiDevicePathSize - ); - if (!EFI_ERROR(Status) && IsDevicePathValid (UefiDevicePath, UefiDevicePathSize)) { - DevicePathText = ConvertDevicePathToText (UefiDevicePath, FALSE, FALSE); - if (DevicePathText != NULL) { - DEBUG ((DEBUG_INFO, "OCB: %s = %s\n", AppleDebugVariables[Index], DevicePathText)); - FreePool (DevicePathText); - FreePool (UefiDevicePath); - continue; - } - - FreePool (UefiDevicePath); - } - DEBUG ((DEBUG_INFO, "OCB: %s - %r\n", AppleDebugVariables[Index], Status)); - } - - DEBUG ((DEBUG_INFO, "OCB: Dumping BootOrder\n")); - - for (Predefined = 0; Predefined < 2; ++Predefined) { - for (Index = 0; Index < BootOrderCount; ++Index) { - UefiDevicePath = InternalGetBootOptionData ( - BootOrder[Index], - BootGuid, - NULL, - NULL, - NULL - ); - if (UefiDevicePath == NULL) { - DEBUG (( - DEBUG_INFO, - "OCB: %u -> Boot%04x - failed to read\n", - (UINT32) Index, - BootOrder[Index] - )); - continue; - } - - DevicePathText = ConvertDevicePathToText (UefiDevicePath, FALSE, FALSE); - DEBUG (( - DEBUG_INFO, - "OCB: %u -> Boot%04x = %s\n", - (UINT32) Index, - BootOrder[Index], - DevicePathText - )); - if (DevicePathText != NULL) { - FreePool (DevicePathText); - } - - FreePool (UefiDevicePath); - } - - // - // Redo with predefined. - // - if (Predefined == 0) { - BootOrder = &ApplePredefinedVariables[0]; - BootOrderCount = ARRAY_SIZE (ApplePredefinedVariables); - DEBUG ((DEBUG_INFO, "OCB: Parsing predefined list...\n")); - } - } -} - -STATIC -OC_BOOT_ENTRY * -InternalGetBootEntryByDevicePath ( - IN OUT OC_BOOT_ENTRY *BootEntries, - IN UINTN NumBootEntries, - IN EFI_DEVICE_PATH_PROTOCOL *UefiDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *UefiRemainingDevicePath, - IN BOOLEAN IsBootNext - ) -{ - INTN CmpResult; - - UINTN RootDevicePathSize; - - EFI_DEVICE_PATH_PROTOCOL *OcDevicePath; - EFI_DEVICE_PATH_PROTOCOL *OcRemainingDevicePath; - - OC_BOOT_ENTRY *BootEntry; - UINTN Index; - - RootDevicePathSize = ((UINT8 *)UefiRemainingDevicePath - (UINT8 *)UefiDevicePath); - - for (Index = 0; Index < NumBootEntries; ++Index) { - BootEntry = &BootEntries[Index]; - if (BootEntry->DevicePath == NULL || BootEntry->Type == OC_BOOT_SYSTEM) { - continue; - } - - OcDevicePath = BootEntry->DevicePath; - - if ((GetDevicePathSize (OcDevicePath) - END_DEVICE_PATH_LENGTH) < RootDevicePathSize) { - continue; - } - - CmpResult = CompareMem (OcDevicePath, UefiDevicePath, RootDevicePathSize); - if (CmpResult != 0) { - continue; - } - // - // FIXME: Ensure that all the entries get properly filtered against any - // malicious sources. The drive itself should already be safe, but it is - // unclear whether a potentially safe device path can be transformed into - // an unsafe one. - // - OcRemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)( - (UINT8 *)OcDevicePath + RootDevicePathSize - ); - if (!IsBootNext) { - // - // For non-BootNext boot, the File Paths must match for the entries to be - // matched. Startup Disk however only stores the drive's Device Path - // excluding the booter path, which we treat as a match as well. - // - if (!IsDevicePathEnd (UefiRemainingDevicePath) - && !IsDevicePathEqual (UefiRemainingDevicePath, OcRemainingDevicePath) - ) { - continue; - } - } else { - // - // Only use the BootNext path when it has a file path. - // - if (!IsDevicePathEnd (UefiRemainingDevicePath)) { - // - // TODO: Investigate whether macOS adds BootNext entries that are not - // possibly located by bless. - // - FreePool (BootEntry->DevicePath); - BootEntry->DevicePath = UefiDevicePath; - } - } - - return BootEntry; - } - - return NULL; -} - -BOOLEAN -InternalIsAppleLegacyLoadApp ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_DEV_PATH_PTR FwVolDevPath; - - ASSERT (DevicePath != NULL); - - if (DevicePath->Type == HARDWARE_DEVICE_PATH - && DevicePath->SubType == HW_MEMMAP_DP) { - FwVolDevPath.DevPath = NextDevicePathNode (DevicePath); - if (FwVolDevPath.DevPath->Type == MEDIA_DEVICE_PATH - && FwVolDevPath.DevPath->SubType == MEDIA_PIWG_FW_FILE_DP) { - return CompareGuid ( - &FwVolDevPath.FirmwareFile->FvFileName, - &gAppleLegacyLoadAppFileGuid - ); - } - } - - return FALSE; -} - -UINT16 * -OcGetBootOrder ( - IN EFI_GUID *BootVariableGuid, - IN BOOLEAN WithBootNext, - OUT UINTN *BootOrderCount, - OUT BOOLEAN *Deduplicated OPTIONAL, - OUT BOOLEAN *HasBootNext OPTIONAL - ) -{ - EFI_STATUS Status; - UINT32 VariableAttributes; - UINT16 BootNext; - UINT16 *BootOrder; - UINTN VariableSize; - UINTN Index; - UINTN Index2; - BOOLEAN BootOrderChanged; - - *BootOrderCount = 0; - - if (Deduplicated != NULL) { - *Deduplicated = FALSE; - } - - if (HasBootNext != NULL) { - *HasBootNext = FALSE; - } - - // - // Precede variable with boot next. - // - if (WithBootNext) { - VariableSize = sizeof (BootNext); - Status = gRT->GetVariable ( - EFI_BOOT_NEXT_VARIABLE_NAME, - BootVariableGuid, - &VariableAttributes, - &VariableSize, - &BootNext - ); - if (!EFI_ERROR(Status) && VariableSize == sizeof (BootNext)) { - if (HasBootNext != NULL) { - *HasBootNext = TRUE; - } - } else { - WithBootNext = FALSE; - } - } - - VariableSize = 0; - Status = gRT->GetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - BootVariableGuid, - &VariableAttributes, - &VariableSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - BootOrder = AllocatePool ((UINTN) WithBootNext * sizeof (BootNext) + VariableSize); - if (BootOrder == NULL) { - return NULL; - } - - Status = gRT->GetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - BootVariableGuid, - &VariableAttributes, - &VariableSize, - BootOrder + (UINTN) WithBootNext - ); - if (EFI_ERROR(Status) - || VariableSize < sizeof (*BootOrder) - || VariableSize % sizeof (*BootOrder) != 0) { - FreePool (BootOrder); - Status = EFI_UNSUPPORTED; - } - } else if (!EFI_ERROR(Status)) { - Status = EFI_NOT_FOUND; - } - - if (EFI_ERROR(Status)) { - if (WithBootNext) { - BootOrder = AllocateCopyPool (sizeof (BootNext), &BootNext); - if (BootOrder != NULL) { - *BootOrderCount = 1; - return BootOrder; - } - } - - return NULL; - } - - if (WithBootNext) { - BootOrder[0] = BootNext; - VariableSize += sizeof (*BootOrder); - } - - BootOrderChanged = FALSE; - - for (Index = 1; Index < VariableSize / sizeof (BootOrder[0]); ++Index) { - for (Index2 = 0; Index2 < Index; ++Index2) { - if (BootOrder[Index] == BootOrder[Index2]) { - // - // Found duplicate. - // - BootOrderChanged = TRUE; - CopyMem ( - &BootOrder[Index], - &BootOrder[Index + 1], - VariableSize - sizeof (BootOrder[0]) * (Index + 1) - ); - VariableSize -= sizeof (BootOrder[0]); - --Index; - break; - } - } - } - - *BootOrderCount = VariableSize / sizeof (*BootOrder); - if (Deduplicated != NULL) { - *Deduplicated = BootOrderChanged; - } - - return BootOrder; -} - -UINT16 * -InternalGetBootOrderForBooting ( - IN EFI_GUID *BootVariableGuid, - OUT UINTN *BootOrderCount - ) -{ - UINT16 *BootOrder; - BOOLEAN HasBootNext; - - BootOrder = OcGetBootOrder ( - BootVariableGuid, - TRUE, - BootOrderCount, - NULL, - &HasBootNext - ); - if (BootOrder == NULL) { - DEBUG ((DEBUG_INFO, "OCB: BootOrder/BootNext are not present or unsupported\n")); - return NULL; - } - - DEBUG_CODE_BEGIN (); - DEBUG (( - DEBUG_INFO, - "OCB: Found %u BootOrder entries with BootNext %a\n", - (UINT32) *BootOrderCount, - HasBootNext ? "included" : "excluded" - )); - InternalDebugBootEnvironment (BootOrder, BootVariableGuid, *BootOrderCount); - DEBUG_CODE_END (); - - if (HasBootNext) { - gRT->SetVariable ( - EFI_BOOT_NEXT_VARIABLE_NAME, - BootVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - 0, - NULL - ); - } - - return BootOrder; -} - -EFI_STATUS -OcSetDefaultBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *Entry - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH *BootOptionDevicePath; - EFI_DEVICE_PATH *BootOptionRemainingDevicePath; - EFI_HANDLE DeviceHandle; - OC_BOOT_ENTRY *MatchedEntry; - EFI_GUID *BootVariableGuid; - UINT16 *BootOrder; - UINT16 *NewBootOrder; - UINT16 BootTmp; - UINTN BootOrderCount; - UINTN BootChosenIndex; - UINTN Index; - UINTN DevicePathSize; - UINTN LoadOptionSize; - UINTN LoadOptionNameSize; - EFI_LOAD_OPTION *LoadOption; - - // - // Do not allow when prohibited. - // - if (!Context->AllowSetDefault) { - return EFI_SECURITY_VIOLATION; - } - - // - // Ignore entries without device paths. - // - if (Entry->DevicePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Context->CustomBootGuid) { - BootVariableGuid = &gOcVendorVariableGuid; - } else { - BootVariableGuid = &gEfiGlobalVariableGuid; - } - - BootOrder = OcGetBootOrder ( - BootVariableGuid, - FALSE, - &BootOrderCount, - NULL, - NULL - ); - - MatchedEntry = NULL; - BootChosenIndex = BootOrderCount; - for (Index = 0; Index < BootOrderCount; ++Index) { - if (BootOrder[Index] == 0x80) { - BootChosenIndex = Index; - } - - if (MatchedEntry != NULL) { - if (BootChosenIndex != BootOrderCount) { - break; - } - continue; - } - - BootOptionDevicePath = InternalGetBootOptionData ( - BootOrder[Index], - BootVariableGuid, - NULL, - NULL, - NULL - ); - - if (BootOptionDevicePath == NULL) { - continue; - } - - BootOptionRemainingDevicePath = BootOptionDevicePath; - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - &BootOptionRemainingDevicePath, - &DeviceHandle - ); - - if (!EFI_ERROR(Status)) { - MatchedEntry = InternalGetBootEntryByDevicePath ( - Entry, - 1, - BootOptionDevicePath, - BootOptionRemainingDevicePath, - FALSE - ); - } - } - - if (MatchedEntry == NULL) { - // - // Write to Boot0080 - // - LoadOptionNameSize = StrSize (Entry->Name); - DevicePathSize = GetDevicePathSize (Entry->DevicePath); - LoadOptionSize = sizeof (EFI_LOAD_OPTION) + LoadOptionNameSize + DevicePathSize; - - LoadOption = AllocatePool (LoadOptionSize); - if (LoadOption == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to allocate default option (%u)\n", (UINT32) LoadOptionSize)); - if (BootOrder != NULL) { - FreePool (BootOrder); - } - return EFI_OUT_OF_RESOURCES; - } - - LoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT; - LoadOption->FilePathListLength = (UINT16) DevicePathSize; - CopyMem (LoadOption + 1, Entry->Name, LoadOptionNameSize); - CopyMem ((UINT8 *) (LoadOption + 1) + LoadOptionNameSize, Entry->DevicePath, DevicePathSize); - - Status = gRT->SetVariable ( - L"Boot0080", - BootVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_NON_VOLATILE, - LoadOptionSize, - LoadOption - ); - - FreePool (LoadOption); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to set default entry Boot0080 - %r\n", - Status - )); - if (BootOrder != NULL) { - FreePool (BootOrder); - } - return Status; - } - } else { - DEBUG ((DEBUG_INFO, "OCB: Matched default entry in BootOrder\n")); - BootChosenIndex = Index; - } - - // - // Update BootOrder to contain new option. - // - if (BootChosenIndex != BootOrderCount) { - BootTmp = BootOrder[0]; - BootOrder[0] = BootOrder[BootChosenIndex]; - BootOrder[BootChosenIndex] = BootTmp; - NewBootOrder = BootOrder; - - DEBUG (( - DEBUG_INFO, - "OCB: Found default entry in BootOrder, reordering %X <-> %X\n", - NewBootOrder[0], - NewBootOrder[BootChosenIndex] - )); - } else { - DEBUG (( - DEBUG_INFO, - "OCB: Adding default entry Boot0080 to BootOrder\n" - )); - - NewBootOrder = AllocatePool ((BootOrderCount + 1) * sizeof (*BootOrder)); - if (NewBootOrder == NULL) { - if (BootOrder != NULL) { - FreePool (BootOrder); - } - return EFI_OUT_OF_RESOURCES; - } - - NewBootOrder[0] = 0x80; - CopyMem (&NewBootOrder[1], &BootOrder[0], BootOrderCount * sizeof (*BootOrder)); - - if (BootOrder != NULL) { - FreePool (BootOrder); - } - - ++BootOrderCount; - } - - Status = gRT->SetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - BootVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_NON_VOLATILE, - BootOrderCount * sizeof (*BootOrder), - NewBootOrder - ); - - FreePool (NewBootOrder); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to set default BootOrder - %r\n", - Status - )); - } - - return Status; -} - -STATIC -EFI_STATUS -InternalRegisterBootOption ( - IN CONST CHAR16 *OptionName, - IN EFI_HANDLE DeviceHandle, - IN CONST CHAR16 *FilePath - ) -{ - EFI_STATUS Status; - EFI_LOAD_OPTION *Option; - UINTN OptionNameSize; - UINTN DevicePathSize; - UINTN OptionSize; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *CurrDevicePath; - UINTN Index; - UINT16 *BootOrder; - UINTN BootOrderSize; - UINT32 BootOrderAttributes; - UINT16 NewBootOrder; - BOOLEAN CurrOptionValid; - - Status = gBS->HandleProtocol ( - DeviceHandle, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCB: Failed to obtain device path for boot option - %r\n", Status)); - return Status; - } - - DevicePath = AppendFileNameDevicePath (DevicePath, (CHAR16 *) FilePath); - if (DevicePath == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to append %s loader path for boot option - %r\n", FilePath)); - return EFI_OUT_OF_RESOURCES; - } - - CurrDevicePath = InternalGetBootOptionData (OC_BOOT_OPTION, &gEfiGlobalVariableGuid, NULL, NULL, NULL); - if (CurrDevicePath != NULL) { - CurrOptionValid = IsDevicePathEqual (DevicePath, CurrDevicePath); - FreePool (CurrDevicePath); - } else { - CurrOptionValid = FALSE; - } - - DEBUG (( - DEBUG_INFO, - "OCB: Have existing option %d, valid %d\n", - CurrDevicePath != NULL, - CurrOptionValid - )); - - if (!CurrOptionValid) { - OptionNameSize = StrSize (OptionName); - DevicePathSize = GetDevicePathSize (DevicePath); - OptionSize = sizeof (EFI_LOAD_OPTION) + OptionNameSize + DevicePathSize; - - DEBUG ((DEBUG_INFO, "OCB: Creating boot option %s of %u bytes\n", OptionName, (UINT32) OptionSize)); - - Option = AllocatePool (OptionSize); - if (Option == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to allocate boot option (%u)\n", (UINT32) OptionSize)); - FreePool (DevicePath); - return EFI_OUT_OF_RESOURCES; - } - - Option->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT; - Option->FilePathListLength = (UINT16) DevicePathSize; - CopyMem (Option + 1, OptionName, OptionNameSize); - CopyMem ((UINT8 *) (Option + 1) + OptionNameSize, DevicePath, DevicePathSize); - - Status = gRT->SetVariable ( - OC_BOOT_OPTION_VARIABLE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_NON_VOLATILE, - OptionSize, - Option - ); - - FreePool (Option); - FreePool (DevicePath); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCB: Failed to store boot option - %r\n", Status)); - return Status; - } - } - - BootOrderSize = 0; - Status = gRT->GetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - &gEfiGlobalVariableGuid, - &BootOrderAttributes, - &BootOrderSize, - NULL - ); - - DEBUG (( - DEBUG_INFO, - "OCB: Have existing order of size %u - %r\n", - (UINT32) BootOrderSize, - Status - )); - - if (Status == EFI_BUFFER_TOO_SMALL && BootOrderSize > 0 && BootOrderSize % sizeof (UINT16) == 0) { - BootOrder = AllocatePool (BootOrderSize + sizeof (UINT16)); - if (BootOrder == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to allocate boot order\n")); - return EFI_OUT_OF_RESOURCES; - } - - Status = gRT->GetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - &gEfiGlobalVariableGuid, - &BootOrderAttributes, - &BootOrderSize, - (VOID *) (BootOrder + 1) - ); - - if (EFI_ERROR(Status) || BootOrderSize == 0 || BootOrderSize % sizeof (UINT16) != 0) { - DEBUG ((DEBUG_INFO, "OCB: Failed to obtain boot order %u - %r\n", (UINT32) BootOrderSize, Status)); - if (!EFI_ERROR(Status)) { - FreePool (BootOrder); - } - return EFI_OUT_OF_RESOURCES; - } - - if (BootOrder[1] == OC_BOOT_OPTION) { - DEBUG ((DEBUG_INFO, "OCB: Boot order has first option as the default option\n")); - FreePool (BootOrder); - return EFI_SUCCESS; - } - - BootOrder[0] = OC_BOOT_OPTION; - - Index = 1; - while (Index <= BootOrderSize / sizeof (UINT16)) { - if (BootOrder[Index] == OC_BOOT_OPTION) { - DEBUG ((DEBUG_INFO, "OCB: Moving boot option to the front from %u position\n", (UINT32) Index)); - CopyMem ( - &BootOrder[Index], - &BootOrder[Index + 1], - BootOrderSize - Index * sizeof (UINT16) - ); - BootOrderSize -= sizeof (UINT16); - } else { - ++Index; - } - } - - Status = gRT->SetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_NON_VOLATILE, - BootOrderSize + sizeof (UINT16), - BootOrder - ); - - FreePool (BootOrder); - } else { - NewBootOrder = OC_BOOT_OPTION; - Status = gRT->SetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_NON_VOLATILE, - sizeof (UINT16), - &NewBootOrder - ); - } - - DEBUG ((DEBUG_INFO, "OCB: Wrote new boot order with boot option - %r\n", Status)); - return EFI_SUCCESS; -} - -EFI_STATUS -OcRegisterBootOption ( - IN CONST CHAR16 *OptionName, - IN EFI_HANDLE DeviceHandle, - IN CONST CHAR16 *FilePath - ) -{ - EFI_STATUS Status; - OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; - OC_FWRT_CONFIG Config; - - Status = gBS->LocateProtocol ( - &gOcFirmwareRuntimeProtocolGuid, - NULL, - (VOID **) &FwRuntime - ); - - if (!EFI_ERROR(Status) && FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) { - ZeroMem (&Config, sizeof (Config)); - FwRuntime->SetOverride (&Config); - DEBUG ((DEBUG_INFO, "OCB: Found FW NVRAM, full access %d\n", Config.BootVariableRedirect)); - } else { - FwRuntime = NULL; - DEBUG ((DEBUG_INFO, "OCB: Missing FW NVRAM, going on...\n")); - } - - Status = InternalRegisterBootOption ( - OptionName, - DeviceHandle, - FilePath - ); - - if (FwRuntime != NULL) { - FwRuntime->SetOverride (NULL); - } - - return Status; -} - -EFI_STATUS -InternalLoadBootEntry ( - IN OC_PICKER_CONTEXT *Context, - IN OC_BOOT_ENTRY *BootEntry, - IN EFI_HANDLE ParentHandle, - OUT EFI_HANDLE *EntryHandle, - OUT INTERNAL_DMG_LOAD_CONTEXT *DmgLoadContext - ) -{ - EFI_STATUS Status; - EFI_STATUS OptionalStatus; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_HANDLE ParentDeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *ParentFilePath; - CHAR16 *UnicodeDevicePath; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - VOID *EntryData; - UINT32 EntryDataSize; - CONST CHAR8 *Args; - UINT32 ArgsLen; - - ASSERT (BootEntry != NULL); - // - // System entries are not loaded but called directly. - // - ASSERT ((BootEntry->Type & OC_BOOT_SYSTEM) == 0); - ASSERT (Context != NULL); - ASSERT (DmgLoadContext != NULL); - - // - // TODO: support Apple loaded image, policy, and dmg boot. - // - - ZeroMem (DmgLoadContext, sizeof (*DmgLoadContext)); - - EntryData = NULL; - EntryDataSize = 0; - ParentDeviceHandle = NULL; - ParentFilePath = NULL; - - if (BootEntry->IsFolder) { - if ((Context->LoadPolicy & OC_LOAD_ALLOW_DMG_BOOT) == 0) { - return EFI_SECURITY_VIOLATION; - } - - DmgLoadContext->DevicePath = BootEntry->DevicePath; - DevicePath = InternalLoadDmg (DmgLoadContext, Context->LoadPolicy); - if (DevicePath == NULL) { - return EFI_UNSUPPORTED; - } - } else if (BootEntry->Type == OC_BOOT_EXTERNAL_TOOL) { - ASSERT (Context->CustomRead != NULL); - - Status = Context->CustomRead ( - Context->CustomEntryContext, - BootEntry, - &EntryData, - &EntryDataSize, - &DevicePath, - &ParentDeviceHandle, - &ParentFilePath - ); - - if (EFI_ERROR(Status)) { - return Status; - } - } else { - DevicePath = BootEntry->DevicePath; - } - - DEBUG_CODE_BEGIN (); - ASSERT (DevicePath != NULL); - UnicodeDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE); - DEBUG (( - DEBUG_INFO, - "OCB: Perform boot %s to dp %s (%p/%u)\n", - BootEntry->Name, - UnicodeDevicePath != NULL ? UnicodeDevicePath : L"", - EntryData, - EntryDataSize - )); - if (UnicodeDevicePath != NULL) { - FreePool (UnicodeDevicePath); - } - DEBUG_CODE_END (); - - Status = gBS->LoadImage ( - FALSE, - ParentHandle, - DevicePath, - EntryData, - EntryDataSize, - EntryHandle - ); - - if (EntryData != NULL) { - FreePool (EntryData); - } - - if (!EFI_ERROR(Status)) { - OptionalStatus = gBS->HandleProtocol ( - *EntryHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &LoadedImage - ); - if (!EFI_ERROR (OptionalStatus)) { - DEBUG (( - DEBUG_INFO, - "OCB: Matching <%a> args on type %u %p\n", - Context->AppleBootArgs, - BootEntry->Type, - BootEntry->LoadOptions - )); - - LoadedImage->LoadOptionsSize = 0; - LoadedImage->LoadOptions = NULL; - - if (BootEntry->LoadOptions == NULL && (BootEntry->Type & OC_BOOT_APPLE_ANY) != 0) { - Args = Context->AppleBootArgs; - ArgsLen = (UINT32) AsciiStrLen (Args); - } else { - Args = BootEntry->LoadOptions; - ArgsLen = BootEntry->LoadOptionsSize; - ASSERT (ArgsLen == ((Args == NULL) ? 0 : (UINT32) AsciiStrLen (Args))); - } - - if (ArgsLen > 0) { - LoadedImage->LoadOptions = AsciiStrCopyToUnicode (Args, ArgsLen); - if (LoadedImage->LoadOptions != NULL) { - LoadedImage->LoadOptionsSize = ArgsLen * sizeof (CHAR16) + sizeof (CHAR16); - } - } - - if (BootEntry->Type == OC_BOOT_EXTERNAL_OS || BootEntry->Type == OC_BOOT_EXTERNAL_TOOL) { - DEBUG (( - DEBUG_INFO, - "OCB: Custom (%u) DeviceHandle %p FilePath %p\n", - BootEntry->Type, - LoadedImage->DeviceHandle, - LoadedImage->FilePath - )); - - // - // Some fragile firmwares fail to properly set LoadedImage file source - // fields to our custom device path, so we fix it up here. - // REF: https://github.com/acidanthera/bugtracker/issues/712 - // - if (LoadedImage->DeviceHandle == NULL && ParentDeviceHandle != NULL) { - if (LoadedImage->FilePath != NULL) { - FreePool (LoadedImage->FilePath); - } - LoadedImage->DeviceHandle = ParentDeviceHandle; - LoadedImage->FilePath = DuplicateDevicePath (ParentFilePath); - } - } - } - } else { - InternalUnloadDmg (DmgLoadContext); - } - - return Status; -} diff --git a/Library/OcBootManagementLib/DmgBootSupport.c b/Library/OcBootManagementLib/DmgBootSupport.c deleted file mode 100644 index 8349c9f41..000000000 --- a/Library/OcBootManagementLib/DmgBootSupport.c +++ /dev/null @@ -1,514 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_DEVICE_PATH_PROTOCOL * -InternalGetFirstDeviceBootFilePath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DmgDevicePath, - IN UINTN DmgDevicePathSize - ) -{ - EFI_DEVICE_PATH_PROTOCOL *BootDevicePath; - - EFI_STATUS Status; - INTN CmpResult; - - CONST EFI_DEVICE_PATH_PROTOCOL *FsDevicePath; - UINTN FsDevicePathSize; - - UINTN NumHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - ASSERT (DmgDevicePath != NULL); - ASSERT (DmgDevicePathSize >= END_DEVICE_PATH_LENGTH); - - BootDevicePath = NULL; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumHandles, - &HandleBuffer - ); - if (EFI_ERROR(Status)) { - return NULL; - } - - for (Index = 0; Index < NumHandles; ++Index) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - (VOID **)&FsDevicePath - ); - if (EFI_ERROR(Status)) { - continue; - } - - FsDevicePathSize = GetDevicePathSize (FsDevicePath); - - if (FsDevicePathSize < DmgDevicePathSize) { - continue; - } - - CmpResult = CompareMem ( - FsDevicePath, - DmgDevicePath, - (DmgDevicePathSize - END_DEVICE_PATH_LENGTH) - ); - if (CmpResult != 0) { - continue; - } - - Status = OcBootPolicyGetBootFileEx ( - HandleBuffer[Index], - gAppleBootPolicyPredefinedPaths, - gAppleBootPolicyNumPredefinedPaths, - &BootDevicePath - ); - if (!EFI_ERROR(Status)) { - break; - } - - BootDevicePath = NULL; - } - - FreePool (HandleBuffer); - - return BootDevicePath; -} - -STATIC -EFI_DEVICE_PATH_PROTOCOL * -InternalGetDiskImageBootFile ( - OUT INTERNAL_DMG_LOAD_CONTEXT *Context, - IN UINT32 Policy, - IN UINTN DmgFileSize, - IN VOID *ChunklistBuffer OPTIONAL, - IN UINT32 ChunklistBufferSize OPTIONAL - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevPath; - - BOOLEAN Result; - OC_APPLE_CHUNKLIST_CONTEXT ChunklistContext; - - CONST EFI_DEVICE_PATH_PROTOCOL *DmgDevicePath; - UINTN DmgDevicePathSize; - - ASSERT (Context != NULL); - ASSERT (DmgFileSize > 0); - - if (ChunklistBuffer == NULL) { - if ((Policy & OC_LOAD_REQUIRE_APPLE_SIGN) != 0) { - DEBUG ((DEBUG_WARN, "OCB: Missing DMG signature, aborting\n")); - return NULL; - } - } else if ((Policy & (OC_LOAD_VERIFY_APPLE_SIGN | OC_LOAD_REQUIRE_TRUSTED_KEY)) != 0) { - ASSERT (ChunklistBufferSize > 0); - - Result = OcAppleChunklistInitializeContext ( - &ChunklistContext, - ChunklistBuffer, - ChunklistBufferSize - ); - if (!Result) { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to initialise DMG Chunklist context\n" - )); - return NULL; - } - - if ((Policy & OC_LOAD_REQUIRE_TRUSTED_KEY) != 0) { - Result = FALSE; - // - // FIXME: Properly abstract OcAppleKeysLib. - // - if ((Policy & OC_LOAD_TRUST_APPLE_V1_KEY) != 0) { - Result = OcAppleChunklistVerifySignature ( - &ChunklistContext, - PkDataBase[0].PublicKey - ); - } - - if (!Result && ((Policy & OC_LOAD_TRUST_APPLE_V2_KEY) != 0)) { - Result = OcAppleChunklistVerifySignature ( - &ChunklistContext, - PkDataBase[1].PublicKey - ); - } - - if (!Result) { - DEBUG ((DEBUG_WARN, "OCB: DMG is not trusted, aborting\n")); - return NULL; - } - } - - Result = OcAppleDiskImageVerifyData ( - Context->DmgContext, - &ChunklistContext - ); - if (!Result) { - DEBUG ((DEBUG_WARN, "OCB: DMG has been altered\n")); - // - // FIXME: Warn user instead of aborting when OC_LOAD_REQUIRE_TRUSTED_KEY - // is not set. - // - return NULL; - } - } - - Context->BlockIoHandle = OcAppleDiskImageInstallBlockIo ( - Context->DmgContext, - DmgFileSize, - &DmgDevicePath, - &DmgDevicePathSize - ); - if (Context->BlockIoHandle == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to install DMG Block I/O\n")); - return NULL; - } - - DevPath = InternalGetFirstDeviceBootFilePath ( - DmgDevicePath, - DmgDevicePathSize - ); - if (DevPath == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to get bootable file off DMG\n")); - - OcAppleDiskImageUninstallBlockIo ( - Context->DmgContext, - Context->BlockIoHandle - ); - return NULL; - } - - return DevPath; -} - -STATIC -EFI_FILE_INFO * -InternalFindFirstDmgFileName ( - IN EFI_FILE_PROTOCOL *Directory, - OUT UINTN *FileNameLen - ) -{ - EFI_STATUS Status; - EFI_FILE_INFO *FileInfo; - BOOLEAN NoFile; - UINTN ExtOffset; - UINTN Length; - INTN Result; - - ASSERT (Directory != NULL); - - for ( - Status = FileHandleFindFirstFile (Directory, &FileInfo), NoFile = FALSE; - (!EFI_ERROR(Status) && !NoFile); - Status = FileHandleFindNextFile (Directory, FileInfo, &NoFile) - ) { - if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { - continue; - } - - // - // Discard filenames that do not contain characters prior to .dmg extension. - // - Length = StrLen (FileInfo->FileName); - if (Length <= L_STR_LEN (L".dmg")) { - continue; - } - - ExtOffset = Length - L_STR_LEN (L".dmg"); - Result = StrCmp (&FileInfo->FileName[ExtOffset], L".dmg"); - if (Result == 0) { - if (FileNameLen != NULL) { - *FileNameLen = ExtOffset; - } - - return FileInfo; - } - } - - return NULL; -} - -STATIC -EFI_FILE_INFO * -InternalFindDmgChunklist ( - IN EFI_FILE_PROTOCOL *Directory, - IN CONST CHAR16 *DmgFileName, - IN UINTN DmgFileNameLen - ) -{ - EFI_STATUS Status; - EFI_FILE_INFO *FileInfo; - BOOLEAN NoFile; - UINTN NameLen; - INTN Result; - UINTN ChunklistFileNameLen; - - ChunklistFileNameLen = (DmgFileNameLen + L_STR_LEN (".chunklist")); - - for ( - Status = FileHandleFindFirstFile (Directory, &FileInfo), NoFile = FALSE; - (!EFI_ERROR(Status) && !NoFile); - Status = FileHandleFindNextFile (Directory, FileInfo, &NoFile) - ) { - if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) { - continue; - } - - NameLen = StrLen (FileInfo->FileName); - - if (NameLen != ChunklistFileNameLen) { - continue; - } - - Result = StrnCmp (FileInfo->FileName, DmgFileName, DmgFileNameLen); - if (Result != 0) { - continue; - } - - Result = StrCmp (&FileInfo->FileName[DmgFileNameLen], L".chunklist"); - if (Result == 0) { - DEBUG (( - DEBUG_INFO, - "OCB: Found chunklist %s for DMG %s[%d]\n", - FileInfo->FileName, - DmgFileName, - DmgFileNameLen - )); - return FileInfo; - } - } - - DEBUG (( - DEBUG_INFO, - "OCB: Found no chunklist for DMG %s[%d]\n", - DmgFileName, - DmgFileNameLen - )); - return NULL; -} - -EFI_DEVICE_PATH_PROTOCOL * -InternalLoadDmg ( - IN OUT INTERNAL_DMG_LOAD_CONTEXT *Context, - IN UINT32 Policy - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevPath; - - EFI_STATUS Status; - BOOLEAN Result; - - EFI_FILE_PROTOCOL *DmgDir; - - UINTN DmgFileNameLen; - EFI_FILE_INFO *DmgFileInfo; - EFI_FILE_PROTOCOL *DmgFile; - UINT32 DmgFileSize; - - EFI_FILE_INFO *ChunklistFileInfo; - EFI_FILE_PROTOCOL *ChunklistFile; - UINT32 ChunklistFileSize; - VOID *ChunklistBuffer; - - CHAR16 *DevPathText; - - ASSERT (Context != NULL); - - DevPath = Context->DevicePath; - Status = OcOpenFileByDevicePath ( - &DevPath, - &DmgDir, - EFI_FILE_MODE_READ, - EFI_FILE_DIRECTORY - ); - if (EFI_ERROR(Status)) { - DevPathText = ConvertDevicePathToText (Context->DevicePath, FALSE, FALSE); - DEBUG ((DEBUG_INFO, "OCB: Failed to open DMG directory %s\n", DevPathText)); - if (DevPathText != NULL) { - FreePool (DevPathText); - } - - return NULL; - } - - DmgFileInfo = InternalFindFirstDmgFileName (DmgDir, &DmgFileNameLen); - if (DmgFileInfo == NULL) { - DevPathText = ConvertDevicePathToText (Context->DevicePath, FALSE, FALSE); - DEBUG ((DEBUG_INFO, "OCB: Unable to find any DMG at %s\n")); - if (DevPathText != NULL) { - FreePool (DevPathText); - } - - DmgDir->Close (DmgDir); - return NULL; - } - - Status = SafeFileOpen ( - DmgDir, - &DmgFile, - DmgFileInfo->FileName, - EFI_FILE_MODE_READ, - 0 - ); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to open DMG file %s - %r\n", - DmgFileInfo->FileName, - Status - )); - - FreePool (DmgFileInfo); - DmgDir->Close (DmgDir); - return NULL; - } - - Status = GetFileSize (DmgFile, &DmgFileSize); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to retrieve DMG file size - %r\n", - Status - )); - - FreePool (DmgFileInfo); - DmgDir->Close (DmgDir); - DmgFile->Close (DmgFile); - return NULL; - } - - Context->DmgContext = AllocatePool (sizeof (*Context->DmgContext)); - if (Context->DmgContext == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to allocate DMG context\n")); - return NULL; - } - - Result = OcAppleDiskImageInitializeFromFile (Context->DmgContext, DmgFile); - - DmgFile->Close (DmgFile); - - if (!Result) { - DEBUG ((DEBUG_INFO, "OCB: Failed to initialise DMG from file\n")); - - FreePool (DmgFileInfo); - FreePool (Context->DmgContext); - DmgDir->Close (DmgDir); - return NULL; - } - - ChunklistBuffer = NULL; - ChunklistFileSize = 0; - - ChunklistFileInfo = InternalFindDmgChunklist ( - DmgDir, - DmgFileInfo->FileName, - DmgFileNameLen - ); - if (ChunklistFileInfo != NULL) { - Status = SafeFileOpen ( - DmgDir, - &ChunklistFile, - ChunklistFileInfo->FileName, - EFI_FILE_MODE_READ, - 0 - ); - if (!EFI_ERROR(Status)) { - Status = GetFileSize (ChunklistFile, &ChunklistFileSize); - if (Status == EFI_SUCCESS) { - ChunklistBuffer = AllocatePool (ChunklistFileSize); - - if (ChunklistBuffer == NULL) { - ChunklistFileSize = 0; - } else { - Status = GetFileData (ChunklistFile, 0, ChunklistFileSize, ChunklistBuffer); - if (EFI_ERROR(Status)) { - FreePool (ChunklistBuffer); - ChunklistBuffer = NULL; - ChunklistFileSize = 0; - } - } - } - - ChunklistFile->Close (ChunklistFile); - } - - FreePool (ChunklistFileInfo); - } - - FreePool (DmgFileInfo); - - DmgDir->Close (DmgDir); - - DevPath = InternalGetDiskImageBootFile ( - Context, - Policy, - DmgFileSize, - ChunklistBuffer, - ChunklistFileSize - ); - Context->DevicePath = DevPath; - - if (DevPath == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Failed to retrieve boot file from DMG\n")); - - OcAppleDiskImageFreeFile (Context->DmgContext); - FreePool (Context->DmgContext); - } - - if (ChunklistBuffer != NULL) { - FreePool (ChunklistBuffer); - } - - return DevPath; -} - -VOID -InternalUnloadDmg ( - IN INTERNAL_DMG_LOAD_CONTEXT *DmgLoadContext - ) -{ - if (DmgLoadContext->DevicePath != NULL) { - FreePool (DmgLoadContext->DevicePath); - OcAppleDiskImageUninstallBlockIo ( - DmgLoadContext->DmgContext, - DmgLoadContext->BlockIoHandle - ); - OcAppleDiskImageFreeContext (DmgLoadContext->DmgContext); - FreePool (DmgLoadContext->DmgContext); - DmgLoadContext->DevicePath = NULL; - } -} diff --git a/Library/OcBootManagementLib/HotKeySupport.c b/Library/OcBootManagementLib/HotKeySupport.c deleted file mode 100644 index 1ff3a83d8..000000000 --- a/Library/OcBootManagementLib/HotKeySupport.c +++ /dev/null @@ -1,440 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define APPLE_KEY_CODE APPLE_KEY - -VOID -OcLoadPickerHotKeys ( - IN OUT OC_PICKER_CONTEXT *Context - ) -{ - EFI_STATUS Status; - APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap; - - UINTN NumKeys; - APPLE_MODIFIER_MAP Modifiers; - APPLE_KEY_CODE Keys[OC_KEY_MAP_DEFAULT_SIZE]; - - BOOLEAN HasCommand; - BOOLEAN HasEscape; - BOOLEAN HasOption; - BOOLEAN HasKeyP; - BOOLEAN HasKeyR; - BOOLEAN HasKeyX; - - if (Context->TakeoffDelay > 0) { - gBS->Stall (Context->TakeoffDelay); - } - - Status = gBS->LocateProtocol ( - &gAppleKeyStateProtocolGuid, - NULL, - (VOID **) &KeyMap - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCB: Missing AppleKeyMapAggregator - %r\n", Status)); - return; - } - - NumKeys = ARRAY_SIZE (Keys); - Status = KeyMap->GetKeyStrokes ( - KeyMap, - &Modifiers, - &NumKeys, - Keys - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCB: GetKeyStrokes - %r\n", Status)); - return; - } - - // - // I do not like this code a little, as it is prone to race conditions during key presses. - // For the good false positives are not too critical here, and in reality users are not that fast. - // - // Reference key list: - // https://support.apple.com/HT201255 - // https://support.apple.com/HT204904 - // - // We are slightly more permissive than AppleBds, as we permit combining keys. - // - - HasCommand = (Modifiers & (APPLE_MODIFIER_LEFT_COMMAND | APPLE_MODIFIER_RIGHT_COMMAND)) != 0; - HasOption = (Modifiers & (APPLE_MODIFIER_LEFT_OPTION | APPLE_MODIFIER_RIGHT_OPTION)) != 0; - HasEscape = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyEscape); - HasKeyP = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyP); - HasKeyR = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyR); - HasKeyX = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyX); - - if (HasOption && HasCommand && HasKeyP && HasKeyR) { - DEBUG ((DEBUG_INFO, "OCB: CMD+OPT+P+R causes NVRAM reset\n")); - Context->PickerCommand = OcPickerResetNvram; - } else if (HasCommand && HasKeyR) { - DEBUG ((DEBUG_INFO, "OCB: CMD+R causes recovery to boot\n")); - Context->PickerCommand = OcPickerBootAppleRecovery; - } else if (HasKeyX) { - DEBUG ((DEBUG_INFO, "OCB: X causes macOS to boot\n")); - Context->PickerCommand = OcPickerBootApple; - } else if (HasOption) { - DEBUG ((DEBUG_INFO, "OCB: OPT causes picker to show\n")); - Context->PickerCommand = OcPickerShowPicker; - } else if (HasEscape) { - DEBUG ((DEBUG_INFO, "OCB: ESC causes picker to show as OC extension\n")); - Context->PickerCommand = OcPickerShowPicker; - } else { - // - // In addition to these overrides we always have ShowPicker = YES in config. - // The following keys are not implemented: - // C - CD/DVD boot, legacy that is gone now. - // D - Diagnostics, could implement dumping stuff here in some future, - // but we will need to store the data before handling the key. - // Should also be DEBUG only for security reasons. - // N - Network boot, simply not supported (and bad for security). - // T - Target disk mode, simply not supported (and bad for security). - // - } -} - -INTN -OcGetAppleKeyIndex ( - IN OUT OC_PICKER_CONTEXT *Context, - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - OUT BOOLEAN *SetDefault OPTIONAL - ) -{ - EFI_STATUS Status; - APPLE_KEY_CODE KeyCode; - - UINTN NumKeys; - APPLE_MODIFIER_MAP Modifiers; - APPLE_KEY_CODE Keys[OC_KEY_MAP_DEFAULT_SIZE]; - - BOOLEAN HasCommand; - BOOLEAN HasShift; - BOOLEAN HasKeyC; - BOOLEAN HasKeyK; - BOOLEAN HasKeyS; - BOOLEAN HasKeyV; - BOOLEAN HasKeyMinus; - BOOLEAN WantsZeroSlide; - BOOLEAN WantsDefault; - UINT32 CsrActiveConfig; - UINTN CsrActiveConfigSize; - - NumKeys = ARRAY_SIZE (Keys); - Status = KeyMap->GetKeyStrokes ( - KeyMap, - &Modifiers, - &NumKeys, - Keys - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCB: GetKeyStrokes - %r\n", Status)); - return OC_INPUT_INVALID; - } - - // - // Handle key combinations. - // - if (Context->PollAppleHotKeys) { - HasCommand = (Modifiers & (APPLE_MODIFIER_LEFT_COMMAND | APPLE_MODIFIER_RIGHT_COMMAND)) != 0; - HasShift = (Modifiers & (APPLE_MODIFIER_LEFT_SHIFT | APPLE_MODIFIER_RIGHT_SHIFT)) != 0; - HasKeyC = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyC); - HasKeyK = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyK); - HasKeyS = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyS); - HasKeyV = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyV); - // - // Checking for PAD minus is our extension to support more keyboards. - // - HasKeyMinus = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyMinus) - || OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyPadMinus); - - // - // Shift is always valid and enables Safe Mode. - // - if (HasShift) { - if (OcGetArgumentFromCmd (Context->AppleBootArgs, "-x", L_STR_LEN ("-x")) == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Shift means -x\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "-x", L_STR_LEN ("-x")); - } - return OC_INPUT_INTERNAL; - } - - // - // CMD+V is always valid and enables Verbose Mode. - // - if (HasCommand && HasKeyV) { - if (OcGetArgumentFromCmd (Context->AppleBootArgs, "-v", L_STR_LEN ("-v")) == NULL) { - DEBUG ((DEBUG_INFO, "OCB: CMD+V means -v\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "-v", L_STR_LEN ("-v")); - } - return OC_INPUT_INTERNAL; - } - - // - // CMD+C+MINUS is always valid and disables compatibility check. - // - if (HasCommand && HasKeyC && HasKeyMinus) { - if (OcGetArgumentFromCmd (Context->AppleBootArgs, "-no_compat_check", L_STR_LEN ("-no_compat_check")) == NULL) { - DEBUG ((DEBUG_INFO, "OCB: CMD+C+MINUS means -no_compat_check\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "-no_compat_check", L_STR_LEN ("-no_compat_check")); - } - return OC_INPUT_INTERNAL; - } - - // - // CMD+K is always valid for new macOS and means force boot to release kernel. - // - if (HasCommand && HasKeyK) { - if (AsciiStrStr (Context->AppleBootArgs, "kcsuffix=release") == NULL) { - DEBUG ((DEBUG_INFO, "OCB: CMD+K means kcsuffix=release\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "kcsuffix=release", L_STR_LEN ("kcsuffix=release")); - } - return OC_INPUT_INTERNAL; - } - - // - // boot.efi also checks for CMD+X, but I have no idea what it is for. - // - - // - // boot.efi requires unrestricted NVRAM just for CMD+S+MINUS, and CMD+S - // does not work at all on T2 macs. For CMD+S we simulate T2 behaviour with - // DisableSingleUser Booter quirk if necessary. - // Ref: https://support.apple.com/HT201573 - // - if (HasCommand && HasKeyS) { - WantsZeroSlide = HasKeyMinus; - - if (WantsZeroSlide) { - CsrActiveConfig = 0; - CsrActiveConfigSize = sizeof (CsrActiveConfig); - Status = gRT->GetVariable ( - L"csr-active-config", - &gEfiAppleBootGuid, - NULL, - &CsrActiveConfigSize, - &CsrActiveConfig - ); - // - // FIXME: CMD+S+Minus behaves as CMD+S when "slide=0" is not supported - // by the SIP configuration. This might be an oversight, but is - // consistent with the boot.efi implementation. - // - WantsZeroSlide = !EFI_ERROR(Status) && (CsrActiveConfig & CSR_ALLOW_UNRESTRICTED_NVRAM) != 0; - } - - if (WantsZeroSlide) { - if (AsciiStrStr (Context->AppleBootArgs, "slide=0") == NULL) { - DEBUG ((DEBUG_INFO, "OCB: CMD+S+MINUS means slide=0\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "slide=0", L_STR_LEN ("slide=0")); - } - } else if (OcGetArgumentFromCmd (Context->AppleBootArgs, "-s", L_STR_LEN ("-s")) == NULL) { - DEBUG ((DEBUG_INFO, "OCB: CMD+S means -s\n")); - OcAppendArgumentToCmd (Context, Context->AppleBootArgs, "-s", L_STR_LEN ("-s")); - } - return OC_INPUT_INTERNAL; - } - } - - // - // Handle VoiceOver. - // - if ((Modifiers & (APPLE_MODIFIER_LEFT_COMMAND | APPLE_MODIFIER_RIGHT_COMMAND)) != 0 - && OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyF5)) { - OcKeyMapFlush (KeyMap, 0, TRUE); - return OC_INPUT_VOICE_OVER; - } - - // - // Handle reload menu. - // - if (OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyEscape) - || OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyZero)) { - OcKeyMapFlush (KeyMap, 0, TRUE); - return OC_INPUT_ABORTED; - } - - if (OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeySpaceBar)) { - OcKeyMapFlush (KeyMap, 0, TRUE); - return OC_INPUT_MORE; - } - - // - // Default update is desired for Ctrl+Index and Ctrl+Enter. - // - WantsDefault = Modifiers != 0 && (Modifiers & ~(APPLE_MODIFIER_LEFT_CONTROL | APPLE_MODIFIER_RIGHT_CONTROL)) == 0; - - // - // Check exact match on index strokes. - // - if ((Modifiers == 0 || WantsDefault) && NumKeys == 1) { - if (Keys[0] == AppleHidUsbKbUsageKeyEnter - || Keys[0] == AppleHidUsbKbUsageKeyReturn - || Keys[0] == AppleHidUsbKbUsageKeyPadEnter) { - if (WantsDefault && SetDefault != NULL) { - *SetDefault = TRUE; - } - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_CONTINUE; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyUpArrow) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_UP; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyDownArrow) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_DOWN; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyLeftArrow) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_LEFT; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyRightArrow) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_RIGHT; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyPgUp - || Keys[0] == AppleHidUsbKbUsageKeyHome) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_TOP; - } - - if (Keys[0] == AppleHidUsbKbUsageKeyPgDn - || Keys[0] == AppleHidUsbKbUsageKeyEnd) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_BOTTOM; - } - - // STATIC_ASSERT (AppleHidUsbKbUsageKeyF1 + 11 == AppleHidUsbKbUsageKeyF12, "Unexpected encoding"); - if (Keys[0] >= AppleHidUsbKbUsageKeyF1 && Keys[0] <= AppleHidUsbKbUsageKeyF12) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_FUNCTIONAL (Keys[0] - AppleHidUsbKbUsageKeyF1 + 1); - } - -// STATIC_ASSERT (AppleHidUsbKbUsageKeyF13 + 11 == AppleHidUsbKbUsageKeyF24, "Unexpected encoding"); - if (Keys[0] >= AppleHidUsbKbUsageKeyF13 && Keys[0] <= AppleHidUsbKbUsageKeyF24) { - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return OC_INPUT_FUNCTIONAL (Keys[0] - AppleHidUsbKbUsageKeyF13 + 13); - } - -// STATIC_ASSERT (AppleHidUsbKbUsageKeyOne + 8 == AppleHidUsbKbUsageKeyNine, "Unexpected encoding"); - for (KeyCode = AppleHidUsbKbUsageKeyOne; KeyCode <= AppleHidUsbKbUsageKeyNine; ++KeyCode) { - if (OcKeyMapHasKey (Keys, NumKeys, KeyCode)) { - if (WantsDefault && SetDefault != NULL) { - *SetDefault = TRUE; - } - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return (INTN) (KeyCode - AppleHidUsbKbUsageKeyOne); - } - } - -// STATIC_ASSERT (AppleHidUsbKbUsageKeyA + 25 == AppleHidUsbKbUsageKeyZ, "Unexpected encoding"); - for (KeyCode = AppleHidUsbKbUsageKeyA; KeyCode <= AppleHidUsbKbUsageKeyZ; ++KeyCode) { - if (OcKeyMapHasKey (Keys, NumKeys, KeyCode)) { - if (WantsDefault && SetDefault != NULL) { - *SetDefault = TRUE; - } - OcKeyMapFlush (KeyMap, Keys[0], TRUE); - return (INTN) (KeyCode - AppleHidUsbKbUsageKeyA + 9); - } - } - } - - if (NumKeys > 0) { - return OC_INPUT_INVALID; - } - - return OC_INPUT_TIMEOUT; -} - -INTN -OcWaitForAppleKeyIndex ( - IN OUT OC_PICKER_CONTEXT *Context, - IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, - IN UINTN Timeout, - OUT BOOLEAN *SetDefault OPTIONAL - ) -{ - INTN ResultingKey; - UINT64 CurrTime; - UINT64 EndTime; - - // - // These hotkeys are normally parsed by boot.efi, and they work just fine - // when ShowPicker is disabled. On some BSPs, however, they may fail badly - // when ShowPicker is enabled, and for this reason we support these hotkeys - // within picker itself. - // - - CurrTime = GetTimeInNanoSecond (GetPerformanceCounter ()); - EndTime = CurrTime + Timeout * 1000000ULL; - - if (SetDefault != NULL) { - *SetDefault = FALSE; - } - - while (Timeout == 0 || CurrTime == 0 || CurrTime < EndTime) { - CurrTime = GetTimeInNanoSecond (GetPerformanceCounter ()); - - ResultingKey = OcGetAppleKeyIndex (Context, KeyMap, SetDefault); - - // - // Requested for another iteration, handled Apple hotkey. - // - if (ResultingKey == OC_INPUT_INTERNAL) { - continue; - } - - // - // Abort the timeout when unrecognised keys are pressed. - // - if (Timeout != 0 && ResultingKey == OC_INPUT_INVALID) { - return OC_INPUT_INVALID; - } - - // - // Found key, return it. - // - if (ResultingKey != OC_INPUT_INVALID && ResultingKey != OC_INPUT_TIMEOUT) { - return ResultingKey; - } - - MicroSecondDelay (10); - } - - return OC_INPUT_TIMEOUT; -} diff --git a/Library/OcBootManagementLib/OcBootManagementLib.c b/Library/OcBootManagementLib/OcBootManagementLib.c deleted file mode 100644 index 182da78d8..000000000 --- a/Library/OcBootManagementLib/OcBootManagementLib.c +++ /dev/null @@ -1,764 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_STATUS -RunShowMenu ( - IN OC_BOOT_CONTEXT *BootContext, - OUT OC_BOOT_ENTRY **ChosenBootEntry - ) -{ - EFI_STATUS Status; - OC_BOOT_ENTRY **BootEntries; - UINT32 EntryReason; - - if (!BootContext->PickerContext->ApplePickerUnsupported - && BootContext->PickerContext->PickerMode == OcPickerModeApple) { - Status = OcRunAppleBootPicker (); - // - // This should not return on success. - // - DEBUG ((DEBUG_INFO, "OCB: Apple BootPicker failed on error - %r, fallback to builtin\n", Status)); - BootContext->PickerContext->ApplePickerUnsupported = TRUE; - } - - BootEntries = OcEnumerateEntries (BootContext); - if (BootEntries == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // We are not allowed to have no default entry. - // However, if default entry is a tool or a system entry, never autoboot it. - // - if (BootContext->DefaultEntry == NULL) { - BootContext->DefaultEntry = BootEntries[0]; - BootContext->PickerContext->TimeoutSeconds = 0; - } - - // - // Ensure that picker entry reason is set as it can be read by boot.efi. - // - EntryReason = ApplePickerEntryReasonUnknown; - gRT->SetVariable ( - APPLE_PICKER_ENTRY_REASON_VARIABLE_NAME, - &gEfiAppleNvramGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (EntryReason), - &EntryReason - ); - - Status = BootContext->PickerContext->ShowMenu ( - BootContext, - BootEntries, - ChosenBootEntry - ); - FreePool (BootEntries); - - return Status; -} - -EFI_STATUS -EFIAPI -OcShowSimpleBootMenu ( - IN OC_BOOT_CONTEXT *BootContext, - IN OC_BOOT_ENTRY **BootEntries, - OUT OC_BOOT_ENTRY **ChosenBootEntry - ) -{ - APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap; - UINTN Index; - UINTN Length; - INTN KeyIndex; - INTN ChosenEntry; - CHAR16 Code[2]; - UINT32 TimeOutSeconds; - UINT32 Count; - BOOLEAN SetDefault; - BOOLEAN PlayedOnce; - BOOLEAN PlayChosen; - - ChosenEntry = -1; - Code[1] = '\0'; - - TimeOutSeconds = BootContext->PickerContext->TimeoutSeconds; - ASSERT (BootContext->DefaultEntry != NULL); - - PlayedOnce = FALSE; - PlayChosen = FALSE; - - KeyMap = OcAppleKeyMapInstallProtocols (FALSE); - if (KeyMap == NULL) { - DEBUG ((DEBUG_ERROR, "OCB: Missing AppleKeyMapAggregator\n")); - return EFI_UNSUPPORTED; - } - - Count = (UINT32) BootContext->BootEntryCount; - - if (Count != MIN (Count, OC_INPUT_MAX)) { - DEBUG ((DEBUG_WARN, "OCB: Cannot display all entries in the menu!\n")); - } - - OcConsoleControlSetMode (EfiConsoleControlScreenText); - gST->ConOut->EnableCursor (gST->ConOut, FALSE); - - if (BootContext->PickerContext->ConsoleAttributes != 0) { - gST->ConOut->SetAttribute (gST->ConOut, BootContext->PickerContext->ConsoleAttributes & 0x7FU); - } - - // - // Extension for OpenCore direct text render for faster redraw with custom background. - // - gST->ConOut->ClearScreen (gST->ConOut); - gST->ConOut->TestString (gST->ConOut, OC_CONSOLE_MARK_CONTROLLED); - - while (TRUE) { - gST->ConOut->ClearScreen (gST->ConOut); - gST->ConOut->OutputString (gST->ConOut, OC_MENU_BOOT_MENU); - - if (BootContext->PickerContext->TitleSuffix != NULL) { - Length = AsciiStrLen (BootContext->PickerContext->TitleSuffix); - gST->ConOut->OutputString (gST->ConOut, L" ("); - for (Index = 0; Index < Length; ++Index) { - Code[0] = BootContext->PickerContext->TitleSuffix[Index]; - gST->ConOut->OutputString (gST->ConOut, Code); - } - gST->ConOut->OutputString (gST->ConOut, L")"); - } - - gST->ConOut->OutputString (gST->ConOut, L"\r\n\r\n"); - - for (Index = 0; Index < MIN (Count, OC_INPUT_MAX); ++Index) { - if (TimeOutSeconds > 0 && BootContext->DefaultEntry->EntryIndex - 1 == Index) { - gST->ConOut->OutputString (gST->ConOut, L"* "); - } else if (ChosenEntry >= 0 && (UINTN) ChosenEntry == Index) { - gST->ConOut->OutputString (gST->ConOut, L"> "); - } else { - gST->ConOut->OutputString (gST->ConOut, L" "); - } - - Code[0] = OC_INPUT_STR[Index]; - gST->ConOut->OutputString (gST->ConOut, Code); - gST->ConOut->OutputString (gST->ConOut, L". "); - gST->ConOut->OutputString (gST->ConOut, BootEntries[Index]->Name); - if (BootEntries[Index]->IsFolder) { - gST->ConOut->OutputString (gST->ConOut, OC_MENU_DISK_IMAGE); - } - if (BootEntries[Index]->IsExternal) { - gST->ConOut->OutputString (gST->ConOut, OC_MENU_EXTERNAL); - } - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - } - - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - gST->ConOut->OutputString (gST->ConOut, OC_MENU_CHOOSE_OS); - - if (!PlayedOnce && BootContext->PickerContext->PickerAudioAssist) { - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileChooseOS, FALSE); - for (Index = 0; Index < Count; ++Index) { - OcPlayAudioEntry (BootContext->PickerContext, BootEntries[Index]); - if (TimeOutSeconds > 0 && BootContext->DefaultEntry->EntryIndex - 1 == Index) { - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileDefault, FALSE); - } - } - OcPlayAudioBeep ( - BootContext->PickerContext, - OC_VOICE_OVER_SIGNALS_NORMAL, - OC_VOICE_OVER_SIGNAL_NORMAL_MS, - OC_VOICE_OVER_SILENCE_NORMAL_MS - ); - PlayedOnce = TRUE; - } - - while (TRUE) { - // - // Pronounce entry name only after N ms of idleness. - // - KeyIndex = OcWaitForAppleKeyIndex ( - BootContext->PickerContext, - KeyMap, - PlayChosen ? OC_VOICE_OVER_IDLE_TIMEOUT_MS : TimeOutSeconds * 1000, - &SetDefault - ); - - if (PlayChosen && KeyIndex == OC_INPUT_TIMEOUT) { - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileSelected, FALSE); - OcPlayAudioEntry (BootContext->PickerContext, BootEntries[ChosenEntry]); - PlayChosen = FALSE; - continue; - } else if (KeyIndex == OC_INPUT_TIMEOUT) { - *ChosenBootEntry = BootEntries[BootContext->DefaultEntry->EntryIndex - 1]; - gST->ConOut->OutputString (gST->ConOut, OC_MENU_TIMEOUT); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileTimeout, FALSE); - return EFI_SUCCESS; - } else if (KeyIndex == OC_INPUT_CONTINUE) { - if (ChosenEntry >= 0) { - *ChosenBootEntry = BootEntries[(UINTN) ChosenEntry]; - } else { - *ChosenBootEntry = BootContext->DefaultEntry; - } - (*ChosenBootEntry)->SetDefault = SetDefault; - gST->ConOut->OutputString (gST->ConOut, OC_MENU_OK); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - return EFI_SUCCESS; - } else if (KeyIndex == OC_INPUT_ABORTED) { - gST->ConOut->OutputString (gST->ConOut, OC_MENU_RELOADING); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileReloading, FALSE); - return EFI_ABORTED; - } else if (KeyIndex == OC_INPUT_MORE && BootContext->PickerContext->HideAuxiliary) { - gST->ConOut->OutputString (gST->ConOut, OC_MENU_SHOW_AUXILIARY); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileShowAuxiliary, FALSE); - BootContext->PickerContext->HideAuxiliary = FALSE; - return EFI_ABORTED; - } else if (KeyIndex == OC_INPUT_UP) { - if (TimeOutSeconds > 0) { - ChosenEntry = (INTN) (BootContext->DefaultEntry->EntryIndex - 1); - } - if (ChosenEntry < 0) { - ChosenEntry = 0; - } else if (ChosenEntry == 0) { - ChosenEntry = (INTN) (MIN (Count, OC_INPUT_MAX) - 1); - } else { - --ChosenEntry; - } - TimeOutSeconds = 0; - if (BootContext->PickerContext->PickerAudioAssist) { - PlayChosen = TRUE; - } - break; - } else if (KeyIndex == OC_INPUT_DOWN) { - if (TimeOutSeconds > 0) { - ChosenEntry = (INTN) (BootContext->DefaultEntry->EntryIndex - 1); - } - if (ChosenEntry < 0) { - ChosenEntry = 0; - } else if (ChosenEntry == (INTN) (MIN (Count, OC_INPUT_MAX) - 1)) { - ChosenEntry = 0; - } else { - ++ChosenEntry; - } - TimeOutSeconds = 0; - if (BootContext->PickerContext->PickerAudioAssist) { - PlayChosen = TRUE; - } - break; - } else if (KeyIndex == OC_INPUT_TOP || KeyIndex == OC_INPUT_LEFT) { - ChosenEntry = 0; - TimeOutSeconds = 0; - if (BootContext->PickerContext->PickerAudioAssist) { - PlayChosen = TRUE; - } - break; - } else if (KeyIndex == OC_INPUT_BOTTOM || KeyIndex == OC_INPUT_RIGHT) { - ChosenEntry = (INTN) (MIN (Count, OC_INPUT_MAX) - 1); - TimeOutSeconds = 0; - if (BootContext->PickerContext->PickerAudioAssist) { - PlayChosen = TRUE; - } - break; - } else if (KeyIndex == OC_INPUT_VOICE_OVER) { - OcToggleVoiceOver (BootContext->PickerContext, 0); - break; - } else if (KeyIndex != OC_INPUT_INVALID && KeyIndex >= 0 && (UINTN)KeyIndex < Count) { - *ChosenBootEntry = BootEntries[KeyIndex]; - (*ChosenBootEntry)->SetDefault = SetDefault; - Code[0] = OC_INPUT_STR[KeyIndex]; - gST->ConOut->OutputString (gST->ConOut, Code); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - return EFI_SUCCESS; - } - - if (TimeOutSeconds > 0) { - OcPlayAudioFile (BootContext->PickerContext, OcVoiceOverAudioFileAbortTimeout, FALSE); - TimeOutSeconds = 0; - break; - } - } - } - - ASSERT (FALSE); -} - -EFI_STATUS -EFIAPI -OcShowSimplePasswordRequest ( - IN OC_PICKER_CONTEXT *Context, - IN OC_PRIVILEGE_LEVEL Level - ) -{ - OC_PRIVILEGE_CONTEXT *Privilege; - - BOOLEAN Result; - - UINT8 Password[32]; - UINT32 PwIndex; - - UINT8 Index; - EFI_STATUS Status; - EFI_INPUT_KEY Key; - - Privilege = Context->PrivilegeContext; - - if (Privilege == NULL || Privilege->CurrentLevel >= Level) { - return EFI_SUCCESS; - } - - OcConsoleControlSetMode (EfiConsoleControlScreenText); - gST->ConOut->EnableCursor (gST->ConOut, FALSE); - gST->ConOut->ClearScreen (gST->ConOut); - gST->ConOut->TestString (gST->ConOut, OC_CONSOLE_MARK_CONTROLLED); - - for (Index = 0; Index < 3; ++Index) { - PwIndex = 0; - // - // Skip previously pressed characters. - // - do { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - } while (!EFI_ERROR(Status)); - - gST->ConOut->OutputString (gST->ConOut, OC_MENU_PASSWORD_REQUEST); - OcPlayAudioFile (Context, OcVoiceOverAudioFileEnterPassword, TRUE); - - while (TRUE) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - if (Status == EFI_NOT_READY) { - continue; - } else if (EFI_ERROR(Status)) { - gST->ConOut->ClearScreen (gST->ConOut); - SecureZeroMem (Password, PwIndex); - SecureZeroMem (&Key.UnicodeChar, sizeof (Key.UnicodeChar)); - - DEBUG ((DEBUG_ERROR, "Input device error\r\n")); - OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_HWERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - return EFI_ABORTED; - } - - // - // TODO: We should really switch to Apple input here. - // - if (Key.ScanCode == SCAN_F5) { - OcToggleVoiceOver (Context, OcVoiceOverAudioFileEnterPassword); - } - - if (Key.ScanCode == SCAN_ESC) { - gST->ConOut->ClearScreen (gST->ConOut); - SecureZeroMem (Password, PwIndex); - // - // ESC aborts the input. - // - return EFI_ABORTED; - } else if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { - gST->ConOut->ClearScreen (gST->ConOut); - // - // RETURN finalizes the input. - // - break; - } else if (Key.UnicodeChar == CHAR_BACKSPACE) { - // - // Delete the last entered character, if such exists. - // - if (PwIndex != 0) { - --PwIndex; - Password[PwIndex] = 0; - // - // Overwrite current character with a space. - // - gST->ConOut->SetCursorPosition ( - gST->ConOut, - gST->ConOut->Mode->CursorColumn - 1, - gST->ConOut->Mode->CursorRow - ); - gST->ConOut->OutputString (gST->ConOut, L" "); - gST->ConOut->SetCursorPosition ( - gST->ConOut, - gST->ConOut->Mode->CursorColumn - 1, - gST->ConOut->Mode->CursorRow - ); - } - - OcPlayAudioFile (Context, AppleVoiceOverAudioFileBeep, TRUE); - continue; - } else if (Key.UnicodeChar == CHAR_NULL - || (UINT8)Key.UnicodeChar != Key.UnicodeChar) { - // - // Only ASCII characters are supported. - // - OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_ERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - continue; - } - - if (PwIndex == ARRAY_SIZE (Password)) { - OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_ERROR, - OC_VOICE_OVER_SIGNAL_ERROR_MS, - OC_VOICE_OVER_SILENCE_ERROR_MS - ); - continue; - } - - gST->ConOut->OutputString (gST->ConOut, L"*"); - Password[PwIndex] = (UINT8)Key.UnicodeChar; - OcPlayAudioFile (Context, AppleVoiceOverAudioFileBeep, TRUE); - ++PwIndex; - } - - Result = OcVerifyPasswordSha512 ( - Password, - PwIndex, - Privilege->Salt, - Privilege->SaltSize, - Privilege->Hash - ); - - SecureZeroMem (Password, PwIndex); - - if (Result) { - gST->ConOut->ClearScreen (gST->ConOut); - Privilege->CurrentLevel = Level; - OcPlayAudioFile (Context, OcVoiceOverAudioFilePasswordAccepted, TRUE); - return EFI_SUCCESS; - } else { - OcPlayAudioFile (Context, OcVoiceOverAudioFilePasswordIncorrect, TRUE); - } - } - - gST->ConOut->ClearScreen (gST->ConOut); - gST->ConOut->OutputString (gST->ConOut, OC_MENU_PASSWORD_RETRY_LIMIT); - gST->ConOut->OutputString (gST->ConOut, L"\r\n"); - OcPlayAudioFile (Context, OcVoiceOverAudioFilePasswordRetryLimit, TRUE); - DEBUG ((DEBUG_WARN, "OCB: User failed to verify password for 3 times running\n")); - - gBS->Stall (5000000); - gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); - return EFI_ACCESS_DENIED; -} - -EFI_STATUS -OcRunBootPicker ( - IN OC_PICKER_CONTEXT *Context - ) -{ - EFI_STATUS Status; - APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap; - OC_BOOT_CONTEXT *BootContext; - OC_BOOT_ENTRY *Chosen; - BOOLEAN SaidWelcome; - - SaidWelcome = FALSE; - - // - // Reset NVRAM right away if requested by a key combination. - // This function should not return under normal conditions. - // - if (Context->PickerCommand == OcPickerResetNvram) { - return InternalSystemActionResetNvram (); - } - - KeyMap = OcAppleKeyMapInstallProtocols (FALSE); - if (KeyMap == NULL) { - DEBUG ((DEBUG_ERROR, "OCB: AppleKeyMap locate failure\n")); - return EFI_NOT_FOUND; - } - - // - // This one is handled as is for Apple BootPicker for now. - // - if (Context->PickerCommand != OcPickerDefault) { - Status = Context->RequestPrivilege ( - Context, - OcPrivilegeAuthorized - ); - if (EFI_ERROR(Status)) { - if (Status != EFI_ABORTED) { - ASSERT (FALSE); - return Status; - } - - Context->PickerCommand = OcPickerDefault; - } - } - - if (Context->PickerCommand == OcPickerShowPicker && Context->PickerMode == OcPickerModeApple) { - Status = OcRunAppleBootPicker (); - DEBUG ((DEBUG_INFO, "OCB: Apple BootPicker failed - %r, fallback to builtin\n", Status)); - Context->ApplePickerUnsupported = TRUE; - } - - if (Context->PickerCommand != OcPickerShowPicker && Context->PickerCommand != OcPickerDefault) { - // - // We cannot ignore auxiliary entries for all other modes. - // - Context->HideAuxiliary = FALSE; - } - - while (TRUE) { - // - // Turbo-boost scanning when bypassing picker. - // - if (Context->PickerCommand == OcPickerDefault) { - BootContext = OcScanForDefaultBootEntry (Context); - } else { - ASSERT ( - Context->PickerCommand == OcPickerShowPicker - || Context->PickerCommand == OcPickerBootApple - || Context->PickerCommand == OcPickerBootAppleRecovery - ); - - BootContext = OcScanForBootEntries (Context); - } - - // - // We have no entries at all or have auxiliary entries. - // Fallback to showing menu in the latter case. - // - if (BootContext == NULL) { - if (Context->HideAuxiliary) { - DEBUG ((DEBUG_WARN, "OCB: System has no boot entries, retrying with auxiliary\n")); - Context->PickerCommand = OcPickerShowPicker; - Context->HideAuxiliary = FALSE; - continue; - } - - DEBUG ((DEBUG_WARN, "OCB: System has no boot entries\n")); - return EFI_NOT_FOUND; - } - - if (Context->PickerCommand == OcPickerShowPicker) { - DEBUG (( - DEBUG_INFO, - "OCB: Showing menu... %a\n", - Context->PollAppleHotKeys ? "(polling hotkeys)" : "" - )); - - if (!SaidWelcome) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileWelcome, FALSE); - SaidWelcome = TRUE; - } - - Status = RunShowMenu (BootContext, &Chosen); - - if (EFI_ERROR(Status) && Status != EFI_ABORTED) { - DEBUG ((DEBUG_ERROR, "OCB: ShowMenu failed - %r\n", Status)); - OcFreeBootContext (BootContext); - return Status; - } - } else if (BootContext->DefaultEntry != NULL) { - Chosen = BootContext->DefaultEntry; - Status = EFI_SUCCESS; - } else { - // - // This can only be failed macOS or macOS recovery boot. - // We may actually not rescan here. - // - ASSERT (Context->PickerCommand == OcPickerBootApple || Context->PickerCommand == OcPickerBootAppleRecovery); - DEBUG ((DEBUG_INFO, "OCB: System has no default boot entry, showing menu\n")); - Context->PickerCommand = OcPickerShowPicker; - OcFreeBootContext (BootContext); - continue; - } - - ASSERT (!EFI_ERROR(Status) || Status == EFI_ABORTED); - - Context->TimeoutSeconds = 0; - - if (!EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Should boot from %u. %s (T:%d|F:%d|G:%d|E:%d|DEF:%d)\n", - Chosen->EntryIndex, - Chosen->Name, - Chosen->Type, - Chosen->IsFolder, - Chosen->IsGeneric, - Chosen->IsExternal, - Chosen->SetDefault - )); - - if (Context->PickerCommand == OcPickerShowPicker) { - ASSERT (Chosen->EntryIndex > 0); - - if (Chosen->SetDefault) { - if (Context->PickerCommand == OcPickerShowPicker) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileSelected, FALSE); - OcPlayAudioFile (Context, OcVoiceOverAudioFileDefault, FALSE); - OcPlayAudioEntry (Context, Chosen); - } - Status = OcSetDefaultBootEntry (Context, Chosen); - DEBUG ((DEBUG_INFO, "OCB: Setting default - %r\n", Status)); - } - - // - // Do screen clearing for builtin menu here, so that it is possible to see the action. - // TODO: Probably remove that completely. - // - if (Context->ShowMenu == OcShowSimpleBootMenu) { - // - // Clear screen from picker contents before loading the entry. - // - gST->ConOut->ClearScreen (gST->ConOut); - gST->ConOut->TestString (gST->ConOut, OC_CONSOLE_MARK_UNCONTROLLED); - } - - // - // Voice chosen information. - // - OcPlayAudioFile (Context, OcVoiceOverAudioFileLoading, FALSE); - Status = OcPlayAudioEntry (Context, Chosen); - if (EFI_ERROR(Status)) { - OcPlayAudioBeep ( - Context, - OC_VOICE_OVER_SIGNALS_PASSWORD_OK, - OC_VOICE_OVER_SIGNAL_NORMAL_MS, - OC_VOICE_OVER_SILENCE_NORMAL_MS - ); - } - } - - Status = OcLoadBootEntry ( - Context, - Chosen, - gImageHandle - ); - - // - // Do not wait on successful return code. - // - if (EFI_ERROR(Status)) { - OcPlayAudioFile (Context, OcVoiceOverAudioFileExecutionFailure, TRUE); - gBS->Stall (SECONDS_TO_MICROSECONDS (3)); - // - // Show picker on first failure. - // - Context->PickerCommand = OcPickerShowPicker; - } else { - OcPlayAudioFile (Context, OcVoiceOverAudioFileExecutionSuccessful, FALSE); - } - - // - // Ensure that we flush all pressed keys after the application. - // This resolves the problem of application-pressed keys being used to control the menu. - // - OcKeyMapFlush (KeyMap, 0, TRUE); - } - - OcFreeBootContext (BootContext); - } -} - -EFI_STATUS -OcRunAppleBootPicker ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HANDLE NewHandle; - EFI_DEVICE_PATH_PROTOCOL *Dp; - APPLE_PICKER_ENTRY_REASON PickerEntryReason; - - DEBUG ((DEBUG_INFO, "OCB: OcRunAppleBootPicker attempting to find...\n")); - - Dp = CreateFvFileDevicePath (&gAppleBootPickerFileGuid); - if (Dp != NULL) { - DEBUG ((DEBUG_INFO, "OCB: OcRunAppleBootPicker attempting to load...\n")); - NewHandle = NULL; - Status = gBS->LoadImage ( - FALSE, - gImageHandle, - Dp, - NULL, - 0, - &NewHandle - ); - if (EFI_ERROR(Status)) { - Status = EFI_INVALID_PARAMETER; - } - } else { - Status = EFI_NOT_FOUND; - } - - if (!EFI_ERROR(Status)) { - PickerEntryReason = ApplePickerEntryReasonUnknown; - Status = gRT->SetVariable ( - APPLE_PICKER_ENTRY_REASON_VARIABLE_NAME, - &gEfiAppleNvramGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (PickerEntryReason), - &PickerEntryReason - ); - - DEBUG ((DEBUG_INFO, "OCB: OcRunAppleBootPicker attempting to start with var %r...\n", Status)); - Status = gBS->StartImage ( - NewHandle, - NULL, - NULL - ); - - if (EFI_ERROR(Status)) { - Status = EFI_UNSUPPORTED; - } - } - - return Status; -} diff --git a/Library/OcBootManagementLib/OcBootManagementLib.inf b/Library/OcBootManagementLib/OcBootManagementLib.inf deleted file mode 100644 index 1141f9c9e..000000000 --- a/Library/OcBootManagementLib/OcBootManagementLib.inf +++ /dev/null @@ -1,114 +0,0 @@ -## @file -# -# Component description file for the library producing the Apple Device property protocol. -# -# Copyright (C) 2019, vit9696. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcBootManagementLib - FILE_GUID = A28FEC6F-DD5C-4D8D-9351-50D9A2047634 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcBootManagementLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - AppleHibernate.c - ApplePanic.c - BootArguments.c - BootAudio.c - BootEntryInfo.c - BootEntryManagement.c - BootManagementInternal.h - DefaultEntryChoice.c - DmgBootSupport.c - HotKeySupport.c - PolicyManagement.c - OcBootManagementLib.c - VariableManagement.c - ../../Include/Library/OcBootManagementLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[Guids] - gAppleApfsContainerInfoGuid ## SOMETIMES_CONSUMES - gAppleApfsVolumeInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedSystemFileInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedSystemFolderInfoGuid ## SOMETIMES_CONSUMES - gAppleBlessedOsxFolderInfoGuid ## SOMETIMES_CONSUMES - gEfiFileInfoGuid ## SOMETIMES_CONSUMES - gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES - gEfiPartTypeSystemPartGuid ## SOMETIMES_CONSUMES - gAppleApfsPartitionTypeGuid ## SOMETIMES_CONSUMES - gEfiAppleBootGuid ## SOMETIMES_CONSUMES - gAppleHfsPartitionTypeGuid ## SOMETIMES_CONSUMES - gAppleHfsBootPartitionTypeGuid ## SOMETIMES_CONSUMES - gAppleLegacyLoadAppFileGuid ## SOMETIMES_CONSUMES - gEfiAppleNvramGuid ## SOMETIMES_CONSUMES - gAppleCoreStorageVariableGuid ## SOMETIMES_CONSUMES - gAppleTamperResistantBootVariableGuid ## SOMETIMES_CONSUMES - gAppleWirelessNetworkVariableGuid ## SOMETIMES_CONSUMES - gApplePersonalizationVariableGuid ## SOMETIMES_CONSUMES - gAppleNetbootVariableGuid ## SOMETIMES_CONSUMES - gAppleSecureBootVariableGuid ## SOMETIMES_CONSUMES - gAppleTamperResistantBootSecureVariableGuid ## SOMETIMES_CONSUMES - gAppleTamperResistantBootEfiUserVariableGuid ## SOMETIMES_CONSUMES - gOcVendorVariableGuid ## SOMETIMES_CONSUMES - gOcReadOnlyVariableGuid ## SOMETIMES_CONSUMES - gOcWriteOnlyVariableGuid ## SOMETIMES_CONSUMES - gAppleBootPickerFileGuid ## SOMETIMES_CONSUMES - gMicrosoftVariableGuid ## SOMETIMES_CONSUMES - -[Protocols] - gAppleBootPolicyProtocolGuid ## PRODUCES - gAppleKeyStateProtocolGuid ## SOMETIMES_CONSUMES - gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiUsbIoProtocolGuid ## SOMETIMES_CONSUMES - gOcFirmwareRuntimeProtocolGuid ## SOMETIMES_CONSUMES - gOcAudioProtocolGuid ## SOMETIMES_CONSUMES - gAppleBeepGenProtocolGuid ## SOMETIMES_CONSUMES - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - MemoryAllocationLib - PrintLib - UefiBootServicesTableLib - OcAppleBootPolicyLib - OcAppleChunklistLib - OcAppleDiskImageLib - OcAppleKeyMapLib - OcAppleKeysLib - OcConsoleLib - OcCryptoLib - OcDevicePathLib - OcGuardLib - OcFileLib - OcRtcLib - OcXmlLib - TimerLib - FileHandleLib diff --git a/Library/OcBootManagementLib/PolicyManagement.c b/Library/OcBootManagementLib/PolicyManagement.c deleted file mode 100644 index 6d0e899f1..000000000 --- a/Library/OcBootManagementLib/PolicyManagement.c +++ /dev/null @@ -1,399 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "BootManagementInternal.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -UINT32 -OcGetDevicePolicyType ( - IN EFI_HANDLE Handle, - OUT BOOLEAN *External OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker; - ACPI_HID_DEVICE_PATH *Acpi; - UINT8 SubType; - - if (External != NULL) { - *External = FALSE; - } - - Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath); - if (EFI_ERROR(Status)) { - return 0; - } - - // - // FIXME: This code does not take care of RamDisk exception as specified per - // https://github.com/acidanthera/bugtracker/issues/335. - // Currently we do not need it, but in future we may. - // - - DevicePathWalker = DevicePath; - while (!IsDevicePathEnd (DevicePathWalker)) { - if (DevicePathType (DevicePathWalker) == MESSAGING_DEVICE_PATH) { - SubType = DevicePathSubType (DevicePathWalker); - switch (SubType) { - case MSG_SATA_DP: - return OC_SCAN_ALLOW_DEVICE_SATA; - case MSG_SASEX_DP: - return OC_SCAN_ALLOW_DEVICE_SASEX; - case MSG_SCSI_DP: - return OC_SCAN_ALLOW_DEVICE_SCSI; - case MSG_NVME_NAMESPACE_DP: - return OC_SCAN_ALLOW_DEVICE_NVME; - case MSG_ATAPI_DP: - if (External != NULL) { - *External = TRUE; - } - return OC_SCAN_ALLOW_DEVICE_ATAPI; - case MSG_USB_DP: - if (External != NULL) { - *External = TRUE; - } - return OC_SCAN_ALLOW_DEVICE_USB; - case MSG_1394_DP: - if (External != NULL) { - *External = TRUE; - } - return OC_SCAN_ALLOW_DEVICE_FIREWIRE; - case MSG_SD_DP: - case MSG_EMMC_DP: - if (External != NULL) { - *External = TRUE; - } - return OC_SCAN_ALLOW_DEVICE_SDCARD; - } - - // - // We do not have good protection against device tunneling. - // These things must be considered: - // - Thunderbolt 2 PCI-e pass-through - // - Thunderbolt 3 PCI-e pass-through (Type-C, may be different from 2) - // - FireWire devices - // For now we hope that first messaging type protects us, and all - // subsequent messaging types are tunneled. - // - - break; - } - - DevicePathWalker = NextDevicePathNode (DevicePathWalker); - } - - DevicePathWalker = DevicePath; - while (!IsDevicePathEnd (DevicePathWalker)) { - if (DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) { - return OC_SCAN_ALLOW_DEVICE_PCI; - } - - if (DevicePathType (DevicePathWalker) == ACPI_DEVICE_PATH) { - Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathWalker; - if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST - && EISA_ID_TO_NUM (Acpi->HID) == 0x0A03) { - // - // Allow PciRoot. - // - DevicePathWalker = NextDevicePathNode (DevicePathWalker); - continue; - } - } else if (DevicePathType (DevicePathWalker) == HARDWARE_DEVICE_PATH - && DevicePathSubType (DevicePathWalker) == HW_PCI_DP) { - // - // Allow Pci. - // - DevicePathWalker = NextDevicePathNode (DevicePathWalker); - continue; - } - - // - // Forbid everything else. - // - break; - } - - return 0; -} - -/** - Microsoft partitions. - https://docs.microsoft.com/ru-ru/windows/win32/api/vds/ns-vds-create_partition_parameters -**/ -EFI_GUID mMsftBasicDataPartitionTypeGuid = { - 0xEBD0A0A2, 0xB9E5, 0x4433, {0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7} -}; - -EFI_GUID mMsftReservedPartitionTypeGuid = { - 0xE3C9E316, 0x0B5C, 0x4DB8, {0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE} -}; - -EFI_GUID mMsftRecoveryPartitionTypeGuid = { - 0xDE94BBA4, 0x06D1, 0x4D40, {0xA1, 0x6A, 0xBF, 0xD5, 0x01, 0x79, 0xD6, 0xAC} -}; - -/** - Linux partitions. - https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs -**/ -EFI_GUID mLinuxRootX86PartitionTypeGuid = { - 0x44479540, 0xF297, 0x41B2, {0x9A, 0xF7, 0xD1, 0x31, 0xD5, 0xF0, 0x45, 0x8A} -}; - -EFI_GUID mLinuxRootX8664PartitionTypeGuid = { - 0x4F68BCE3, 0xE8CD, 0x4DB1, {0x96, 0xE7, 0xFB, 0xCA, 0xF9, 0x84, 0xB7, 0x09} -}; - -UINT32 -OcGetFileSystemPolicyType ( - IN EFI_HANDLE Handle - ) -{ - CONST EFI_PARTITION_ENTRY *PartitionEntry; - - PartitionEntry = OcGetGptPartitionEntry (Handle); - - if (PartitionEntry == NULL) { - DEBUG ((DEBUG_INFO, "OCB: Missing partition info for %p\n", Handle)); - return 0; - } - - if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleApfsPartitionTypeGuid)) { - return OC_SCAN_ALLOW_FS_APFS; - } - - if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) { - return OC_SCAN_ALLOW_FS_ESP; - } - - // - // Unsure whether these two should be separate, likely not. - // - if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleHfsPartitionTypeGuid) - || CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleHfsBootPartitionTypeGuid)) { - return OC_SCAN_ALLOW_FS_HFS; - } - - if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &mMsftBasicDataPartitionTypeGuid)) { - return OC_SCAN_ALLOW_FS_NTFS; - } - - if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &mLinuxRootX86PartitionTypeGuid) - || CompareGuid (&PartitionEntry->PartitionTypeGUID, &mLinuxRootX8664PartitionTypeGuid)) { - return OC_SCAN_ALLOW_FS_EXT; - } - - return 0; -} - -EFI_STATUS -InternalCheckScanPolicy ( - IN EFI_HANDLE Handle, - IN UINT32 Policy, - OUT BOOLEAN *External OPTIONAL - ) -{ - UINT32 DevicePolicy; - UINT32 FileSystemPolicy; - - // - // Always request policy type due to external checks. - // - DevicePolicy = OcGetDevicePolicyType (Handle, External); - if ((Policy & OC_SCAN_DEVICE_LOCK) != 0 && (Policy & DevicePolicy) == 0) { - DEBUG ((DEBUG_INFO, "OCB: Invalid device policy (%x/%x) for %p\n", DevicePolicy, Policy, Handle)); - return EFI_SECURITY_VIOLATION; - } - - if ((Policy & OC_SCAN_FILE_SYSTEM_LOCK) != 0) { - FileSystemPolicy = OcGetFileSystemPolicyType (Handle); - - if ((Policy & FileSystemPolicy) == 0) { - DEBUG ((DEBUG_INFO, "OCB: Invalid file system policy (%x/%x) for %p\n", FileSystemPolicy, Policy, Handle)); - return EFI_SECURITY_VIOLATION; - } - } - - return EFI_SUCCESS; -} - -OC_BOOT_ENTRY_TYPE -OcGetBootDevicePathType ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT BOOLEAN *IsFolder OPTIONAL, - OUT BOOLEAN *IsGeneric OPTIONAL - ) -{ - EFI_DEVICE_PATH_PROTOCOL *CurrNode; - CHAR16 *Path; - UINTN PathSize; - UINTN PathLen; - UINTN RestLen; - UINTN Index; - - Path = NULL; - - if (IsGeneric != NULL) { - *IsGeneric = FALSE; - } - - if (IsFolder != NULL) { - *IsFolder = FALSE; - } - - for (CurrNode = DevicePath; !IsDevicePathEnd (CurrNode); CurrNode = NextDevicePathNode (CurrNode)) { - if ((DevicePathType (CurrNode) == MEDIA_DEVICE_PATH) - && (DevicePathSubType (CurrNode) == MEDIA_FILEPATH_DP)) { - // - // Perform copying of all the underlying nodes due to potential unaligned access. - // - PathSize = OcFileDevicePathFullNameSize (CurrNode); - if (PathSize == 0) { - return OC_BOOT_UNKNOWN; - } - - Path = AllocatePool (PathSize); - if (Path == NULL) { - return OC_BOOT_UNKNOWN; - } - - OcFileDevicePathFullName (Path, (FILEPATH_DEVICE_PATH *) CurrNode, PathSize); - PathLen = StrLen (Path); - break; - } - } - - if (Path == NULL) { - return OC_BOOT_UNKNOWN; - } - - // - // Use the trailing character to determine folder. - // - if (IsFolder != NULL && Path[PathLen - 1] == L'\\') { - *IsFolder = TRUE; - } - - // - // Detect macOS recovery by com.apple.recovery.boot in the bootloader path. - // - if (OcStrStrLength (Path, PathLen, L"com.apple.recovery.boot", L_STR_LEN (L"com.apple.recovery.boot")) != NULL) { - FreePool (Path); - return OC_BOOT_APPLE_RECOVERY; - } - - if (OcStrStrLength (Path, PathLen, L"EFI\\APPLE", L_STR_LEN (L"EFI\\APPLE")) != NULL) { - FreePool (Path); - return OC_BOOT_APPLE_FW_UPDATE; - } - - // - // Detect macOS by boot.efi in the bootloader name. - // Detect macOS Time Machine by tmbootpicker.efi in the bootloader name. - // - STATIC CONST CHAR16 *Bootloaders[] = { - L"boot.efi", - L"tmbootpicker.efi", - L"bootmgfw.efi" - }; - - STATIC CONST UINTN BootloaderLengths[] = { - L_STR_LEN (L"boot.efi"), - L_STR_LEN (L"tmbootpicker.efi"), - L_STR_LEN (L"bootmgfw.efi") - }; - - STATIC CONST OC_BOOT_ENTRY_TYPE BootloaderTypes[] = { - OC_BOOT_APPLE_OS, - OC_BOOT_APPLE_TIME_MACHINE, - OC_BOOT_WINDOWS - }; - - for (Index = 0; Index < ARRAY_SIZE (Bootloaders); ++Index) { - if (PathLen < BootloaderLengths[Index]) { - continue; - } - - RestLen = PathLen - BootloaderLengths[Index]; - if ((RestLen == 0 || Path[RestLen - 1] == L'\\') - && OcStrniCmp (&Path[RestLen], Bootloaders[Index], BootloaderLengths[Index]) == 0) { - FreePool (Path); - return BootloaderTypes[Index]; - } - } - - CONST CHAR16 *GenericBootloader = &EFI_REMOVABLE_MEDIA_FILE_NAME[L_STR_LEN (L"\\EFI\\BOOT\\")]; - CONST UINTN GenericBootloaderLength = L_STR_LEN (EFI_REMOVABLE_MEDIA_FILE_NAME) - L_STR_LEN (L"\\EFI\\BOOT\\"); - - if (IsGeneric != NULL && PathLen >= GenericBootloaderLength) { - RestLen = PathLen - GenericBootloaderLength; - if ((RestLen == 0 || Path[RestLen - 1] == L'\\') - && OcStrniCmp (&Path[RestLen], GenericBootloader, GenericBootloaderLength) == 0) { - *IsGeneric = TRUE; - } - } - - FreePool (Path); - return OC_BOOT_UNKNOWN; -} - -EFI_LOADED_IMAGE_PROTOCOL * -OcGetAppleBootLoadedImage ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - - if (!EFI_ERROR(Status) - && LoadedImage->FilePath != NULL - && (OcGetBootDevicePathType (LoadedImage->FilePath, NULL, NULL) & OC_BOOT_APPLE_ANY) != 0) { - return LoadedImage; - } - - return NULL; -} diff --git a/Library/OcBootManagementLib/VariableManagement.c b/Library/OcBootManagementLib/VariableManagement.c deleted file mode 100644 index e837a5617..000000000 --- a/Library/OcBootManagementLib/VariableManagement.c +++ /dev/null @@ -1,355 +0,0 @@ -/** @file - Copyright (C) 2016, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_GUID -mOzmosisProprietary1Guid = { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } }; - -STATIC -EFI_GUID -mOzmosisProprietary2Guid = { 0x1F8E0C02, 0x58A9, 0x4E34, { 0xAE, 0x22, 0x2B, 0x63, 0x74, 0x5F, 0xA1, 0x01 } }; - -STATIC -EFI_GUID -mOzmosisProprietary3Guid = { 0x9480E8A1, 0x1793, 0x46C9, { 0x91, 0xD8, 0x11, 0x08, 0xDB, 0xA4, 0x73, 0x1C } }; - -STATIC -EFI_GUID -mBootChimeVendorVariableGuid = {0x89D4F995, 0x67E3, 0x4895, { 0x8F, 0x18, 0x45, 0x4B, 0x65, 0x1D, 0x92, 0x15 } }; - - -STATIC -BOOLEAN -IsDeletableVariable ( - IN CHAR16 *Name, - IN EFI_GUID *Guid - ) -{ - // - // Apple GUIDs - // - if (CompareGuid (Guid, &gEfiAppleNvramGuid) - || CompareGuid (Guid, &gEfiAppleBootGuid) - || CompareGuid (Guid, &gAppleCoreStorageVariableGuid) - || CompareGuid (Guid, &gAppleTamperResistantBootVariableGuid) - || CompareGuid (Guid, &gAppleWirelessNetworkVariableGuid) - || CompareGuid (Guid, &gApplePersonalizationVariableGuid) - || CompareGuid (Guid, &gAppleNetbootVariableGuid) - || CompareGuid (Guid, &gAppleSecureBootVariableGuid) - || CompareGuid (Guid, &gAppleTamperResistantBootSecureVariableGuid) - || CompareGuid (Guid, &gAppleTamperResistantBootEfiUserVariableGuid)) { - return TRUE; - // - // Global variable boot options - // - } else if (CompareGuid (Guid, &gEfiGlobalVariableGuid)) { - // - // Only erase boot and driver entries for BDS - // I.e. BootOrder, Boot####, DriverOrder, Driver#### - // - if (StrnCmp (Name, L"Boot", StrLen(L"Boot")) == 0 - || StrnCmp (Name, L"Driver", StrLen(L"Driver")) == 0) { - return TRUE; - } - // - // Lilu & OpenCore extensions if present - // - } else if (CompareGuid (Guid, &gOcVendorVariableGuid)) { - // - // Do not remove OpenCore critical variables. - // - if (StrCmp (Name, OC_BOOT_REDIRECT_VARIABLE_NAME) != 0 - && StrCmp (Name, OC_LOAD_POLICY_VARIABLE_NAME) != 0 - && StrCmp (Name, OC_SCAN_POLICY_VARIABLE_NAME) != 0) { - return TRUE; - } - } else if (CompareGuid (Guid, &gOcReadOnlyVariableGuid) - || CompareGuid (Guid, &gOcWriteOnlyVariableGuid)) { - return TRUE; - // - // Ozmozis extensions if present - // - } else if (CompareGuid (Guid, &mOzmosisProprietary1Guid) - || CompareGuid (Guid, &mOzmosisProprietary2Guid) - || CompareGuid (Guid, &mOzmosisProprietary3Guid)) { - return TRUE; - // - // Boot Chime preferences if present - // - } else if (CompareGuid (Guid, &mBootChimeVendorVariableGuid)) { - return TRUE; - // - // Microsoft certificates if present - // - } else if (CompareGuid (Guid, &gMicrosoftVariableGuid)) { - // - // Do not remove current OEM policy. - // - if (StrCmp (Name, L"CurrentPolicy") != 0) { - return TRUE; - } - } - - return FALSE; -} - -STATIC -VOID -DeleteVariables ( - VOID - ) -{ - EFI_GUID CurrentGuid; - EFI_STATUS Status; - CHAR16 *Buffer; - CHAR16 *TmpBuffer; - UINTN BufferSize; - UINTN RequestedSize; - BOOLEAN Restart; - BOOLEAN CriticalFailure; - - // - // Request 1024 byte buffer. - // - Buffer = NULL; - BufferSize = 0; - RequestedSize = 1024; - - // - // Force starting from 0th GUID. - // - Restart = TRUE; - - // - // Assume we have not failed yet. - // - CriticalFailure = FALSE; - - do { - // - // Allocate new buffer if needed. - // - if (RequestedSize > BufferSize) { - TmpBuffer = AllocateZeroPool (RequestedSize); - if (TmpBuffer != NULL) { - if (Buffer != NULL) { - CopyMem (TmpBuffer, Buffer, BufferSize); - FreePool (Buffer); - } - Buffer = TmpBuffer; - BufferSize = RequestedSize; - } else { - DEBUG (( - DEBUG_INFO, - "OCB: Failed to allocate variable name buffer of %u bytes\n", - (UINT32)RequestedSize - )); - break; - } - } - - // - // To start the search variable name should be L"". - // - if (Restart) { - ZeroMem (&CurrentGuid, sizeof (CurrentGuid)); - ZeroMem (Buffer, BufferSize); - Restart = FALSE; - } - - // - // Always pass maximum variable name size to reduce reallocations. - // - RequestedSize = BufferSize; - Status = gRT->GetNextVariableName (&RequestedSize, Buffer, &CurrentGuid); - - if (!EFI_ERROR(Status)) { - if (IsDeletableVariable (Buffer, &CurrentGuid)) { - Status = gRT->SetVariable (Buffer, &CurrentGuid, 0, 0, NULL); - if (!EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "Deleting %g:%s... OK\n", - &CurrentGuid, - Buffer - )); - // - // Calls to SetVariable() between calls to GetNextVariableName() - // may produce unpredictable results, so we restart. - // - Restart = TRUE; - } else if (Status == EFI_NOT_FOUND || Status == EFI_SECURITY_VIOLATION) { - DEBUG (( - DEBUG_INFO, - "Deleting %g:%s... SKIP - %r\n", - &CurrentGuid, - Buffer, - Status - )); - } else { - DEBUG (( - DEBUG_INFO, - "Deleting %g:%s... FAIL - %r\n", - &CurrentGuid, - Buffer, - Status - )); - break; - } - } else { - // Print (L"Skipping %g:%s\n", &CurrentGuid, Buffer); - } - } else if (Status != EFI_BUFFER_TOO_SMALL && Status != EFI_NOT_FOUND) { - if (!CriticalFailure) { - DEBUG ((DEBUG_INFO, "OCB: Unexpected error (%r), trying to rescan\n", Status)); - CriticalFailure = TRUE; - } else { - DEBUG ((DEBUG_INFO, "OCB: Unexpected error (%r), aborting\n", Status)); - break; - } - } - } while (Status != EFI_NOT_FOUND); - - if (Buffer != NULL) { - FreePool (Buffer); - } -} - -VOID -OcDeleteVariables ( - VOID - ) -{ - EFI_STATUS Status; - OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; - OC_FWRT_CONFIG Config; - UINTN BootProtectSize; - EFI_GUID *BootProtectGuid; - UINT32 BootProtect; - UINT16 BootOrder; - VOID *BootOption; - UINTN BootOptionSize; - - DEBUG ((DEBUG_INFO, "OCB: NVRAM cleanup...\n")); - - // - // Obtain boot protection marker. - // - BootProtectSize = sizeof (BootProtect); - Status = gRT->GetVariable ( - OC_BOOT_PROTECT_VARIABLE_NAME, - &gOcVendorVariableGuid, - NULL, - &BootProtectSize, - &BootProtect - ); - if (EFI_ERROR(Status)) { - BootProtect = 0; - } - - Status = gBS->LocateProtocol ( - &gOcFirmwareRuntimeProtocolGuid, - NULL, - (VOID **) &FwRuntime - ); - - if (!EFI_ERROR(Status) && FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) { - ZeroMem (&Config, sizeof (Config)); - FwRuntime->SetOverride (&Config); - DEBUG ((DEBUG_INFO, "OCB: Found FW NVRAM, full access %d\n", Config.BootVariableRedirect)); - } else { - FwRuntime = NULL; - DEBUG ((DEBUG_INFO, "OCB: Missing compatible FW NVRAM, going on...\n")); - } - - if ((BootProtect & OC_BOOT_PROTECT_VARIABLE_BOOTSTRAP) != 0) { - BootProtectGuid = (BootProtect & OC_BOOT_PROTECT_VARIABLE_NAMESPACE) != 0 ? &gOcVendorVariableGuid : &gEfiGlobalVariableGuid; - Status = GetVariable2 ( - OC_BOOT_OPTION_VARIABLE_NAME, - BootProtectGuid, - &BootOption, - &BootOptionSize - ); - if (!EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCB: Found %g:%s for preservation of %u bytes\n", - BootProtectGuid, - OC_BOOT_OPTION_VARIABLE_NAME, - (UINT32) BootOptionSize - )); - } else { - BootProtect = 0; - } - } - - DeleteVariables (); - - if ((BootProtect & OC_BOOT_PROTECT_VARIABLE_BOOTSTRAP) != 0) { - Status = gRT->SetVariable ( - OC_BOOT_OPTION_VARIABLE_NAME, - BootProtectGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - BootOptionSize, - BootOption - ); - BootOrder = OC_BOOT_OPTION; - if (!EFI_ERROR(Status)) { - Status = gRT->SetVariable ( - EFI_BOOT_ORDER_VARIABLE_NAME, - BootProtectGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - sizeof (BootOrder), - &BootOrder - ); - } - - DEBUG ((DEBUG_INFO, "OCB: Restored %s - %r\n", OC_BOOT_OPTION_VARIABLE_NAME, Status)); - FreePool (BootOption); - } - - if (FwRuntime != NULL) { - DEBUG ((DEBUG_INFO, "OCB: Restoring FW NVRAM...\n")); - FwRuntime->SetOverride (NULL); - } -} - -EFI_STATUS -InternalSystemActionResetNvram ( - VOID - ) -{ - OcDeleteVariables (); - DirectRestCold (); - return EFI_DEVICE_ERROR; -} diff --git a/Library/OcCompressionLib/OcCompressionLib.c b/Library/OcCompressionLib/OcCompressionLib.c deleted file mode 100644 index 28fec6358..000000000 --- a/Library/OcCompressionLib/OcCompressionLib.c +++ /dev/null @@ -1,140 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -UINT32 -DecompressMaskedRLE24 ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN UINT8 *Src, - IN UINT32 SrcLen, - IN UINT8 *Mask, - IN UINT32 MaskLen, - IN BOOLEAN Premultiply - ) -{ - // - // Data is encoded in three runs one by one: red, green, blue. - // The amount of pixels is equal to mask size, as it is 8-bit unencoded. - // - // Unlike normal RLE, where we process a sequence (N standing - // for repeat count byte, and B for value byte), this one is more similar - // to LZ algorithms: - // 1. & BIT7 != 0 is a normal repeat with N = - 125 bytes. - // 2. & BIT7 == 0 is a raw sequence of + 1 bytes. - // Despite this obviously being more a variant of an LZ algorithm, I follow - // suit by calling it RLE24 just as others do. - // - - UINT8 *SrcEnd; - UINT8 *SrcLast; - UINT8 *DstCur; - UINT8 *DstEnd; - UINT8 ControlValue; - UINT8 DstValue; - UINT8 RunIndex; - - if (SrcLen < 2 || MaskLen != DstLen / sizeof (UINT32)) { - return 0; - } - - SrcEnd = Src + SrcLen; - SrcLast = SrcEnd - 1; - - // - // Run over all channels. - // - for (RunIndex = 0; RunIndex < 3 && Src < SrcLast; ++RunIndex) { - // - // The resulting image is in BGRA format. - // - DstCur = Dst + 2 - RunIndex; - DstEnd = DstCur + MaskLen * sizeof (UINT32); - - // - // Iterate as long as we have enough control values. - // - while (Src < SrcLast && DstCur < DstEnd) { - // - // Process repeat sequences. - // - ControlValue = *Src++; - if (ControlValue & BIT7) { - ControlValue -= 125; - DstValue = *Src++; - - // - // Early exit on not enough bytes to fill. - // - if ((UINT32) (DstEnd - DstCur) < ControlValue * sizeof (UINT32)) { - return 0; - } - - while (ControlValue > 0) { - *DstCur = DstValue; - DstCur += sizeof (UINT32); - --ControlValue; - } - } else { - ++ControlValue; - - // - // Early exit on not enough bytes to read or fill. - // - if ((UINT32) (SrcEnd - Src) < ControlValue || (UINT32) (DstEnd - DstCur) < ControlValue * sizeof (UINT32)) { - return 0; - } - - while (ControlValue > 0) { - *DstCur = *Src++; - DstCur += sizeof (UINT32); - --ControlValue; - } - } - } - - // - // We failed fill the current run, abort. - // - if (DstCur != DstEnd) { - return 0; - } - } - - // - // Add mask to the resulting BGRA image. - // - if (Premultiply) { - DstCur = Dst; - SrcEnd = Mask + MaskLen; - while (Mask < SrcEnd) { - DstValue = *Mask++; - DstCur[0] = (UINT8) ((DstCur[0] * DstValue) / 0xFF); - DstCur[1] = (UINT8) ((DstCur[1] * DstValue) / 0xFF); - DstCur[2] = (UINT8) ((DstCur[2] * DstValue) / 0xFF); - DstCur[3] = DstValue; - DstCur += sizeof (UINT32); - } - } else { - DstCur = Dst + 3; - SrcEnd = Mask + MaskLen; - while (Mask < SrcEnd) { - *DstCur = *Mask++; - DstCur += sizeof (UINT32); - } - } - - return MaskLen * sizeof (UINT32); -} diff --git a/Library/OcCompressionLib/OcCompressionLib.inf b/Library/OcCompressionLib/OcCompressionLib.inf deleted file mode 100644 index 08daad516..000000000 --- a/Library/OcCompressionLib/OcCompressionLib.inf +++ /dev/null @@ -1,71 +0,0 @@ -## @file -# OcCompressionLib -# -# Copyright (c) 2019, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcCompressionLib - FILE_GUID = C384FA2A-B1AE-44FA-A33C-D59325B637C9 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcCompressionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - OcCompressionLib.c - ../../Include/Library/OcCompressionLib.h - - lzss/lzss.c - lzss/lzss.h - - lzvn/lzvn.c - lzvn/lzvn.h - - zlib/adler32.c - zlib/compress.c - zlib/crc32.c - zlib/crc32.h - zlib/deflate.c - zlib/deflate.h - zlib/infback.c - zlib/inffast.c - zlib/inffast.h - zlib/inffixed.h - zlib/inflate.c - zlib/inflate.h - zlib/inftrees.c - zlib/inftrees.h - zlib/trees.c - zlib/trees.h - zlib/uncompr.c - zlib/zconf.h - zlib/zlib.h - zlib/zlib_uefi.c - zlib/zutil.h - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - MemoryAllocationLib diff --git a/Library/OcCompressionLib/lzss/lzss.c b/Library/OcCompressionLib/lzss/lzss.c deleted file mode 100644 index 974f90890..000000000 --- a/Library/OcCompressionLib/lzss/lzss.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include "lzss.h" - -/******************************************************************************* -*******************************************************************************/ -u_int32_t local_adler32(u_int8_t * buffer, int32_t length) -{ - int32_t cnt; - u_int32_t result, lowHalf, highHalf; - - lowHalf = 1; - highHalf = 0; - - for (cnt = 0; cnt < length; cnt++) { - if ((cnt % 5000) == 0) { - lowHalf %= 65521L; - highHalf %= 65521L; - } - - lowHalf += buffer[cnt]; - highHalf += lowHalf; - } - - lowHalf %= 65521L; - highHalf %= 65521L; - - result = (highHalf << 16) | lowHalf; - - return result; -} - -/************************************************************** - LZSS.C -- A Data Compression Program -*************************************************************** - 4/6/1989 Haruhiko Okumura - Use, distribute, and modify this program freely. - Please send me your improved versions. - PC-VAN SCIENCE - NIFTY-Serve PAF01022 - CompuServe 74050,1022 - -**************************************************************/ - -#define N 4096 /* size of ring buffer - must be power of 2 */ -#define F 18 /* upper limit for match_length */ -#define THRESHOLD 2 /* encode string into position and length - if match_length is greater than this */ -#define NIL N /* index for root of binary search trees */ - -struct encode_state { - /* - * left & right children & parent. These constitute binary search trees. - */ - int lchild[N + 1], rchild[N + 257], parent[N + 1]; - - /* ring buffer of size N, with extra F-1 bytes to aid string comparison */ - u_int8_t text_buf[N + F - 1]; - - /* - * match_length of longest match. - * These are set by the insert_node() procedure. - */ - int match_position, match_length; -}; - - -/******************************************************************************* -*******************************************************************************/ -u_int32_t decompress_lzss( - u_int8_t * dst, - u_int32_t dstlen, - u_int8_t * src, - u_int32_t srclen) -{ - /* ring buffer of size N, with extra F-1 bytes to aid string comparison */ - u_int8_t text_buf[N + F - 1]; - u_int8_t * dststart = dst; - const u_int8_t * dstend = dst + dstlen; - const u_int8_t * srcend = src + srclen; - int i, j, k, r; - u_int8_t c; - unsigned int flags; - - if (dstlen > OC_COMPRESSION_MAX_LENGTH || srclen > OC_COMPRESSION_MAX_LENGTH) { - return 0; - } - - dst = dststart; - memset(text_buf, ' ', N - F); - r = N - F; - flags = 0; - for ( ; ; ) { - if (((flags >>= 1) & 0x100) == 0) { - if (src < srcend) c = *src++; else break; - flags = c | 0xFF00; /* uses higher byte cleverly */ - } /* to count eight */ - if (flags & 1) { - if (src < srcend) c = *src++; else break; - if (dst < dstend) *dst++ = c; else break; - text_buf[r++] = c; - r &= (N - 1); - } else { - if (src < srcend) i = *src++; else break; - if (src < srcend) j = *src++; else break; - i |= ((j & 0xF0) << 4); - j = (j & 0x0F) + THRESHOLD; - for (k = 0; k <= j; k++) { - c = text_buf[(i + k) & (N - 1)]; - if (dst < dstend) *dst++ = c; else break; - text_buf[r++] = c; - r &= (N - 1); - } - } - } - - return (u_int32_t)(dst - dststart); -} - -/* - * initialize state, mostly the trees - * - * For i = 0 to N - 1, rchild[i] and lchild[i] will be the right and left - * children of node i. These nodes need not be initialized. Also, parent[i] - * is the parent of node i. These are initialized to NIL (= N), which stands - * for 'not used.' For i = 0 to 255, rchild[N + i + 1] is the root of the - * tree for strings that begin with character i. These are initialized to NIL. - * Note there are 256 trees. */ -static void init_state(struct encode_state *sp) -{ - bzero(sp, sizeof(*sp)); - memset(&sp->text_buf[0], ' ', N - F); - bzero(&sp->rchild[N + 1], 256 * sizeof(sp->rchild[0])); - bzero(&sp->parent[0], N * sizeof(sp->parent[0])); -} - -/* - * Inserts string of length F, text_buf[r..r+F-1], into one of the trees - * (text_buf[r]'th tree) and returns the longest-match position and length - * via the global variables match_position and match_length. - * If match_length = F, then removes the old node in favor of the new one, - * because the old one will be deleted sooner. Note r plays double role, - * as tree node and position in buffer. - */ -static void insert_node(struct encode_state *sp, int r) -{ - int i, p, cmp; - u_int8_t *key; - - cmp = 1; - key = &sp->text_buf[r]; - p = N + 1 + key[0]; - sp->rchild[r] = sp->lchild[r] = NIL; - sp->match_length = 0; - for ( ; ; ) { - if (cmp >= 0) { - if (sp->rchild[p] != NIL) - p = sp->rchild[p]; - else { - sp->rchild[p] = r; - sp->parent[r] = p; - return; - } - } else { - if (sp->lchild[p] != NIL) - p = sp->lchild[p]; - else { - sp->lchild[p] = r; - sp->parent[r] = p; - return; - } - } - for (i = 1; i < F; i++) { - if ((cmp = key[i] - sp->text_buf[p + i]) != 0) - break; - } - if (i > sp->match_length) { - sp->match_position = p; - if ((sp->match_length = i) >= F) - break; - } - } - sp->parent[r] = sp->parent[p]; - sp->lchild[r] = sp->lchild[p]; - sp->rchild[r] = sp->rchild[p]; - sp->parent[sp->lchild[p]] = r; - sp->parent[sp->rchild[p]] = r; - if (sp->rchild[sp->parent[p]] == p) - sp->rchild[sp->parent[p]] = r; - else - sp->lchild[sp->parent[p]] = r; - sp->parent[p] = NIL; /* remove p */ -} - -/* deletes node p from tree */ -static void delete_node(struct encode_state *sp, int p) -{ - int q; - - if (sp->parent[p] == NIL) - return; /* not in tree */ - if (sp->rchild[p] == NIL) - q = sp->lchild[p]; - else if (sp->lchild[p] == NIL) - q = sp->rchild[p]; - else { - q = sp->lchild[p]; - if (sp->rchild[q] != NIL) { - do { - q = sp->rchild[q]; - } while (sp->rchild[q] != NIL); - sp->rchild[sp->parent[q]] = sp->lchild[q]; - sp->parent[sp->lchild[q]] = sp->parent[q]; - sp->lchild[q] = sp->lchild[p]; - sp->parent[sp->lchild[p]] = q; - } - sp->rchild[q] = sp->rchild[p]; - sp->parent[sp->rchild[p]] = q; - } - sp->parent[q] = sp->parent[p]; - if (sp->rchild[sp->parent[p]] == p) - sp->rchild[sp->parent[p]] = q; - else - sp->lchild[sp->parent[p]] = q; - sp->parent[p] = NIL; -} - -/******************************************************************************* -*******************************************************************************/ -u_int8_t * compress_lzss( - u_int8_t * dst, - u_int32_t dstlen, - u_int8_t * src, - u_int32_t srclen) -{ - u_int8_t * result = NULL; - /* Encoding state, mostly tree but some current match stuff */ - struct encode_state *sp; - - int i, len, r, s, last_match_length, code_buf_ptr; - u_int8_t c; - u_int8_t code_buf[17], mask; - u_int8_t * srcend = src + srclen; - u_int8_t *dstend = dst + dstlen; - - if (dstlen > OC_COMPRESSION_MAX_LENGTH || srclen > OC_COMPRESSION_MAX_LENGTH) { - return NULL; - } - - /* initialize trees */ - sp = (struct encode_state *) malloc(sizeof(*sp)); - if (!sp) goto finish; - - init_state(sp); - - /* - * code_buf[1..16] saves eight units of code, and code_buf[0] works - * as eight flags, "1" representing that the unit is an unencoded - * letter (1 byte), "0" a position-and-length pair (2 bytes). - * Thus, eight units require at most 16 bytes of code. - */ - code_buf[0] = 0; - code_buf_ptr = mask = 1; - - /* Clear the buffer with any character that will appear often. */ - s = 0; r = N - F; - - /* Read F bytes into the last F bytes of the buffer */ - for (len = 0; len < F && src < srcend; len++) - sp->text_buf[r + len] = *src++; - if (!len) - goto finish; - - /* - * Insert the F strings, each of which begins with one or more - * 'space' characters. Note the order in which these strings are - * inserted. This way, degenerate trees will be less likely to occur. - */ - for (i = 1; i <= F; i++) - insert_node(sp, r - i); - - /* - * Finally, insert the whole string just read. - * The global variables match_length and match_position are set. - */ - insert_node(sp, r); - do { - /* match_length may be spuriously long near the end of text. */ - if (sp->match_length > len) - sp->match_length = len; - if (sp->match_length <= THRESHOLD) { - sp->match_length = 1; /* Not long enough match. Send one byte. */ - code_buf[0] |= mask; /* 'send one byte' flag */ - code_buf[code_buf_ptr++] = sp->text_buf[r]; /* Send uncoded. */ - } else { - /* Send position and length pair. Note match_length > THRESHOLD. */ - code_buf[code_buf_ptr++] = (u_int8_t) sp->match_position; - code_buf[code_buf_ptr++] = (u_int8_t) - ( ((sp->match_position >> 4) & 0xF0) - | (sp->match_length - (THRESHOLD + 1)) ); - } - if ((mask <<= 1) == 0) { /* Shift mask left one bit. */ - /* Send at most 8 units of code together */ - for (i = 0; i < code_buf_ptr; i++) - if (dst < dstend) - *dst++ = code_buf[i]; - else - goto finish; - code_buf[0] = 0; - code_buf_ptr = mask = 1; - } - last_match_length = sp->match_length; - for (i = 0; i < last_match_length && src < srcend; i++) { - delete_node(sp, s); /* Delete old strings and */ - c = *src++; - sp->text_buf[s] = c; /* read new bytes */ - - /* - * If the position is near the end of buffer, extend the buffer - * to make string comparison easier. - */ - if (s < F - 1) - sp->text_buf[s + N] = c; - - /* Since this is a ring buffer, increment the position modulo N. */ - s = (s + 1) & (N - 1); - r = (r + 1) & (N - 1); - - /* Register the string in text_buf[r..r+F-1] */ - insert_node(sp, r); - } - while (i++ < last_match_length) { - delete_node(sp, s); - - /* After the end of text, no need to read, */ - s = (s + 1) & (N - 1); - r = (r + 1) & (N - 1); - /* but buffer may not be empty. */ - if (--len) - insert_node(sp, r); - } - } while (len > 0); /* until length of string to be processed is zero */ - - if (code_buf_ptr > 1) { /* Send remaining code. */ - for (i = 0; i < code_buf_ptr; i++) - if (dst < dstend) - *dst++ = code_buf[i]; - else - goto finish; - } - - result = dst; - -finish: - if (sp) free(sp); - - return result; -} diff --git a/Library/OcCompressionLib/lzss/lzss.h b/Library/OcCompressionLib/lzss/lzss.h deleted file mode 100644 index 11a6c6875..000000000 --- a/Library/OcCompressionLib/lzss/lzss.h +++ /dev/null @@ -1,54 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef LZSS_H -#define LZSS_H - -#include -#include -#include - -typedef UINT8 u_int8_t; -typedef UINT16 u_int16_t; -typedef UINT32 u_int32_t; - -typedef INT8 int8_t; -typedef INT16 int16_t; -typedef INT32 int32_t; - -#define compress_lzss CompressLZSS -#define decompress_lzss DecompressLZSS - -#ifdef memset -#undef memset -#endif - -#ifdef bzero -#undef bzero -#endif - -#ifdef malloc -#undef malloc -#endif - -#ifdef free -#undef free -#endif - -#define memset(Dst, Val, Size) SetMem ((Dst), (Size), (Val)) -#define bzero(Dst, Size) ZeroMem ((Dst), (Size)) -#define malloc(Size) AllocatePool (Size) -#define free(Ptr) FreePool (Ptr) - -#endif // LZSS_H diff --git a/Library/OcCompressionLib/lzvn/lzvn.c b/Library/OcCompressionLib/lzvn/lzvn.c deleted file mode 100644 index 43bf6a99a..000000000 --- a/Library/OcCompressionLib/lzvn/lzvn.c +++ /dev/null @@ -1,845 +0,0 @@ -/* -Copyright (c) 2015-2016, Apple Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// LZVN low-level decoder - -#include "lzvn.h" - -#ifndef assert -# define assert(x) do { } while (0) -#endif - -#if defined(_MSC_VER) && !defined(__clang__) -# define LZFSE_INLINE __forceinline -# define __builtin_expect(X, Y) (X) -# define __attribute__(X) -# pragma warning(disable : 4068) // warning C4068: unknown pragma -#else -# define LZFSE_INLINE static inline __attribute__((__always_inline__)) -#endif - -/*! @abstract Signed offset in buffers, stored on either 32 or 64 bits. */ -#if defined(_M_AMD64) || defined(__x86_64__) || defined(__arm64__) -typedef int64_t lzvn_offset; -#else -typedef int32_t lzvn_offset; -#endif - -/*! @abstract Base decoder state. */ -typedef struct { - - // Decoder I/O - - // Next byte to read in source buffer - const unsigned char *src; - // Next byte after source buffer - const unsigned char *src_end; - - // Next byte to write in destination buffer (by decoder) - unsigned char *dst; - // Valid range for destination buffer is [dst_begin, dst_end - 1] - unsigned char *dst_begin; - unsigned char *dst_end; - // Next byte to read in destination buffer (modified by caller) - unsigned char *dst_current; - - // Decoder state - - // Partially expanded match, or 0,0,0. - // In that case, src points to the next literal to copy, or the next op-code - // if L==0. - size_t L, M, D; - - // Distance for last emitted match, or 0 - lzvn_offset d_prev; - - // Did we decode end-of-stream? - int end_of_stream; - -} lzvn_decoder_state; - -/*! @abstract Load bytes from memory location SRC. */ -LZFSE_INLINE uint16_t load2(const void *ptr) { - uint16_t data; - memcpy(&data, ptr, sizeof data); - return data; -} - -LZFSE_INLINE uint32_t load4(const void *ptr) { - uint32_t data; - memcpy(&data, ptr, sizeof data); - return data; -} - -LZFSE_INLINE uint64_t load8(const void *ptr) { - uint64_t data; - memcpy(&data, ptr, sizeof data); - return data; -} - -/*! @abstract Store bytes to memory location DST. */ -LZFSE_INLINE void store4(void *ptr, uint32_t data) { - memcpy(ptr, &data, sizeof data); -} - -LZFSE_INLINE void store8(void *ptr, uint64_t data) { - memcpy(ptr, &data, sizeof data); -} - -/*! @abstract Extracts \p width bits from \p container, starting with \p lsb; if - * we view \p container as a bit array, we extract \c container[lsb:lsb+width]. */ -LZFSE_INLINE uintmax_t extract(uintmax_t container, unsigned lsb, - unsigned width) { - static const size_t container_width = sizeof container * 8; - assert(lsb < container_width); - assert(width > 0 && width <= container_width); - assert(lsb + width <= container_width); - if (width == container_width) - return container; - return (container >> lsb) & (((uintmax_t)1 << width) - 1); -} - -#if !defined(HAVE_LABELS_AS_VALUES) -# if defined(__GNUC__) || defined(__clang__) -# define HAVE_LABELS_AS_VALUES 1 -# else -# define HAVE_LABELS_AS_VALUES 0 -# endif -#endif - -// Both the source and destination buffers are represented by a pointer and -// a length; they are *always* updated in concert using this macro; however -// many bytes the pointer is advanced, the length is decremented by the same -// amount. Thus, pointer + length always points to the byte one past the end -// of the buffer. -#define PTR_LEN_INC(_pointer, _length, _increment) \ - (_pointer += _increment, _length -= _increment) - -// Update state with current positions and distance, corresponding to the -// beginning of an instruction in both streams -#define UPDATE_GOOD \ - (state->src = src_ptr, state->dst = dst_ptr, state->d_prev = D) - -/*! @abstract Decode source to destination. - * Updates \p state (src,dst,d_prev). */ -void lzvn_decode(lzvn_decoder_state *state) { -#if HAVE_LABELS_AS_VALUES - // Jump table for all instructions - static const void *opc_tbl[256] = { - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&eos, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&nop, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&nop, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&udef, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, - &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, - &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, - &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, - &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, &&med_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&sml_d, &&pre_d, &&lrg_d, - &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, - &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, &&udef, - &&lrg_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, - &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, &&sml_l, - &&lrg_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, - &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m, &&sml_m}; -#endif - size_t src_len = state->src_end - state->src; - size_t dst_len = state->dst_end - state->dst; - if (src_len == 0 || dst_len == 0) - return; // empty buffer - - const unsigned char *src_ptr = state->src; - unsigned char *dst_ptr = state->dst; - size_t D = state->d_prev; - size_t M; - size_t L; - size_t opc_len; - - // Do we have a partially expanded match saved in state? - if (state->L != 0 || state->M != 0) { - L = state->L; - M = state->M; - D = state->D; - opc_len = 0; // we already skipped the op - state->L = state->M = state->D = 0; - if (M == 0) - goto copy_literal; - if (L == 0) - goto copy_match; - goto copy_literal_and_match; - } - - unsigned char opc = src_ptr[0]; - -#if HAVE_LABELS_AS_VALUES - goto *opc_tbl[opc]; -#else - for (;;) { - switch (opc) { -#endif -// =============================================================== -// These four opcodes (sml_d, med_d, lrg_d, and pre_d) encode both a -// literal and a match. The bulk of their implementations are shared; -// each label here only does the work of setting the opcode length (not -// including any literal bytes), and extracting the literal length, match -// length, and match distance (except in pre_d). They then jump into the -// shared implementation to actually output the literal and match bytes. -// -// No error checking happens in the first stage, except for ensuring that -// the source has enough length to represent the full opcode before -// reading past the first byte. -#if HAVE_LABELS_AS_VALUES -sml_d: -#else - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 48: - case 49: - case 50: - case 51: - case 52: - case 53: - case 56: - case 57: - case 58: - case 59: - case 60: - case 61: - case 64: - case 65: - case 66: - case 67: - case 68: - case 69: - case 72: - case 73: - case 74: - case 75: - case 76: - case 77: - case 80: - case 81: - case 82: - case 83: - case 84: - case 85: - case 88: - case 89: - case 90: - case 91: - case 92: - case 93: - case 96: - case 97: - case 98: - case 99: - case 100: - case 101: - case 104: - case 105: - case 106: - case 107: - case 108: - case 109: - case 128: - case 129: - case 130: - case 131: - case 132: - case 133: - case 136: - case 137: - case 138: - case 139: - case 140: - case 141: - case 144: - case 145: - case 146: - case 147: - case 148: - case 149: - case 152: - case 153: - case 154: - case 155: - case 156: - case 157: - case 192: - case 193: - case 194: - case 195: - case 196: - case 197: - case 200: - case 201: - case 202: - case 203: - case 204: - case 205: -#endif - UPDATE_GOOD; - // "small distance": This opcode has the structure LLMMMDDD DDDDDDDD LITERAL - // where the length of literal (0-3 bytes) is encoded by the high 2 bits of - // the first byte. We first extract the literal length so we know how long - // the opcode is, then check that the source can hold both this opcode and - // at least one byte of the next (because any valid input stream must be - // terminated with an eos token). - opc_len = 2; - L = (size_t)extract(opc, 6, 2); - M = (size_t)extract(opc, 3, 3) + 3; - // We need to ensure that the source buffer is long enough that we can - // safely read this entire opcode, the literal that follows, and the first - // byte of the next opcode. Once we satisfy this requirement, we can - // safely unpack the match distance. A check similar to this one is - // present in all the opcode implementations. - if (src_len <= opc_len + L) - return; // source truncated - D = (size_t)extract(opc, 0, 3) << 8 | src_ptr[1]; - goto copy_literal_and_match; - -#if HAVE_LABELS_AS_VALUES -med_d: -#else - case 160: - case 161: - case 162: - case 163: - case 164: - case 165: - case 166: - case 167: - case 168: - case 169: - case 170: - case 171: - case 172: - case 173: - case 174: - case 175: - case 176: - case 177: - case 178: - case 179: - case 180: - case 181: - case 182: - case 183: - case 184: - case 185: - case 186: - case 187: - case 188: - case 189: - case 190: - case 191: -#endif - UPDATE_GOOD; - // "medium distance": This is a minor variant of the "small distance" - // encoding, where we will now use two extra bytes instead of one to encode - // the restof the match length and distance. This allows an extra two bits - // for the match length, and an extra three bits for the match distance. The - // full structure of the opcode is 101LLMMM DDDDDDMM DDDDDDDD LITERAL. - opc_len = 3; - L = (size_t)extract(opc, 3, 2); - if (src_len <= opc_len + L) - return; // source truncated - uint16_t opc23 = load2(&src_ptr[1]); - M = (size_t)((extract(opc, 0, 3) << 2 | extract(opc23, 0, 2)) + 3); - D = (size_t)extract(opc23, 2, 14); - goto copy_literal_and_match; - -#if HAVE_LABELS_AS_VALUES -lrg_d: -#else - case 7: - case 15: - case 23: - case 31: - case 39: - case 47: - case 55: - case 63: - case 71: - case 79: - case 87: - case 95: - case 103: - case 111: - case 135: - case 143: - case 151: - case 159: - case 199: - case 207: -#endif - UPDATE_GOOD; - // "large distance": This is another variant of the "small distance" - // encoding, where we will now use two extra bytes to encode the match - // distance, which allows distances up to 65535 to be represented. The full - // structure of the opcode is LLMMM111 DDDDDDDD DDDDDDDD LITERAL. - opc_len = 3; - L = (size_t)extract(opc, 6, 2); - M = (size_t)extract(opc, 3, 3) + 3; - if (src_len <= opc_len + L) - return; // source truncated - D = load2(&src_ptr[1]); - goto copy_literal_and_match; - -#if HAVE_LABELS_AS_VALUES -pre_d: -#else - case 70: - case 78: - case 86: - case 94: - case 102: - case 110: - case 134: - case 142: - case 150: - case 158: - case 198: - case 206: -#endif - UPDATE_GOOD; - // "previous distance": This opcode has the structure LLMMM110, where the - // length of the literal (0-3 bytes) is encoded by the high 2 bits of the - // first byte. We first extract the literal length so we know how long - // the opcode is, then check that the source can hold both this opcode and - // at least one byte of the next (because any valid input stream must be - // terminated with an eos token). - opc_len = 1; - L = (size_t)extract(opc, 6, 2); - M = (size_t)extract(opc, 3, 3) + 3; - if (src_len <= opc_len + L) - return; // source truncated - goto copy_literal_and_match; - -copy_literal_and_match: - // Common implementation of writing data for opcodes that have both a - // literal and a match. We begin by advancing the source pointer past - // the opcode, so that it points at the first literal byte (if L - // is non-zero; otherwise it points at the next opcode). - PTR_LEN_INC(src_ptr, src_len, opc_len); - // Now we copy the literal from the source pointer to the destination. - if (__builtin_expect(dst_len >= 4 && src_len >= 4, 1)) { - // The literal is 0-3 bytes; if we are not near the end of the buffer, - // we can safely just do a 4 byte copy (which is guaranteed to cover - // the complete literal, and may include some other bytes as well). - store4(dst_ptr, load4(src_ptr)); - } else if (L <= dst_len) { - // We are too close to the end of either the input or output stream - // to be able to safely use a four-byte copy, but we will not exhaust - // either stream (we already know that the source will not be - // exhausted from checks in the individual opcode implementations, - // and we just tested that dst_len > L). Thus, we need to do a - // byte-by-byte copy of the literal. This is slow, but it can only ever - // happen near the very end of a buffer, so it is not an important case to - // optimize. - for (size_t i = 0; i < L; ++i) - dst_ptr[i] = src_ptr[i]; - } else { - // Destination truncated: fill DST, and store partial match - - // Copy partial literal - for (size_t i = 0; i < dst_len; ++i) - dst_ptr[i] = src_ptr[i]; - // Save state - state->src = src_ptr + dst_len; - state->dst = dst_ptr + dst_len; - state->L = L - dst_len; - state->M = M; - state->D = D; - return; // destination truncated - } - // Having completed the copy of the literal, we advance both the source - // and destination pointers by the number of literal bytes. - PTR_LEN_INC(dst_ptr, dst_len, L); - PTR_LEN_INC(src_ptr, src_len, L); - // Check if the match distance is valid; matches must not reference - // bytes that preceed the start of the output buffer, nor can the match - // distance be zero. - if (D > (size_t)(dst_ptr - state->dst_begin) || D == 0) - goto invalid_match_distance; -copy_match: - // Now we copy the match from dst_ptr - D to dst_ptr. It is important to keep - // in mind that we may have D < M, in which case the source and destination - // windows overlap in the copy. The semantics of the match copy are *not* - // those of memmove( ); if the buffers overlap it needs to behave as though - // we were copying byte-by-byte in increasing address order. If, for example, - // D is 1, the copy operation is equivalent to: - // - // memset(dst_ptr, dst_ptr[-1], M); - // - // i.e. it splats the previous byte. This means that we need to be very - // careful about using wide loads or stores to perform the copy operation. - if (__builtin_expect(dst_len >= M + 7 && D >= 8, 1)) { - // We are not near the end of the buffer, and the match distance - // is at least eight. Thus, we can safely loop using eight byte - // copies. The last of these may slop over the intended end of - // the match, but this is OK because we know we have a safety bound - // away from the end of the destination buffer. - for (size_t i = 0; i < M; i += 8) - store8(&dst_ptr[i], load8(dst_ptr + i - D)); - } else if (M <= dst_len) { - // Either the match distance is too small, or we are too close to - // the end of the buffer to safely use eight byte copies. Fall back - // on a simple byte-by-byte implementation. - for (size_t i = 0; i < M; ++i) - dst_ptr[i] = *(dst_ptr + i - D); - } else { - // Destination truncated: fill DST, and store partial match - - // Copy partial match - for (size_t i = 0; i < dst_len; ++i) - dst_ptr[i] = *(dst_ptr + i - D); - // Save state - state->src = src_ptr; - state->dst = dst_ptr + dst_len; - state->L = 0; - state->M = M - dst_len; - state->D = D; - return; // destination truncated - } - // Update the destination pointer and length to account for the bytes - // written by the match, then load the next opcode byte and branch to - // the appropriate implementation. - PTR_LEN_INC(dst_ptr, dst_len, M); - opc = src_ptr[0]; -#if HAVE_LABELS_AS_VALUES - goto *opc_tbl[opc]; -#else - break; -#endif - -// =============================================================== -// Opcodes representing only a match (no literal). -// These two opcodes (lrg_m and sml_m) encode only a match. The match -// distance is carried over from the previous opcode, so all they need -// to encode is the match length. We are able to reuse the match copy -// sequence from the literal and match opcodes to perform the actual -// copy implementation. -#if HAVE_LABELS_AS_VALUES -sml_m: -#else - case 241: - case 242: - case 243: - case 244: - case 245: - case 246: - case 247: - case 248: - case 249: - case 250: - case 251: - case 252: - case 253: - case 254: - case 255: -#endif - UPDATE_GOOD; - // "small match": This opcode has no literal, and uses the previous match - // distance (i.e. it encodes only the match length), in a single byte as - // 1111MMMM. - opc_len = 1; - if (src_len <= opc_len) - return; // source truncated - M = (size_t)extract(opc, 0, 4); - PTR_LEN_INC(src_ptr, src_len, opc_len); - goto copy_match; - -#if HAVE_LABELS_AS_VALUES -lrg_m: -#else - case 240: -#endif - UPDATE_GOOD; - // "large match": This opcode has no literal, and uses the previous match - // distance (i.e. it encodes only the match length). It is encoded in two - // bytes as 11110000 MMMMMMMM. Because matches smaller than 16 bytes can - // be represented by sml_m, there is an implicit bias of 16 on the match - // length; the representable values are [16,271]. - opc_len = 2; - if (src_len <= opc_len) - return; // source truncated - M = src_ptr[1] + 16; - PTR_LEN_INC(src_ptr, src_len, opc_len); - goto copy_match; - -// =============================================================== -// Opcodes representing only a literal (no match). -// These two opcodes (lrg_l and sml_l) encode only a literal. There is no -// match length or match distance to worry about (but we need to *not* -// touch D, as it must be preserved between opcodes). -#if HAVE_LABELS_AS_VALUES -sml_l: -#else - case 225: - case 226: - case 227: - case 228: - case 229: - case 230: - case 231: - case 232: - case 233: - case 234: - case 235: - case 236: - case 237: - case 238: - case 239: -#endif - UPDATE_GOOD; - // "small literal": This opcode has no match, and encodes only a literal - // of length up to 15 bytes. The format is 1110LLLL LITERAL. - opc_len = 1; - L = (size_t)extract(opc, 0, 4); - goto copy_literal; - -#if HAVE_LABELS_AS_VALUES -lrg_l: -#else - case 224: -#endif - UPDATE_GOOD; - // "large literal": This opcode has no match, and uses the previous match - // distance (i.e. it encodes only the match length). It is encoded in two - // bytes as 11100000 LLLLLLLL LITERAL. Because literals smaller than 16 - // bytes can be represented by sml_l, there is an implicit bias of 16 on - // the literal length; the representable values are [16,271]. - opc_len = 2; - if (src_len <= 2) - return; // source truncated - L = src_ptr[1] + 16; - goto copy_literal; - -copy_literal: - // Check that the source buffer is large enough to hold the complete - // literal and at least the first byte of the next opcode. If so, advance - // the source pointer to point to the first byte of the literal and adjust - // the source length accordingly. - if (src_len <= opc_len + L) - return; // source truncated - PTR_LEN_INC(src_ptr, src_len, opc_len); - // Now we copy the literal from the source pointer to the destination. - if (dst_len >= L + 7 && src_len >= L + 7) { - // We are not near the end of the source or destination buffers; thus - // we can safely copy the literal using wide copies, without worrying - // about reading or writing past the end of either buffer. - for (size_t i = 0; i < L; i += 8) - store8(&dst_ptr[i], load8(&src_ptr[i])); - } else if (L <= dst_len) { - // We are too close to the end of either the input or output stream - // to be able to safely use an eight-byte copy. Instead we copy the - // literal byte-by-byte. - for (size_t i = 0; i < L; ++i) - dst_ptr[i] = src_ptr[i]; - } else { - // Destination truncated: fill DST, and store partial match - - // Copy partial literal - for (size_t i = 0; i < dst_len; ++i) - dst_ptr[i] = src_ptr[i]; - // Save state - state->src = src_ptr + dst_len; - state->dst = dst_ptr + dst_len; - state->L = L - dst_len; - state->M = 0; - state->D = D; - return; // destination truncated - } - // Having completed the copy of the literal, we advance both the source - // and destination pointers by the number of literal bytes. - PTR_LEN_INC(dst_ptr, dst_len, L); - PTR_LEN_INC(src_ptr, src_len, L); - // Load the first byte of the next opcode, and jump to its implementation. - opc = src_ptr[0]; -#if HAVE_LABELS_AS_VALUES - goto *opc_tbl[opc]; -#else - break; -#endif - -// =============================================================== -// Other opcodes -#if HAVE_LABELS_AS_VALUES -nop: -#else - case 14: - case 22: -#endif - UPDATE_GOOD; - opc_len = 1; - if (src_len <= opc_len) - return; // source truncated - PTR_LEN_INC(src_ptr, src_len, opc_len); - opc = src_ptr[0]; -#if HAVE_LABELS_AS_VALUES - goto *opc_tbl[opc]; -#else - break; -#endif - -#if HAVE_LABELS_AS_VALUES -eos: -#else - case 6: -#endif - opc_len = 8; - if (src_len < opc_len) - return; // source truncated (here we don't need an extra byte for next op - // code) - PTR_LEN_INC(src_ptr, src_len, opc_len); - state->end_of_stream = 1; - UPDATE_GOOD; - return; // end-of-stream - -// =============================================================== -// Return on error -#if HAVE_LABELS_AS_VALUES -udef: -#else - case 30: - case 38: - case 46: - case 54: - case 62: - case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - case 119: - case 120: - case 121: - case 122: - case 123: - case 124: - case 125: - case 126: - case 127: - case 208: - case 209: - case 210: - case 211: - case 212: - case 213: - case 214: - case 215: - case 216: - case 217: - case 218: - case 219: - case 220: - case 221: - case 222: - case 223: -#endif -invalid_match_distance: - - return; // we already updated state -#if !HAVE_LABELS_AS_VALUES - } - } -#endif -} - -size_t lzvn_decode_buffer(unsigned char *dst, size_t dst_size, - const unsigned char *src, size_t src_size) { - // Init LZVN decoder state - lzvn_decoder_state dstate; - - if (dst_size > OC_COMPRESSION_MAX_LENGTH || src_size > OC_COMPRESSION_MAX_LENGTH) { - return 0; - } - - memset(&dstate, 0x00, sizeof(dstate)); - dstate.src = src; - dstate.src_end = src + src_size; - - dstate.dst_begin = dst; - dstate.dst = dst; - dstate.dst_end = dst + dst_size; - - dstate.d_prev = 0; - dstate.end_of_stream = 0; - - // Run LZVN decoder - lzvn_decode(&dstate); - - // This is how much we decompressed - return dstate.dst - dst; -} diff --git a/Library/OcCompressionLib/lzvn/lzvn.h b/Library/OcCompressionLib/lzvn/lzvn.h deleted file mode 100644 index e74f458e3..000000000 --- a/Library/OcCompressionLib/lzvn/lzvn.h +++ /dev/null @@ -1,45 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef LZVN_H -#define LZVN_H - -#include -#include - -typedef UINT16 uint16_t; -typedef UINT32 uint32_t; -typedef UINT64 uint64_t; - -typedef INT16 int16_t; -typedef INT32 int32_t; -typedef INT64 int64_t; - -typedef UINTN size_t; -typedef UINTN uintmax_t; - -#define lzvn_decode_buffer DecompressLZVN - -#ifdef memset -#undef memset -#endif - -#ifdef memcpy -#undef memcpy -#endif - -#define memset(Dst, Value, Size) SetMem ((Dst), (Size), (UINT8)(Value)) -#define memcpy(Dst, Src, Size) CopyMem ((Dst), (Src), (Size)) - -#endif /* LZVN_H */ diff --git a/Library/OcCompressionLib/zlib/adler32.c b/Library/OcCompressionLib/zlib/adler32.c deleted file mode 100644 index d0be4380a..000000000 --- a/Library/OcCompressionLib/zlib/adler32.c +++ /dev/null @@ -1,186 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/Library/OcCompressionLib/zlib/compress.c b/Library/OcCompressionLib/zlib/compress.c deleted file mode 100644 index e2db404ab..000000000 --- a/Library/OcCompressionLib/zlib/compress.c +++ /dev/null @@ -1,86 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/Library/OcCompressionLib/zlib/crc32.c b/Library/OcCompressionLib/zlib/crc32.c deleted file mode 100644 index 62cb9fe34..000000000 --- a/Library/OcCompressionLib/zlib/crc32.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016, 2018 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * This interleaved implementation of a CRC makes use of pipelined multiple - * arithmetic-logic units, commonly found in modern CPU cores. It is due to - * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - MAKECRCH can be #defined to write out crc32.h. A main() routine is also - produced, so that this one source file can be compiled to an executable. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ - - /* - A CRC of a message is computed on N braids of words in the message, where - each word consists of W bytes (4 or 8). If N is 3, for example, then three - running sparse CRCs are calculated respectively on each braid, at these - indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... - This is done starting at a word boundary, and continues until as many blocks - of N * W bytes as are available have been processed. The results are combined - into a single CRC at the end. For this code, N must be in the range 1..6 and - W must be 4 or 8. The upper limit on N can be increased if desired by adding - more #if blocks, extending the patterns apparent in the code. In addition, - crc32.h would need to be regenerated, if the maximum N value is increased. - - N and W are chosen empirically by benchmarking the execution time on a given - processor. The choices for N and W below were based on testing on Intel Kaby - Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 - Octeon II processors. The Intel, AMD, and ARM processors were all fastest - with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. - They were all tested with either gcc or clang, all using the -O3 optimization - level. Your mileage may vary. - */ - -/* Define N */ -#ifdef Z_TESTN -# define N Z_TESTN -#else -# define N 5 -#endif -#if N < 1 || N > 6 -# error N must be in 1..6 -#endif - -/* - z_crc_t must be at least 32 bits. z_word_t must be at least as long as - z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and - that bytes are eight bits. - */ - -/* - Define W and the associated z_word_t type. If W is not defined, then a - braided calculation is not used, and the associated tables and code are not - compiled. - */ -#ifdef Z_TESTW -# if Z_TESTW-1 != -1 -# define W Z_TESTW -# endif -#else -# ifdef MAKECRCH -# define W 8 /* required for MAKECRCH */ -# else -# if defined(__x86_64__) || defined(__aarch64__) -# define W 8 -# else -# define W 4 -# endif -# endif -#endif -#ifdef W -# if W == 8 && defined(Z_U8) - typedef Z_U8 z_word_t; -# elif defined(Z_U4) -# undef W -# define W 4 - typedef Z_U4 z_word_t; -# else -# undef W -# endif -#endif - -/* Local functions. */ -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); -#ifdef W - local z_word_t byte_swap OF((z_word_t word)); - local z_crc_t crc_word OF((z_word_t data)); - local z_word_t crc_word_big OF((z_word_t data)); -#endif /* W */ - -/* CRC polynomial. */ -#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ - -#ifdef DYNAMIC_CRC_TABLE - -local z_crc_t FAR crc_table[256]; -local z_crc_t FAR x2n_table[32]; -local void make_crc_table OF((void)); -#ifdef W - local z_word_t FAR crc_big_table[256]; - local z_crc_t FAR crc_braid_table[W][256]; - local z_word_t FAR crc_braid_big_table[W][256]; - local void braid OF((z_crc_t [][256], z_word_t [][256], int, int)); -#endif -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *, int)); - local void write_table32hi OF((FILE *, const z_word_t FAR *, int)); - local void write_table64 OF((FILE *, const z_word_t FAR *, int)); -#endif /* MAKECRCH */ - -/* - Define a once() function depending on the availability of atomics. If this is - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in - multiple threads, and if atomics are not available, then get_crc_table() must - be called to initialize the tables and must return before any threads are - allowed to compute or combine CRCs. - */ - -/* Definition of once functionality. */ -typedef struct once_s once_t; -local void once OF((once_t *, void (*)(void))); - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - atomic_flag begun; - atomic_int done; -}; -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - ONCE_INIT. - */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - volatile int begun; - volatile int done; -}; -#define ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to minimize the period of - vulnerability. */ -local int test_and_set OF((int volatile *)); -local int test_and_set(flag) - int volatile *flag; -{ - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif - -/* State for once(). */ -local once_t made = ONCE_INIT; - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x - (which is shifting right by one and adding x^32 mod p if the bit shifted out - is a one). We start with the highest power (least significant bit) of q and - repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all the - information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ - -local void make_crc_table() -{ - unsigned i, j, n; - z_crc_t p; - - /* initialize the CRC of bytes tables */ - for (i = 0; i < 256; i++) { - p = i; - for (j = 0; j < 8; j++) - p = p & 1 ? (p >> 1) ^ POLY : p >> 1; - crc_table[i] = p; -#ifdef W - crc_big_table[i] = byte_swap(p); -#endif - } - - /* initialize the x^2^n mod p(x) table */ - p = (z_crc_t)1 << 30; /* x^1 */ - x2n_table[0] = p; - for (n = 1; n < 32; n++) - x2n_table[n] = p = multmodp(p, p); - -#ifdef W - /* initialize the braiding tables -- needs x2n_table[] */ - braid(crc_braid_table, crc_braid_big_table, N, W); -#endif - -#ifdef MAKECRCH - { - /* - The crc32.h header file contains tables for both 32-bit and 64-bit - z_word_t's, and so requires a 64-bit type be available. In that case, - z_word_t must be defined to be 64-bits. This code then also generates - and writes out the tables for the case that z_word_t is 32 bits. - */ -#if !defined(W) || W != 8 -# error Need a 64-bit integer type in order to generate crc32.h. -#endif - FILE *out; - int k, n; - z_crc_t ltl[8][256]; - z_word_t big[8][256]; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - - /* write out little-endian CRC table to crc32.h */ - fprintf(out, - "/* crc32.h -- tables for rapid CRC calculation\n" - " * Generated automatically by crc32.c\n */\n" - "\n" - "local const z_crc_t FAR crc_table[] = {\n" - " "); - write_table(out, crc_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#ifdef W\n" - "\n" - "#if W == 8\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table64(out, crc_big_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table32hi(out, crc_big_table, 256); - fprintf(out, - "};\n" - "\n" - "#endif\n"); - - /* write out braid tables for each value of N */ - for (n = 1; n <= 6; n++) { - fprintf(out, - "\n" - "#if N == %d\n", n); - - /* compute braid tables for this N and 64-bit word_t */ - braid(ltl, big, n, 8); - - /* write out braid tables for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#if W == 8\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table64(out, big[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n"); - - /* compute braid tables for this N and 32-bit word_t */ - braid(ltl, big, n, 4); - - /* write out braid tables for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table32hi(out, big[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "#endif\n" - "\n" - "#endif\n"); - } - fprintf(out, - "\n" - "#endif\n"); - - /* write out zeros operator table to crc32.h */ - fprintf(out, - "\n" - "local const z_crc_t FAR x2n_table[] = {\n" - " "); - write_table(out, x2n_table, 32); - fprintf(out, - "};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH - -/* - Write the 32-bit values in table[0..k-1] to out, five per line in - hexadecimal separated by commas. - */ -local void write_table(out, table, k) - FILE *out; - const z_crc_t FAR *table; - int k; -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the high 32-bits of each value in table[0..k-1] to out, five per line - in hexadecimal separated by commas. - */ -local void write_table32hi(out, table, k) -FILE *out; -const z_word_t FAR *table; -int k; -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n] >> 32), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the 64-bit values in table[0..k-1] to out, three per line in - hexadecimal separated by commas. This assumes that if there is a 64-bit - type, then there is also a long long integer type, and it is at least 64 - bits. If not, then the type cast and format string can be adjusted - accordingly. - */ -local void write_table64(out, table, k) - FILE *out; - const z_word_t FAR *table; - int k; -{ - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", - (unsigned long long)(table[n]), - n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); -} - -/* Actually do the deed. */ -int main() -{ - make_crc_table(); - return 0; -} - -#endif /* MAKECRCH */ - -#ifdef W -/* - Generate the little and big-endian braid tables for the given n and z_word_t - size w. Each array must have room for w blocks of 256 elements. - */ -local void braid(ltl, big, n, w) - z_crc_t ltl[][256]; - z_word_t big[][256]; - int n; - int w; -{ - int k; - z_crc_t i, p, q; - for (k = 0; k < w; k++) { - p = x2nmodp((n * w + 3 - k) << 3, 0); - ltl[k][0] = 0; - big[w - 1 - k][0] = 0; - for (i = 1; i < 256; i++) { - ltl[k][i] = q = multmodp(i << 24, p); - big[w - 1 - k][i] = byte_swap(q); - } - } -} -#endif - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ======================================================================== - * Routines used for CRC calculation. Some are also required for the table - * generation above. - */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(a, b) - z_crc_t a; - z_crc_t b; -{ - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(n, k) - z_off64_t n; - unsigned k; -{ - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - -#ifdef W - -/* - Swap the bytes in a z_word_t to convert between little and big endian. Any - self-respecting compiler will optimize this to a single machine byte-swap - instruction, if one is available. This assumes that word_t is either 32 bits - or 64 bits. - */ -local z_word_t byte_swap(word) - z_word_t word; -{ -#if W == 8 - return - (word & 0xff00000000000000) >> 56 | - (word & 0xff000000000000) >> 40 | - (word & 0xff0000000000) >> 24 | - (word & 0xff00000000) >> 8 | - (word & 0xff000000) << 8 | - (word & 0xff0000) << 24 | - (word & 0xff00) << 40 | - (word & 0xff) << 56; -#else /* W == 4 */ - return - (word & 0xff000000) >> 24 | - (word & 0xff0000) >> 8 | - (word & 0xff00) << 8 | - (word & 0xff) << 24; -#endif -} - -/* - Return the CRC of the W bytes in the word_t data, taking the - least-significant byte of the word as the first byte of data, without any pre - or post conditioning. This is used to combine the CRCs of each braid. - */ -local z_crc_t crc_word(data) - z_word_t data; -{ - int k; - for (k = 0; k < W; k++) - data = (data >> 8) ^ crc_table[data & 0xff]; - return (z_crc_t)data; -} - -local z_word_t crc_word_big(data) - z_word_t data; -{ - int k; - for (k = 0; k < W; k++) - data = (data << 8) ^ - crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; - return data; -} - -#endif /* W */ - -/* ========================================================================= - * This function can be used by asm versions of crc32(), and to force the - * generation of the CRC tables in a threaded application. - */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= - * Use ARM machine instructions if available. This will compute the CRC about - * ten times faster than the braided calculation. This code does not check for - * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will - * only be defined if the compilation specifies an ARM processor architecture - * that has the instructions. For example, compiling with -march=armv8.1-a or - * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 - * instructions. - */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 - -/* - Constants empirically determined to maximize speed. These values are from - measurements on a Cortex-A57. Your mileage may vary. - */ -#define Z_BATCH 3990 /* number of words in a batch */ -#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ -#define Z_BATCH_MIN 800 /* fewest words in a final batch */ - -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - z_crc_t val; - z_word_t crc1, crc2; - const z_word_t *word; - z_word_t val0, val1, val2; - z_size_t last, last2, i; - z_size_t num; - - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc ^= 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ - word = (z_word_t const *)buf; - num = len >> 3; - len &= 7; - - /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three - CRCs are combined into a single CRC after each set of batches. */ - while (num >= 3 * Z_BATCH) { - crc1 = 0; - crc2 = 0; - for (i = 0; i < Z_BATCH; i++) { - val0 = word[i]; - val1 = word[i + Z_BATCH]; - val2 = word[i + 2 * Z_BATCH]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * Z_BATCH; - num -= 3 * Z_BATCH; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; - } - - /* Do one last smaller batch with the remaining words, if there are enough - to pay for the combination of CRCs. */ - last = num / 3; - if (last >= Z_BATCH_MIN) { - last2 = last << 1; - crc1 = 0; - crc2 = 0; - for (i = 0; i < last; i++) { - val0 = word[i]; - val1 = word[i + last]; - val2 = word[i + last2]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * last; - num -= 3 * last; - val = x2nmodp(last, 6); - crc = multmodp(val, crc) ^ crc1; - crc = multmodp(val, crc) ^ crc2; - } - - /* Compute the CRC on any remaining words. */ - for (i = 0; i < num; i++) { - val0 = word[i]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - } - word += num; - - /* Complete the CRC on any remaining bytes. */ - buf = (const unsigned char FAR *)word; - while (len) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#else - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc ^= 0xffffffff; - -#ifdef W - - /* If provided enough bytes, do a braided CRC calculation. */ - if (len >= N * W + W - 1) { - z_size_t blks; - z_word_t const *words; - unsigned endian; - int k; - - /* Compute the CRC up to a z_word_t boundary. */ - while (len && ((z_size_t)buf & (W - 1)) != 0) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Compute the CRC on as many N z_word_t blocks as are available. */ - blks = len / (N * W); - len -= blks * N * W; - words = (z_word_t const *)buf; - - /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianess at execution time. If the - compiler knows what the endianess will be, it can optimize out the - check and the unused branch. */ - endian = 1; - if (*(unsigned char *)&endian) { - /* Little endian. */ - - z_crc_t crc0; - z_word_t word0; -#if N > 1 - z_crc_t crc1; - z_word_t word1; -#if N > 2 - z_crc_t crc2; - z_word_t word2; -#if N > 3 - z_crc_t crc3; - z_word_t word3; -#if N > 4 - z_crc_t crc4; - z_word_t word4; -#if N > 5 - z_crc_t crc5; - z_word_t word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = crc; -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - crc = crc_word(crc0 ^ words[0]); -#if N > 1 - crc = crc_word(crc1 ^ words[1] ^ crc); -#if N > 2 - crc = crc_word(crc2 ^ words[2] ^ crc); -#if N > 3 - crc = crc_word(crc3 ^ words[3] ^ crc); -#if N > 4 - crc = crc_word(crc4 ^ words[4] ^ crc); -#if N > 5 - crc = crc_word(crc5 ^ words[5] ^ crc); -#endif -#endif -#endif -#endif -#endif - words += N; - } - else { - /* Big endian. */ - - z_word_t crc0, word0, comb; -#if N > 1 - z_word_t crc1, word1; -#if N > 2 - z_word_t crc2, word2; -#if N > 3 - z_word_t crc3, word3; -#if N > 4 - z_word_t crc4, word4; -#if N > 5 - z_word_t crc5, word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = byte_swap(crc); -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_big_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_big_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_big_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_big_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_big_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_big_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - comb = crc_word_big(crc0 ^ words[0]); -#if N > 1 - comb = crc_word_big(crc1 ^ words[1] ^ comb); -#if N > 2 - comb = crc_word_big(crc2 ^ words[2] ^ comb); -#if N > 3 - comb = crc_word_big(crc3 ^ words[3] ^ comb); -#if N > 4 - comb = crc_word_big(crc4 ^ words[4] ^ comb); -#if N > 5 - comb = crc_word_big(crc5 ^ words[5] ^ comb); -#endif -#endif -#endif -#endif -#endif - words += N; - crc = byte_swap(comb); - } - - /* - Update the pointer to the remaining bytes to process. - */ - buf = (unsigned char const *)words; - } - -#endif /* W */ - - /* Complete the computation of the CRC on any remaining bytes. */ - while (len >= 8) { - len -= 8; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - while (len) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - return crc32_z(crc, buf, len); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine64(crc1, crc2, len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(len2) - z_off64_t len2; -{ -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(len2) - z_off_t len2; -{ - return crc32_combine_gen64(len2); -} - -/* ========================================================================= */ -uLong crc32_combine_op(crc1, crc2, op) - uLong crc1; - uLong crc2; - uLong op; -{ - return multmodp(op, crc1) ^ crc2; -} diff --git a/Library/OcCompressionLib/zlib/crc32.h b/Library/OcCompressionLib/zlib/crc32.h deleted file mode 100644 index 137df68d6..000000000 --- a/Library/OcCompressionLib/zlib/crc32.h +++ /dev/null @@ -1,9446 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}; - -#ifdef W - -#if W == 8 - -local const z_word_t FAR crc_big_table[] = { - 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}; - -#else /* W == 4 */ - -local const z_word_t FAR crc_big_table[] = { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}; - -#endif - -#if N == 1 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}, - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}, - {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, - 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, - 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, - 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, - 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, - 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, - 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, - 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, - 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, - 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, - 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, - 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, - 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, - 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, - 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, - 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, - 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, - 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, - 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, - 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, - 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, - 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, - 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, - 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, - 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, - 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, - 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, - 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, - 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, - 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, - 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, - 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, - 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, - 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, - 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, - 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, - 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, - 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, - 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, - 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, - 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, - 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, - 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, - 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, - 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, - 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, - 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, - 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, - 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, - 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, - 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, - 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, - 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, - 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, - 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, - 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, - 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, - 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, - 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, - 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, - 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, - 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, - 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, - 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, - 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, - 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, - 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, - 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, - 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, - 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, - 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, - 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, - 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, - 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, - 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, - 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, - 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, - 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, - 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, - 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, - 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, - 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, - 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, - 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, - 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, - 0x72fd249300000000}, - {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, - 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, - 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, - 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, - 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, - 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, - 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, - 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, - 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, - 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, - 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, - 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, - 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, - 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, - 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, - 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, - 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, - 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, - 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, - 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, - 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, - 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, - 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, - 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, - 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, - 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, - 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, - 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, - 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, - 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, - 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, - 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, - 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, - 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, - 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, - 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, - 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, - 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, - 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, - 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, - 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, - 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, - 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, - 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, - 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, - 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, - 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, - 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, - 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, - 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, - 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, - 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, - 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, - 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, - 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, - 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, - 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, - 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, - 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, - 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, - 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, - 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, - 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, - 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, - 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, - 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, - 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, - 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, - 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, - 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, - 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, - 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, - 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, - 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, - 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, - 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, - 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, - 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, - 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, - 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, - 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, - 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, - 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, - 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, - 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, - 0xed3498be00000000}, - {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, - 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, - 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, - 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, - 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, - 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, - 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, - 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, - 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, - 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, - 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, - 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, - 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, - 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, - 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, - 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, - 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, - 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, - 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, - 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, - 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, - 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, - 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, - 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, - 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, - 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, - 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, - 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, - 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, - 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, - 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, - 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, - 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, - 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, - 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, - 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, - 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, - 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, - 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, - 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, - 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, - 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, - 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, - 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, - 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, - 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, - 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, - 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, - 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, - 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, - 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, - 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, - 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, - 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, - 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, - 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, - 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, - 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, - 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, - 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, - 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, - 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, - 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, - 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, - 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, - 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, - 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, - 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, - 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, - 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, - 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, - 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, - 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, - 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, - 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, - 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, - 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, - 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, - 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, - 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, - 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, - 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, - 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, - 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, - 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, - 0xf10605de00000000}, - {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, - 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, - 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, - 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, - 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, - 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, - 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, - 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, - 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, - 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, - 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, - 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, - 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, - 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, - 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, - 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, - 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, - 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, - 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, - 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, - 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, - 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, - 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, - 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, - 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, - 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, - 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, - 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, - 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, - 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, - 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, - 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, - 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, - 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, - 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, - 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, - 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, - 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, - 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, - 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, - 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, - 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, - 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, - 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, - 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, - 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, - 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, - 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, - 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, - 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, - 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, - 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, - 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, - 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, - 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, - 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, - 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, - 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, - 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, - 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, - 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, - 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, - 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, - 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, - 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, - 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, - 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, - 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, - 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, - 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, - 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, - 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, - 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, - 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, - 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, - 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, - 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, - 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, - 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, - 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, - 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, - 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, - 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, - 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, - 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, - 0x8cc764ca00000000}, - {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, - 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, - 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, - 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, - 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, - 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, - 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, - 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, - 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, - 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, - 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, - 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, - 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, - 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, - 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, - 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, - 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, - 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, - 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, - 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, - 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, - 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, - 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, - 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, - 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, - 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, - 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, - 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, - 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, - 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, - 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, - 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, - 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, - 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, - 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, - 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, - 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, - 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, - 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, - 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, - 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, - 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, - 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, - 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, - 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, - 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, - 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, - 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, - 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, - 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, - 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, - 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, - 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, - 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, - 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, - 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, - 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, - 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, - 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, - 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, - 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, - 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, - 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, - 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, - 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, - 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, - 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, - 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, - 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, - 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, - 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, - 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, - 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, - 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, - 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, - 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, - 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, - 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, - 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, - 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, - 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, - 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, - 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, - 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, - 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, - 0xccabc4e400000000}, - {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, - 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, - 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, - 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, - 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, - 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, - 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, - 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, - 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, - 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, - 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, - 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, - 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, - 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, - 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, - 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, - 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, - 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, - 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, - 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, - 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, - 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, - 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, - 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, - 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, - 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, - 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, - 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, - 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, - 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, - 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, - 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, - 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, - 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, - 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, - 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, - 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, - 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, - 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, - 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, - 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, - 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, - 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, - 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, - 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, - 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, - 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, - 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, - 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, - 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, - 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, - 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, - 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, - 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, - 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, - 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, - 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, - 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, - 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, - 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, - 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, - 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, - 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, - 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, - 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, - 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, - 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, - 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, - 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, - 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, - 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, - 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, - 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, - 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, - 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, - 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, - 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, - 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, - 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, - 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, - 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, - 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, - 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, - 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, - 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, - 0x304a369200000000}, - {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, - 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, - 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, - 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, - 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, - 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, - 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, - 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, - 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, - 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, - 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, - 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, - 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, - 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, - 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, - 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, - 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, - 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, - 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, - 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, - 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, - 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, - 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, - 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, - 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, - 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, - 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, - 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, - 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, - 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, - 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, - 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, - 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, - 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, - 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, - 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, - 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, - 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, - 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, - 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, - 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, - 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, - 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, - 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, - 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, - 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, - 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, - 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, - 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, - 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, - 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, - 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, - 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, - 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, - 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, - 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, - 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, - 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, - 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, - 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, - 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, - 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, - 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, - 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, - 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, - 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, - 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, - 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, - 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, - 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, - 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, - 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, - 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, - 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, - 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, - 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, - 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, - 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, - 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, - 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, - 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, - 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, - 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, - 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, - 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, - 0xe6064b2600000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}, - {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493}, - {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be}, - {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de}}; - -#endif - -#endif - -#if N == 2 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}, - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, - 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, - 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, - 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, - 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, - 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, - 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, - 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, - 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, - 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, - 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, - 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, - 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, - 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, - 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, - 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, - 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, - 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, - 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, - 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, - 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, - 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, - 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, - 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, - 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, - 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, - 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, - 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, - 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, - 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, - 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, - 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, - 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, - 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, - 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, - 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, - 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, - 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, - 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, - 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, - 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, - 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, - 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, - 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, - 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, - 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, - 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, - 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, - 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, - 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, - 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, - 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, - 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, - 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, - 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, - 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, - 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, - 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, - 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, - 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, - 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, - 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, - 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, - 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, - 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, - 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, - 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, - 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, - 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, - 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, - 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, - 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, - 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, - 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, - 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, - 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, - 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, - 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, - 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, - 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, - 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, - 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, - 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, - 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, - 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, - 0x4b0c4f4900000000}, - {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, - 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, - 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, - 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, - 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, - 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, - 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, - 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, - 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, - 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, - 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, - 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, - 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, - 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, - 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, - 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, - 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, - 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, - 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, - 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, - 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, - 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, - 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, - 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, - 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, - 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, - 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, - 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, - 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, - 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, - 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, - 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, - 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, - 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, - 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, - 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, - 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, - 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, - 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, - 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, - 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, - 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, - 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, - 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, - 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, - 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, - 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, - 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, - 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, - 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, - 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, - 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, - 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, - 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, - 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, - 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, - 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, - 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, - 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, - 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, - 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, - 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, - 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, - 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, - 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, - 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, - 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, - 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, - 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, - 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, - 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, - 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, - 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, - 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, - 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, - 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, - 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, - 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, - 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, - 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, - 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, - 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, - 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, - 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, - 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, - 0x14d747e100000000}, - {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, - 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, - 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, - 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, - 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, - 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, - 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, - 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, - 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, - 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, - 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, - 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, - 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, - 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, - 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, - 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, - 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, - 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, - 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, - 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, - 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, - 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, - 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, - 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, - 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, - 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, - 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, - 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, - 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, - 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, - 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, - 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, - 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, - 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, - 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, - 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, - 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, - 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, - 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, - 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, - 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, - 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, - 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, - 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, - 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, - 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, - 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, - 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, - 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, - 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, - 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, - 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, - 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, - 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, - 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, - 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, - 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, - 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, - 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, - 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, - 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, - 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, - 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, - 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, - 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, - 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, - 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, - 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, - 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, - 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, - 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, - 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, - 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, - 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, - 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, - 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, - 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, - 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, - 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, - 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, - 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, - 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, - 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, - 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, - 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, - 0xaa933b1a00000000}, - {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, - 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, - 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, - 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, - 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, - 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, - 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, - 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, - 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, - 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, - 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, - 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, - 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, - 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, - 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, - 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, - 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, - 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, - 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, - 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, - 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, - 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, - 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, - 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, - 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, - 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, - 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, - 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, - 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, - 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, - 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, - 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, - 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, - 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, - 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, - 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, - 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, - 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, - 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, - 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, - 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, - 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, - 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, - 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, - 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, - 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, - 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, - 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, - 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, - 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, - 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, - 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, - 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, - 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, - 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, - 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, - 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, - 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, - 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, - 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, - 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, - 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, - 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, - 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, - 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, - 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, - 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, - 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, - 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, - 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, - 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, - 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, - 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, - 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, - 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, - 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, - 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, - 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, - 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, - 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, - 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, - 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, - 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, - 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, - 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, - 0x6571193600000000}, - {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, - 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, - 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, - 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, - 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, - 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, - 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, - 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, - 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, - 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, - 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, - 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, - 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, - 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, - 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, - 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, - 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, - 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, - 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, - 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, - 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, - 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, - 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, - 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, - 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, - 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, - 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, - 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, - 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, - 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, - 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, - 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, - 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, - 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, - 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, - 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, - 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, - 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, - 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, - 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, - 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, - 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, - 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, - 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, - 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, - 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, - 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, - 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, - 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, - 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, - 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, - 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, - 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, - 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, - 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, - 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, - 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, - 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, - 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, - 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, - 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, - 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, - 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, - 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, - 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, - 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, - 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, - 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, - 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, - 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, - 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, - 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, - 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, - 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, - 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, - 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, - 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, - 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, - 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, - 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, - 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, - 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, - 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, - 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, - 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, - 0xa68cee3d00000000}, - {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, - 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, - 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, - 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, - 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, - 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, - 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, - 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, - 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, - 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, - 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, - 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, - 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, - 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, - 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, - 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, - 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, - 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, - 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, - 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, - 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, - 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, - 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, - 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, - 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, - 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, - 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, - 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, - 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, - 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, - 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, - 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, - 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, - 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, - 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, - 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, - 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, - 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, - 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, - 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, - 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, - 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, - 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, - 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, - 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, - 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, - 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, - 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, - 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, - 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, - 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, - 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, - 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, - 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, - 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, - 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, - 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, - 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, - 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, - 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, - 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, - 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, - 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, - 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, - 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, - 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, - 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, - 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, - 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, - 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, - 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, - 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, - 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, - 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, - 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, - 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, - 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, - 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, - 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, - 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, - 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, - 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, - 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, - 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, - 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, - 0x51e8883f00000000}, - {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, - 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, - 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, - 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, - 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, - 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, - 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, - 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, - 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, - 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, - 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, - 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, - 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, - 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, - 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, - 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, - 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, - 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, - 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, - 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, - 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, - 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, - 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, - 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, - 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, - 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, - 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, - 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, - 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, - 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, - 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, - 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, - 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, - 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, - 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, - 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, - 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, - 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, - 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, - 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, - 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, - 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, - 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, - 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, - 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, - 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, - 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, - 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, - 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, - 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, - 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, - 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, - 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, - 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, - 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, - 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, - 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, - 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, - 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, - 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, - 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, - 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, - 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, - 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, - 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, - 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, - 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, - 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, - 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, - 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, - 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, - 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, - 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, - 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, - 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, - 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, - 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, - 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, - 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, - 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, - 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, - 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, - 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, - 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, - 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, - 0x8ae9531c00000000}, - {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, - 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, - 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, - 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, - 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, - 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, - 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, - 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, - 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, - 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, - 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, - 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, - 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, - 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, - 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, - 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, - 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, - 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, - 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, - 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, - 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, - 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, - 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, - 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, - 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, - 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, - 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, - 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, - 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, - 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, - 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, - 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, - 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, - 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, - 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, - 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, - 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, - 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, - 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, - 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, - 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, - 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, - 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, - 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, - 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, - 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, - 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, - 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, - 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, - 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, - 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, - 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, - 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, - 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, - 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, - 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, - 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, - 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, - 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, - 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, - 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, - 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, - 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, - 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, - 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, - 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, - 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, - 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, - 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, - 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, - 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, - 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, - 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, - 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, - 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, - 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, - 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, - 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, - 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, - 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, - 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, - 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, - 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, - 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, - 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, - 0xd739710d00000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, - 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, - 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, - 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, - 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, - 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, - 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, - 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, - 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, - 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, - 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, - 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, - 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, - 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, - 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, - 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, - 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, - 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, - 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, - 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, - 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, - 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, - 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, - 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, - 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, - 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, - 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, - 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, - 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, - 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, - 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, - 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, - 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, - 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, - 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, - 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, - 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, - 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, - 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, - 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, - 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, - 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, - 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, - 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, - 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, - 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, - 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, - 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, - 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, - 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, - 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, - 0x8cc764ca}, - {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, - 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, - 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, - 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, - 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, - 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, - 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, - 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, - 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, - 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, - 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, - 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, - 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, - 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, - 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, - 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, - 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, - 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, - 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, - 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, - 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, - 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, - 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, - 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, - 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, - 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, - 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, - 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, - 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, - 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, - 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, - 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, - 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, - 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, - 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, - 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, - 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, - 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, - 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, - 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, - 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, - 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, - 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, - 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, - 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, - 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, - 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, - 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, - 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, - 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, - 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, - 0xccabc4e4}, - {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, - 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, - 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, - 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, - 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, - 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, - 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, - 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, - 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, - 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, - 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, - 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, - 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, - 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, - 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, - 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, - 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, - 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, - 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, - 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, - 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, - 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, - 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, - 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, - 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, - 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, - 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, - 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, - 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, - 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, - 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, - 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, - 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, - 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, - 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, - 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, - 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, - 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, - 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, - 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, - 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, - 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, - 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, - 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, - 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, - 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, - 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, - 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, - 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, - 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, - 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, - 0x304a3692}, - {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, - 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, - 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, - 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, - 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, - 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, - 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, - 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, - 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, - 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, - 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, - 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, - 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, - 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, - 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, - 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, - 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, - 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, - 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, - 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, - 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, - 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, - 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, - 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, - 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, - 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, - 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, - 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, - 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, - 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, - 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, - 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, - 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, - 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, - 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, - 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, - 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, - 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, - 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, - 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, - 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, - 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, - 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, - 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, - 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, - 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, - 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, - 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, - 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, - 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, - 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, - 0xe6064b26}}; - -#endif - -#endif - -#if N == 3 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}, - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, - 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, - 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, - 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, - 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, - 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, - 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, - 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, - 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, - 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, - 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, - 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, - 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, - 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, - 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, - 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, - 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, - 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, - 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, - 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, - 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, - 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, - 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, - 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, - 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, - 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, - 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, - 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, - 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, - 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, - 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, - 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, - 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, - 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, - 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, - 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, - 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, - 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, - 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, - 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, - 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, - 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, - 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, - 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, - 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, - 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, - 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, - 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, - 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, - 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, - 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, - 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, - 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, - 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, - 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, - 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, - 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, - 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, - 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, - 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, - 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, - 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, - 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, - 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, - 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, - 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, - 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, - 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, - 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, - 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, - 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, - 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, - 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, - 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, - 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, - 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, - 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, - 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, - 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, - 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, - 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, - 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, - 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, - 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, - 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, - 0x4e36ba1800000000}, - {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, - 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, - 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, - 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, - 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, - 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, - 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, - 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, - 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, - 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, - 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, - 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, - 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, - 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, - 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, - 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, - 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, - 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, - 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, - 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, - 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, - 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, - 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, - 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, - 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, - 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, - 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, - 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, - 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, - 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, - 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, - 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, - 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, - 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, - 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, - 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, - 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, - 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, - 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, - 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, - 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, - 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, - 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, - 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, - 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, - 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, - 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, - 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, - 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, - 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, - 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, - 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, - 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, - 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, - 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, - 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, - 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, - 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, - 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, - 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, - 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, - 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, - 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, - 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, - 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, - 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, - 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, - 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, - 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, - 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, - 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, - 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, - 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, - 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, - 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, - 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, - 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, - 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, - 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, - 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, - 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, - 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, - 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, - 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, - 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, - 0xa1d67c9100000000}, - {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, - 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, - 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, - 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, - 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, - 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, - 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, - 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, - 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, - 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, - 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, - 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, - 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, - 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, - 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, - 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, - 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, - 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, - 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, - 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, - 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, - 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, - 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, - 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, - 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, - 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, - 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, - 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, - 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, - 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, - 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, - 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, - 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, - 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, - 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, - 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, - 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, - 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, - 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, - 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, - 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, - 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, - 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, - 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, - 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, - 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, - 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, - 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, - 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, - 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, - 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, - 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, - 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, - 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, - 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, - 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, - 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, - 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, - 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, - 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, - 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, - 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, - 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, - 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, - 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, - 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, - 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, - 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, - 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, - 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, - 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, - 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, - 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, - 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, - 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, - 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, - 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, - 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, - 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, - 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, - 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, - 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, - 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, - 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, - 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, - 0xa8ef40a100000000}, - {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, - 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, - 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, - 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, - 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, - 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, - 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, - 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, - 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, - 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, - 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, - 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, - 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, - 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, - 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, - 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, - 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, - 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, - 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, - 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, - 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, - 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, - 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, - 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, - 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, - 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, - 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, - 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, - 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, - 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, - 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, - 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, - 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, - 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, - 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, - 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, - 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, - 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, - 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, - 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, - 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, - 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, - 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, - 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, - 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, - 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, - 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, - 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, - 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, - 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, - 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, - 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, - 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, - 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, - 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, - 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, - 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, - 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, - 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, - 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, - 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, - 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, - 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, - 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, - 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, - 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, - 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, - 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, - 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, - 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, - 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, - 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, - 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, - 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, - 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, - 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, - 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, - 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, - 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, - 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, - 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, - 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, - 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, - 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, - 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, - 0x356bacd800000000}, - {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, - 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, - 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, - 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, - 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, - 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, - 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, - 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, - 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, - 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, - 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, - 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, - 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, - 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, - 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, - 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, - 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, - 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, - 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, - 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, - 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, - 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, - 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, - 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, - 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, - 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, - 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, - 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, - 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, - 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, - 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, - 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, - 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, - 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, - 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, - 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, - 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, - 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, - 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, - 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, - 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, - 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, - 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, - 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, - 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, - 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, - 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, - 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, - 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, - 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, - 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, - 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, - 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, - 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, - 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, - 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, - 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, - 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, - 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, - 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, - 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, - 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, - 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, - 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, - 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, - 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, - 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, - 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, - 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, - 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, - 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, - 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, - 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, - 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, - 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, - 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, - 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, - 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, - 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, - 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, - 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, - 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, - 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, - 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, - 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, - 0x48686b5600000000}, - {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, - 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, - 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, - 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, - 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, - 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, - 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, - 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, - 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, - 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, - 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, - 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, - 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, - 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, - 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, - 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, - 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, - 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, - 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, - 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, - 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, - 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, - 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, - 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, - 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, - 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, - 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, - 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, - 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, - 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, - 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, - 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, - 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, - 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, - 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, - 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, - 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, - 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, - 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, - 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, - 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, - 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, - 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, - 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, - 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, - 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, - 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, - 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, - 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, - 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, - 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, - 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, - 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, - 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, - 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, - 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, - 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, - 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, - 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, - 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, - 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, - 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, - 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, - 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, - 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, - 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, - 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, - 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, - 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, - 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, - 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, - 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, - 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, - 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, - 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, - 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, - 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, - 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, - 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, - 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, - 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, - 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, - 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, - 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, - 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, - 0xcaa2517800000000}, - {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, - 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, - 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, - 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, - 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, - 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, - 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, - 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, - 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, - 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, - 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, - 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, - 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, - 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, - 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, - 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, - 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, - 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, - 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, - 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, - 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, - 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, - 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, - 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, - 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, - 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, - 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, - 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, - 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, - 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, - 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, - 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, - 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, - 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, - 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, - 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, - 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, - 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, - 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, - 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, - 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, - 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, - 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, - 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, - 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, - 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, - 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, - 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, - 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, - 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, - 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, - 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, - 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, - 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, - 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, - 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, - 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, - 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, - 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, - 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, - 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, - 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, - 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, - 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, - 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, - 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, - 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, - 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, - 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, - 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, - 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, - 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, - 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, - 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, - 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, - 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, - 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, - 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, - 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, - 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, - 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, - 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, - 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, - 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, - 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, - 0x0c7ac97b00000000}, - {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, - 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, - 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, - 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, - 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, - 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, - 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, - 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, - 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, - 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, - 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, - 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, - 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, - 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, - 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, - 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, - 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, - 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, - 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, - 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, - 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, - 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, - 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, - 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, - 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, - 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, - 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, - 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, - 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, - 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, - 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, - 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, - 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, - 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, - 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, - 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, - 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, - 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, - 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, - 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, - 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, - 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, - 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, - 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, - 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, - 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, - 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, - 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, - 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, - 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, - 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, - 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, - 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, - 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, - 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, - 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, - 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, - 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, - 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, - 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, - 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, - 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, - 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, - 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, - 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, - 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, - 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, - 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, - 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, - 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, - 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, - 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, - 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, - 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, - 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, - 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, - 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, - 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, - 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, - 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, - 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, - 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, - 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, - 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, - 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, - 0x5185cd0900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, - 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, - 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, - 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, - 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, - 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, - 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, - 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, - 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, - 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, - 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, - 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, - 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, - 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, - 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, - 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, - 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, - 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, - 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, - 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, - 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, - 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, - 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, - 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, - 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, - 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, - 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, - 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, - 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, - 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, - 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, - 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, - 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, - 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, - 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, - 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, - 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, - 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, - 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, - 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, - 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, - 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, - 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, - 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, - 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, - 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, - 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, - 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, - 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, - 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, - 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, - 0x4b0c4f49}, - {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, - 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, - 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, - 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, - 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, - 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, - 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, - 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, - 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, - 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, - 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, - 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, - 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, - 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, - 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, - 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, - 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, - 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, - 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, - 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, - 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, - 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, - 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, - 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, - 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, - 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, - 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, - 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, - 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, - 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, - 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, - 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, - 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, - 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, - 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, - 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, - 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, - 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, - 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, - 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, - 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, - 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, - 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, - 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, - 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, - 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, - 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, - 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, - 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, - 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, - 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, - 0x14d747e1}, - {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, - 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, - 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, - 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, - 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, - 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, - 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, - 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, - 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, - 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, - 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, - 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, - 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, - 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, - 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, - 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, - 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, - 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, - 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, - 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, - 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, - 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, - 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, - 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, - 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, - 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, - 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, - 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, - 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, - 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, - 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, - 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, - 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, - 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, - 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, - 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, - 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, - 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, - 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, - 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, - 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, - 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, - 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, - 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, - 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, - 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, - 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, - 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, - 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, - 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, - 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, - 0xaa933b1a}, - {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, - 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, - 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, - 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, - 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, - 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, - 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, - 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, - 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, - 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, - 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, - 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, - 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, - 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, - 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, - 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, - 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, - 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, - 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, - 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, - 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, - 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, - 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, - 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, - 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, - 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, - 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, - 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, - 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, - 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, - 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, - 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, - 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, - 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, - 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, - 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, - 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, - 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, - 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, - 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, - 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, - 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, - 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, - 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, - 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, - 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, - 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, - 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, - 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, - 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, - 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, - 0x65711936}}; - -#endif - -#endif - -#if N == 4 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, - 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, - 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, - 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, - 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, - 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, - 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, - 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, - 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, - 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, - 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, - 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, - 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, - 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, - 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, - 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, - 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, - 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, - 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, - 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, - 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, - 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, - 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, - 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, - 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, - 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, - 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, - 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, - 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, - 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, - 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, - 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, - 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, - 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, - 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, - 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, - 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, - 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, - 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, - 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, - 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, - 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, - 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, - 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, - 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, - 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, - 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, - 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, - 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, - 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, - 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, - 0xe3c45916}, - {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, - 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, - 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, - 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, - 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, - 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, - 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, - 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, - 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, - 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, - 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, - 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, - 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, - 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, - 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, - 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, - 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, - 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, - 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, - 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, - 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, - 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, - 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, - 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, - 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, - 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, - 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, - 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, - 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, - 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, - 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, - 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, - 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, - 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, - 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, - 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, - 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, - 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, - 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, - 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, - 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, - 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, - 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, - 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, - 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, - 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, - 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, - 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, - 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, - 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, - 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, - 0xa7520488}, - {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, - 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, - 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, - 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, - 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, - 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, - 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, - 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, - 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, - 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, - 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, - 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, - 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, - 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, - 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, - 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, - 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, - 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, - 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, - 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, - 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, - 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, - 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, - 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, - 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, - 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, - 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, - 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, - 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, - 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, - 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, - 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, - 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, - 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, - 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, - 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, - 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, - 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, - 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, - 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, - 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, - 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, - 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, - 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, - 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, - 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, - 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, - 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, - 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, - 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, - 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, - 0x3522e9e4}, - {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, - 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, - 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, - 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, - 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, - 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, - 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, - 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, - 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, - 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, - 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, - 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, - 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, - 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, - 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, - 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, - 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, - 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, - 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, - 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, - 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, - 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, - 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, - 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, - 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, - 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, - 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, - 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, - 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, - 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, - 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, - 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, - 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, - 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, - 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, - 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, - 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, - 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, - 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, - 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, - 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, - 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, - 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, - 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, - 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, - 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, - 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, - 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, - 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, - 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, - 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, - 0x97411e28}, - {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, - 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, - 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, - 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, - 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, - 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, - 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, - 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, - 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, - 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, - 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, - 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, - 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, - 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, - 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, - 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, - 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, - 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, - 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, - 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, - 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, - 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, - 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, - 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, - 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, - 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, - 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, - 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, - 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, - 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, - 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, - 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, - 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, - 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, - 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, - 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, - 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, - 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, - 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, - 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, - 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, - 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, - 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, - 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, - 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, - 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, - 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, - 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, - 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, - 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, - 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, - 0x93c7a00b}, - {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, - 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, - 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, - 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, - 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, - 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, - 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, - 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, - 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, - 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, - 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, - 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, - 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, - 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, - 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, - 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, - 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, - 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, - 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, - 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, - 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, - 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, - 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, - 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, - 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, - 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, - 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, - 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, - 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, - 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, - 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, - 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, - 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, - 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, - 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, - 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, - 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, - 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, - 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, - 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, - 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, - 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, - 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, - 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, - 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, - 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, - 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, - 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, - 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, - 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, - 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, - 0xce5f968d}, - {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, - 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, - 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, - 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, - 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, - 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, - 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, - 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, - 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, - 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, - 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, - 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, - 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, - 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, - 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, - 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, - 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, - 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, - 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, - 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, - 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, - 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, - 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, - 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, - 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, - 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, - 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, - 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, - 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, - 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, - 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, - 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, - 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, - 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, - 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, - 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, - 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, - 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, - 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, - 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, - 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, - 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, - 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, - 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, - 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, - 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, - 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, - 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, - 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, - 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, - 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, - 0x3e721277}, - {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, - 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, - 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, - 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, - 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, - 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, - 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, - 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, - 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, - 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, - 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, - 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, - 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, - 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, - 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, - 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, - 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, - 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, - 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, - 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, - 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, - 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, - 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, - 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, - 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, - 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, - 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, - 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, - 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, - 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, - 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, - 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, - 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, - 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, - 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, - 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, - 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, - 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, - 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, - 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, - 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, - 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, - 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, - 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, - 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, - 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, - 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, - 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, - 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, - 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, - 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, - 0x1c65ace7}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, - 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, - 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, - 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, - 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, - 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, - 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, - 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, - 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, - 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, - 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, - 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, - 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, - 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, - 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, - 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, - 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, - 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, - 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, - 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, - 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, - 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, - 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, - 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, - 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, - 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, - 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, - 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, - 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, - 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, - 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, - 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, - 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, - 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, - 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, - 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, - 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, - 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, - 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, - 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, - 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, - 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, - 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, - 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, - 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, - 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, - 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, - 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, - 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, - 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, - 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, - 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, - 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, - 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, - 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, - 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, - 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, - 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, - 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, - 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, - 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, - 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, - 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, - 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, - 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, - 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, - 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, - 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, - 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, - 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, - 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, - 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, - 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, - 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, - 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, - 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, - 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, - 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, - 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, - 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, - 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, - 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, - 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, - 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, - 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, - 0xe7ac651c00000000}, - {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, - 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, - 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, - 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, - 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, - 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, - 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, - 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, - 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, - 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, - 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, - 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, - 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, - 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, - 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, - 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, - 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, - 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, - 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, - 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, - 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, - 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, - 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, - 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, - 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, - 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, - 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, - 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, - 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, - 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, - 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, - 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, - 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, - 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, - 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, - 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, - 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, - 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, - 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, - 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, - 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, - 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, - 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, - 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, - 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, - 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, - 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, - 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, - 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, - 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, - 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, - 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, - 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, - 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, - 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, - 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, - 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, - 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, - 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, - 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, - 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, - 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, - 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, - 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, - 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, - 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, - 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, - 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, - 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, - 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, - 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, - 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, - 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, - 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, - 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, - 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, - 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, - 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, - 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, - 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, - 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, - 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, - 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, - 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, - 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, - 0x7712723e00000000}, - {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, - 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, - 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, - 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, - 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, - 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, - 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, - 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, - 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, - 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, - 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, - 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, - 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, - 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, - 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, - 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, - 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, - 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, - 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, - 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, - 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, - 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, - 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, - 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, - 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, - 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, - 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, - 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, - 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, - 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, - 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, - 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, - 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, - 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, - 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, - 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, - 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, - 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, - 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, - 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, - 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, - 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, - 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, - 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, - 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, - 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, - 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, - 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, - 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, - 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, - 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, - 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, - 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, - 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, - 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, - 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, - 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, - 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, - 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, - 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, - 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, - 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, - 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, - 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, - 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, - 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, - 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, - 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, - 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, - 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, - 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, - 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, - 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, - 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, - 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, - 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, - 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, - 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, - 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, - 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, - 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, - 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, - 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, - 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, - 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, - 0x8d965fce00000000}, - {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, - 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, - 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, - 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, - 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, - 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, - 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, - 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, - 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, - 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, - 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, - 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, - 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, - 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, - 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, - 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, - 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, - 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, - 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, - 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, - 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, - 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, - 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, - 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, - 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, - 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, - 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, - 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, - 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, - 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, - 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, - 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, - 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, - 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, - 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, - 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, - 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, - 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, - 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, - 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, - 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, - 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, - 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, - 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, - 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, - 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, - 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, - 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, - 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, - 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, - 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, - 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, - 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, - 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, - 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, - 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, - 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, - 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, - 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, - 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, - 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, - 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, - 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, - 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, - 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, - 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, - 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, - 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, - 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, - 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, - 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, - 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, - 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, - 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, - 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, - 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, - 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, - 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, - 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, - 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, - 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, - 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, - 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, - 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, - 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, - 0x0ba0c79300000000}, - {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, - 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, - 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, - 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, - 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, - 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, - 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, - 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, - 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, - 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, - 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, - 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, - 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, - 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, - 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, - 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, - 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, - 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, - 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, - 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, - 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, - 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, - 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, - 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, - 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, - 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, - 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, - 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, - 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, - 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, - 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, - 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, - 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, - 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, - 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, - 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, - 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, - 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, - 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, - 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, - 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, - 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, - 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, - 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, - 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, - 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, - 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, - 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, - 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, - 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, - 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, - 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, - 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, - 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, - 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, - 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, - 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, - 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, - 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, - 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, - 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, - 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, - 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, - 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, - 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, - 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, - 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, - 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, - 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, - 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, - 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, - 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, - 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, - 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, - 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, - 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, - 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, - 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, - 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, - 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, - 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, - 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, - 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, - 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, - 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, - 0x281e419700000000}, - {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, - 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, - 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, - 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, - 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, - 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, - 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, - 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, - 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, - 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, - 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, - 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, - 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, - 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, - 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, - 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, - 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, - 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, - 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, - 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, - 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, - 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, - 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, - 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, - 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, - 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, - 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, - 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, - 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, - 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, - 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, - 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, - 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, - 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, - 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, - 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, - 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, - 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, - 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, - 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, - 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, - 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, - 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, - 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, - 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, - 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, - 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, - 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, - 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, - 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, - 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, - 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, - 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, - 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, - 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, - 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, - 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, - 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, - 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, - 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, - 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, - 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, - 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, - 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, - 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, - 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, - 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, - 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, - 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, - 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, - 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, - 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, - 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, - 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, - 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, - 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, - 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, - 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, - 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, - 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, - 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, - 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, - 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, - 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, - 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, - 0xe4e9223500000000}, - {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, - 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, - 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, - 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, - 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, - 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, - 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, - 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, - 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, - 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, - 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, - 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, - 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, - 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, - 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, - 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, - 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, - 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, - 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, - 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, - 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, - 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, - 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, - 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, - 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, - 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, - 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, - 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, - 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, - 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, - 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, - 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, - 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, - 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, - 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, - 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, - 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, - 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, - 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, - 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, - 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, - 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, - 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, - 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, - 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, - 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, - 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, - 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, - 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, - 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, - 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, - 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, - 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, - 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, - 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, - 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, - 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, - 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, - 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, - 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, - 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, - 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, - 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, - 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, - 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, - 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, - 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, - 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, - 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, - 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, - 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, - 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, - 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, - 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, - 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, - 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, - 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, - 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, - 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, - 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, - 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, - 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, - 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, - 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, - 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, - 0x880452a700000000}, - {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, - 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, - 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, - 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, - 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, - 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, - 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, - 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, - 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, - 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, - 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, - 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, - 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, - 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, - 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, - 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, - 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, - 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, - 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, - 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, - 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, - 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, - 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, - 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, - 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, - 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, - 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, - 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, - 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, - 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, - 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, - 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, - 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, - 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, - 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, - 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, - 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, - 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, - 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, - 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, - 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, - 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, - 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, - 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, - 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, - 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, - 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, - 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, - 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, - 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, - 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, - 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, - 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, - 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, - 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, - 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, - 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, - 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, - 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, - 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, - 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, - 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, - 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, - 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, - 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, - 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, - 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, - 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, - 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, - 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, - 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, - 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, - 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, - 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, - 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, - 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, - 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, - 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, - 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, - 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, - 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, - 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, - 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, - 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, - 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, - 0x1659c4e300000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, - 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, - 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, - 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, - 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, - 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, - 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, - 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, - 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, - 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, - 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, - 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, - 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, - 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, - 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, - 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, - 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, - 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, - 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, - 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, - 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, - 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, - 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, - 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, - 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, - 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, - 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, - 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, - 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, - 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, - 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, - 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, - 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, - 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, - 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, - 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, - 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, - 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, - 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, - 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, - 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, - 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, - 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, - 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, - 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, - 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, - 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, - 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, - 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, - 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, - 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, - 0xa68cee3d}, - {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, - 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, - 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, - 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, - 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, - 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, - 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, - 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, - 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, - 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, - 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, - 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, - 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, - 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, - 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, - 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, - 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, - 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, - 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, - 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, - 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, - 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, - 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, - 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, - 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, - 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, - 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, - 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, - 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, - 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, - 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, - 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, - 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, - 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, - 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, - 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, - 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, - 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, - 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, - 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, - 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, - 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, - 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, - 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, - 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, - 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, - 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, - 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, - 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, - 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, - 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, - 0x51e8883f}, - {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, - 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, - 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, - 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, - 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, - 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, - 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, - 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, - 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, - 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, - 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, - 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, - 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, - 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, - 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, - 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, - 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, - 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, - 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, - 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, - 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, - 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, - 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, - 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, - 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, - 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, - 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, - 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, - 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, - 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, - 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, - 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, - 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, - 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, - 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, - 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, - 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, - 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, - 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, - 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, - 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, - 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, - 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, - 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, - 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, - 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, - 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, - 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, - 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, - 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, - 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, - 0x8ae9531c}, - {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, - 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, - 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, - 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, - 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, - 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, - 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, - 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, - 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, - 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, - 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, - 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, - 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, - 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, - 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, - 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, - 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, - 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, - 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, - 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, - 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, - 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, - 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, - 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, - 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, - 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, - 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, - 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, - 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, - 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, - 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, - 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, - 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, - 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, - 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, - 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, - 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, - 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, - 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, - 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, - 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, - 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, - 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, - 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, - 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, - 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, - 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, - 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, - 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, - 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, - 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, - 0xd739710d}}; - -#endif - -#endif - -#if N == 5 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, - 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, - 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, - 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, - 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, - 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, - 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, - 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, - 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, - 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, - 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, - 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, - 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, - 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, - 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, - 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, - 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, - 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, - 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, - 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, - 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, - 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, - 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, - 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, - 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, - 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, - 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, - 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, - 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, - 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, - 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, - 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, - 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, - 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, - 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, - 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, - 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, - 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, - 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, - 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, - 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, - 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, - 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, - 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, - 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, - 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, - 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, - 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, - 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, - 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, - 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, - 0xe9947565}, - {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, - 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, - 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, - 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, - 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, - 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, - 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, - 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, - 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, - 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, - 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, - 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, - 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, - 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, - 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, - 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, - 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, - 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, - 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, - 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, - 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, - 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, - 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, - 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, - 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, - 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, - 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, - 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, - 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, - 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, - 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, - 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, - 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, - 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, - 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, - 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, - 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, - 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, - 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, - 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, - 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, - 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, - 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, - 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, - 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, - 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, - 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, - 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, - 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, - 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, - 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, - 0xf7d05006}, - {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, - 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, - 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, - 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, - 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, - 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, - 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, - 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, - 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, - 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, - 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, - 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, - 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, - 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, - 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, - 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, - 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, - 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, - 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, - 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, - 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, - 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, - 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, - 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, - 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, - 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, - 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, - 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, - 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, - 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, - 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, - 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, - 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, - 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, - 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, - 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, - 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, - 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, - 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, - 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, - 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, - 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, - 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, - 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, - 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, - 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, - 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, - 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, - 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, - 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, - 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, - 0xb2075b94}, - {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, - 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, - 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, - 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, - 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, - 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, - 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, - 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, - 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, - 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, - 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, - 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, - 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, - 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, - 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, - 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, - 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, - 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, - 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, - 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, - 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, - 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, - 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, - 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, - 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, - 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, - 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, - 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, - 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, - 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, - 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, - 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, - 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, - 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, - 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, - 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, - 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, - 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, - 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, - 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, - 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, - 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, - 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, - 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, - 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, - 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, - 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, - 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, - 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, - 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, - 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, - 0xba50bcb9}, - {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, - 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, - 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, - 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, - 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, - 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, - 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, - 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, - 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, - 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, - 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, - 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, - 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, - 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, - 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, - 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, - 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, - 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, - 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, - 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, - 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, - 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, - 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, - 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, - 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, - 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, - 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, - 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, - 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, - 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, - 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, - 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, - 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, - 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, - 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, - 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, - 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, - 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, - 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, - 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, - 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, - 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, - 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, - 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, - 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, - 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, - 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, - 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, - 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, - 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, - 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, - 0x808abcf4}, - {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, - 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, - 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, - 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, - 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, - 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, - 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, - 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, - 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, - 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, - 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, - 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, - 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, - 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, - 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, - 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, - 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, - 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, - 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, - 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, - 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, - 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, - 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, - 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, - 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, - 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, - 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, - 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, - 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, - 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, - 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, - 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, - 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, - 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, - 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, - 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, - 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, - 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, - 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, - 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, - 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, - 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, - 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, - 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, - 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, - 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, - 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, - 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, - 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, - 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, - 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, - 0xefdb3f95}, - {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, - 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, - 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, - 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, - 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, - 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, - 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, - 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, - 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, - 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, - 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, - 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, - 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, - 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, - 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, - 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, - 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, - 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, - 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, - 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, - 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, - 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, - 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, - 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, - 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, - 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, - 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, - 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, - 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, - 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, - 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, - 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, - 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, - 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, - 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, - 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, - 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, - 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, - 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, - 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, - 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, - 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, - 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, - 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, - 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, - 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, - 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, - 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, - 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, - 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, - 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, - 0x0e2fbf43}, - {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, - 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, - 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, - 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, - 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, - 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, - 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, - 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, - 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, - 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, - 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, - 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, - 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, - 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, - 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, - 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, - 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, - 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, - 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, - 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, - 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, - 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, - 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, - 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, - 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, - 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, - 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, - 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, - 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, - 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, - 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, - 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, - 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, - 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, - 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, - 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, - 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, - 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, - 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, - 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, - 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, - 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, - 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, - 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, - 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, - 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, - 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, - 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, - 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, - 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, - 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, - 0xf4377108}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, - 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, - 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, - 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, - 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, - 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, - 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, - 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, - 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, - 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, - 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, - 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, - 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, - 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, - 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, - 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, - 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, - 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, - 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, - 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, - 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, - 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, - 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, - 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, - 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, - 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, - 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, - 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, - 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, - 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, - 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, - 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, - 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, - 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, - 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, - 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, - 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, - 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, - 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, - 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, - 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, - 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, - 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, - 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, - 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, - 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, - 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, - 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, - 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, - 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, - 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, - 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, - 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, - 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, - 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, - 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, - 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, - 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, - 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, - 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, - 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, - 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, - 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, - 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, - 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, - 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, - 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, - 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, - 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, - 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, - 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, - 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, - 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, - 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, - 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, - 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, - 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, - 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, - 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, - 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, - 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, - 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, - 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, - 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, - 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, - 0x087137f400000000}, - {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, - 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, - 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, - 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, - 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, - 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, - 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, - 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, - 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, - 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, - 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, - 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, - 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, - 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, - 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, - 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, - 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, - 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, - 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, - 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, - 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, - 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, - 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, - 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, - 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, - 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, - 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, - 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, - 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, - 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, - 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, - 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, - 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, - 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, - 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, - 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, - 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, - 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, - 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, - 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, - 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, - 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, - 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, - 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, - 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, - 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, - 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, - 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, - 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, - 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, - 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, - 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, - 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, - 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, - 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, - 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, - 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, - 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, - 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, - 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, - 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, - 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, - 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, - 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, - 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, - 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, - 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, - 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, - 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, - 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, - 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, - 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, - 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, - 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, - 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, - 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, - 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, - 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, - 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, - 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, - 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, - 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, - 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, - 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, - 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, - 0x43bf2f0e00000000}, - {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, - 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, - 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, - 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, - 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, - 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, - 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, - 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, - 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, - 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, - 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, - 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, - 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, - 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, - 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, - 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, - 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, - 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, - 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, - 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, - 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, - 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, - 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, - 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, - 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, - 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, - 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, - 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, - 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, - 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, - 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, - 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, - 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, - 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, - 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, - 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, - 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, - 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, - 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, - 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, - 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, - 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, - 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, - 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, - 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, - 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, - 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, - 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, - 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, - 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, - 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, - 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, - 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, - 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, - 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, - 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, - 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, - 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, - 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, - 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, - 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, - 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, - 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, - 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, - 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, - 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, - 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, - 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, - 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, - 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, - 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, - 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, - 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, - 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, - 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, - 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, - 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, - 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, - 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, - 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, - 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, - 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, - 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, - 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, - 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, - 0x953fdbef00000000}, - {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, - 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, - 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, - 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, - 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, - 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, - 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, - 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, - 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, - 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, - 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, - 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, - 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, - 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, - 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, - 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, - 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, - 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, - 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, - 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, - 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, - 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, - 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, - 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, - 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, - 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, - 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, - 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, - 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, - 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, - 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, - 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, - 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, - 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, - 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, - 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, - 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, - 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, - 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, - 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, - 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, - 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, - 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, - 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, - 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, - 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, - 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, - 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, - 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, - 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, - 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, - 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, - 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, - 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, - 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, - 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, - 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, - 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, - 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, - 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, - 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, - 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, - 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, - 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, - 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, - 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, - 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, - 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, - 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, - 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, - 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, - 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, - 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, - 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, - 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, - 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, - 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, - 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, - 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, - 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, - 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, - 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, - 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, - 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, - 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, - 0xf4bc8a8000000000}, - {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, - 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, - 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, - 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, - 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, - 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, - 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, - 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, - 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, - 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, - 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, - 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, - 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, - 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, - 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, - 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, - 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, - 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, - 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, - 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, - 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, - 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, - 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, - 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, - 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, - 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, - 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, - 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, - 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, - 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, - 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, - 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, - 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, - 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, - 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, - 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, - 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, - 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, - 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, - 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, - 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, - 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, - 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, - 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, - 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, - 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, - 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, - 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, - 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, - 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, - 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, - 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, - 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, - 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, - 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, - 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, - 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, - 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, - 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, - 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, - 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, - 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, - 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, - 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, - 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, - 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, - 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, - 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, - 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, - 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, - 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, - 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, - 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, - 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, - 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, - 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, - 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, - 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, - 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, - 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, - 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, - 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, - 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, - 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, - 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, - 0xb9bc50ba00000000}, - {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, - 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, - 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, - 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, - 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, - 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, - 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, - 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, - 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, - 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, - 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, - 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, - 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, - 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, - 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, - 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, - 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, - 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, - 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, - 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, - 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, - 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, - 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, - 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, - 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, - 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, - 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, - 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, - 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, - 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, - 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, - 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, - 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, - 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, - 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, - 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, - 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, - 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, - 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, - 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, - 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, - 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, - 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, - 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, - 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, - 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, - 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, - 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, - 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, - 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, - 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, - 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, - 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, - 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, - 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, - 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, - 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, - 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, - 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, - 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, - 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, - 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, - 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, - 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, - 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, - 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, - 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, - 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, - 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, - 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, - 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, - 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, - 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, - 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, - 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, - 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, - 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, - 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, - 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, - 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, - 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, - 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, - 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, - 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, - 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, - 0x945b07b200000000}, - {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, - 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, - 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, - 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, - 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, - 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, - 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, - 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, - 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, - 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, - 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, - 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, - 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, - 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, - 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, - 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, - 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, - 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, - 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, - 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, - 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, - 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, - 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, - 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, - 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, - 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, - 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, - 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, - 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, - 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, - 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, - 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, - 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, - 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, - 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, - 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, - 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, - 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, - 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, - 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, - 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, - 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, - 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, - 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, - 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, - 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, - 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, - 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, - 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, - 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, - 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, - 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, - 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, - 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, - 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, - 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, - 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, - 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, - 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, - 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, - 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, - 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, - 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, - 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, - 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, - 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, - 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, - 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, - 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, - 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, - 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, - 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, - 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, - 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, - 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, - 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, - 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, - 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, - 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, - 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, - 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, - 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, - 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, - 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, - 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, - 0x0650d0f700000000}, - {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, - 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, - 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, - 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, - 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, - 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, - 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, - 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, - 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, - 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, - 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, - 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, - 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, - 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, - 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, - 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, - 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, - 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, - 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, - 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, - 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, - 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, - 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, - 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, - 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, - 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, - 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, - 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, - 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, - 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, - 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, - 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, - 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, - 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, - 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, - 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, - 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, - 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, - 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, - 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, - 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, - 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, - 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, - 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, - 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, - 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, - 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, - 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, - 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, - 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, - 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, - 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, - 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, - 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, - 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, - 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, - 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, - 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, - 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, - 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, - 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, - 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, - 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, - 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, - 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, - 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, - 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, - 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, - 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, - 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, - 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, - 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, - 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, - 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, - 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, - 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, - 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, - 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, - 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, - 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, - 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, - 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, - 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, - 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, - 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, - 0x657594e900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, - 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, - 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, - 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, - 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, - 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, - 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, - 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, - 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, - 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, - 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, - 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, - 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, - 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, - 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, - 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, - 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, - 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, - 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, - 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, - 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, - 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, - 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, - 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, - 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, - 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, - 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, - 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, - 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, - 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, - 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, - 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, - 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, - 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, - 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, - 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, - 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, - 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, - 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, - 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, - 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, - 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, - 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, - 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, - 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, - 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, - 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, - 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, - 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, - 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, - 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, - 0x4e36ba18}, - {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, - 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, - 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, - 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, - 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, - 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, - 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, - 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, - 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, - 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, - 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, - 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, - 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, - 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, - 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, - 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, - 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, - 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, - 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, - 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, - 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, - 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, - 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, - 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, - 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, - 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, - 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, - 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, - 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, - 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, - 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, - 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, - 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, - 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, - 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, - 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, - 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, - 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, - 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, - 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, - 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, - 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, - 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, - 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, - 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, - 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, - 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, - 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, - 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, - 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, - 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, - 0xa1d67c91}, - {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, - 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, - 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, - 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, - 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, - 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, - 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, - 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, - 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, - 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, - 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, - 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, - 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, - 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, - 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, - 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, - 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, - 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, - 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, - 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, - 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, - 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, - 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, - 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, - 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, - 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, - 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, - 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, - 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, - 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, - 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, - 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, - 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, - 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, - 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, - 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, - 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, - 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, - 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, - 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, - 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, - 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, - 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, - 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, - 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, - 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, - 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, - 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, - 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, - 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, - 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, - 0xa8ef40a1}, - {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, - 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, - 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, - 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, - 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, - 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, - 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, - 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, - 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, - 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, - 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, - 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, - 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, - 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, - 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, - 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, - 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, - 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, - 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, - 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, - 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, - 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, - 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, - 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, - 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, - 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, - 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, - 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, - 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, - 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, - 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, - 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, - 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, - 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, - 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, - 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, - 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, - 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, - 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, - 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, - 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, - 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, - 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, - 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, - 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, - 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, - 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, - 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, - 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, - 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, - 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, - 0x356bacd8}}; - -#endif - -#endif - -#if N == 6 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, - 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, - 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, - 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, - 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, - 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, - 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, - 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, - 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, - 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, - 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, - 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, - 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, - 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, - 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, - 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, - 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, - 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, - 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, - 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, - 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, - 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, - 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, - 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, - 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, - 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, - 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, - 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, - 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, - 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, - 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, - 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, - 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, - 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, - 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, - 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, - 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, - 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, - 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, - 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, - 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, - 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, - 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, - 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, - 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, - 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, - 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, - 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, - 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, - 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, - 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, - 0x8568a0a8}, - {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, - 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, - 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, - 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, - 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, - 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, - 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, - 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, - 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, - 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, - 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, - 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, - 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, - 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, - 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, - 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, - 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, - 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, - 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, - 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, - 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, - 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, - 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, - 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, - 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, - 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, - 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, - 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, - 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, - 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, - 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, - 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, - 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, - 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, - 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, - 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, - 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, - 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, - 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, - 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, - 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, - 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, - 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, - 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, - 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, - 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, - 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, - 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, - 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, - 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, - 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, - 0x0d907052}, - {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, - 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, - 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, - 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, - 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, - 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, - 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, - 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, - 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, - 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, - 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, - 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, - 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, - 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, - 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, - 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, - 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, - 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, - 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, - 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, - 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, - 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, - 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, - 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, - 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, - 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, - 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, - 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, - 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, - 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, - 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, - 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, - 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, - 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, - 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, - 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, - 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, - 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, - 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, - 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, - 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, - 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, - 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, - 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, - 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, - 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, - 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, - 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, - 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, - 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, - 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, - 0xfd1a6c8a}, - {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, - 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, - 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, - 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, - 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, - 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, - 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, - 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, - 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, - 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, - 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, - 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, - 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, - 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, - 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, - 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, - 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, - 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, - 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, - 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, - 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, - 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, - 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, - 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, - 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, - 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, - 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, - 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, - 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, - 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, - 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, - 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, - 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, - 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, - 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, - 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, - 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, - 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, - 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, - 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, - 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, - 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, - 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, - 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, - 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, - 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, - 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, - 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, - 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, - 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, - 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, - 0x7895f01a}, - {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, - 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, - 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, - 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, - 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, - 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, - 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, - 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, - 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, - 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, - 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, - 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, - 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, - 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, - 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, - 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, - 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, - 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, - 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, - 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, - 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, - 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, - 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, - 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, - 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, - 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, - 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, - 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, - 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, - 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, - 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, - 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, - 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, - 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, - 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, - 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, - 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, - 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, - 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, - 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, - 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, - 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, - 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, - 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, - 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, - 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, - 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, - 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, - 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, - 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, - 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, - 0x9239b848}, - {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, - 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, - 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, - 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, - 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, - 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, - 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, - 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, - 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, - 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, - 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, - 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, - 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, - 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, - 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, - 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, - 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, - 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, - 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, - 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, - 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, - 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, - 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, - 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, - 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, - 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, - 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, - 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, - 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, - 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, - 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, - 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, - 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, - 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, - 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, - 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, - 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, - 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, - 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, - 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, - 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, - 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, - 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, - 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, - 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, - 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, - 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, - 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, - 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, - 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, - 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, - 0xeb36d3cc}, - {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, - 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, - 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, - 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, - 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, - 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, - 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, - 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, - 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, - 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, - 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, - 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, - 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, - 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, - 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, - 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, - 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, - 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, - 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, - 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, - 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, - 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, - 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, - 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, - 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, - 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, - 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, - 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, - 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, - 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, - 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, - 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, - 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, - 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, - 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, - 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, - 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, - 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, - 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, - 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, - 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, - 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, - 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, - 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, - 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, - 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, - 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, - 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, - 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, - 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, - 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, - 0x38e5f3c5}, - {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, - 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, - 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, - 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, - 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, - 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, - 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, - 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, - 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, - 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, - 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, - 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, - 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, - 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, - 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, - 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, - 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, - 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, - 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, - 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, - 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, - 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, - 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, - 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, - 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, - 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, - 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, - 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, - 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, - 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, - 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, - 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, - 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, - 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, - 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, - 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, - 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, - 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, - 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, - 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, - 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, - 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, - 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, - 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, - 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, - 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, - 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, - 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, - 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, - 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, - 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, - 0x3d3101a2}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, - 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, - 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, - 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, - 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, - 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, - 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, - 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, - 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, - 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, - 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, - 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, - 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, - 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, - 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, - 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, - 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, - 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, - 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, - 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, - 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, - 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, - 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, - 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, - 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, - 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, - 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, - 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, - 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, - 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, - 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, - 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, - 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, - 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, - 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, - 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, - 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, - 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, - 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, - 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, - 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, - 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, - 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, - 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, - 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, - 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, - 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, - 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, - 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, - 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, - 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, - 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, - 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, - 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, - 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, - 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, - 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, - 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, - 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, - 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, - 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, - 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, - 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, - 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, - 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, - 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, - 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, - 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, - 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, - 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, - 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, - 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, - 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, - 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, - 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, - 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, - 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, - 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, - 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, - 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, - 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, - 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, - 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, - 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, - 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, - 0xa201313d00000000}, - {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, - 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, - 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, - 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, - 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, - 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, - 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, - 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, - 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, - 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, - 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, - 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, - 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, - 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, - 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, - 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, - 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, - 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, - 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, - 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, - 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, - 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, - 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, - 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, - 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, - 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, - 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, - 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, - 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, - 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, - 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, - 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, - 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, - 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, - 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, - 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, - 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, - 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, - 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, - 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, - 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, - 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, - 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, - 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, - 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, - 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, - 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, - 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, - 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, - 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, - 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, - 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, - 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, - 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, - 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, - 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, - 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, - 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, - 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, - 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, - 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, - 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, - 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, - 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, - 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, - 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, - 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, - 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, - 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, - 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, - 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, - 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, - 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, - 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, - 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, - 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, - 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, - 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, - 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, - 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, - 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, - 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, - 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, - 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, - 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, - 0xc5f3e53800000000}, - {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, - 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, - 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, - 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, - 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, - 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, - 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, - 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, - 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, - 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, - 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, - 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, - 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, - 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, - 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, - 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, - 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, - 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, - 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, - 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, - 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, - 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, - 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, - 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, - 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, - 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, - 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, - 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, - 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, - 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, - 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, - 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, - 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, - 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, - 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, - 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, - 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, - 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, - 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, - 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, - 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, - 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, - 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, - 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, - 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, - 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, - 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, - 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, - 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, - 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, - 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, - 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, - 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, - 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, - 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, - 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, - 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, - 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, - 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, - 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, - 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, - 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, - 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, - 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, - 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, - 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, - 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, - 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, - 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, - 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, - 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, - 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, - 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, - 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, - 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, - 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, - 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, - 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, - 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, - 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, - 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, - 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, - 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, - 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, - 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, - 0xccd336eb00000000}, - {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, - 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, - 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, - 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, - 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, - 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, - 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, - 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, - 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, - 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, - 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, - 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, - 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, - 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, - 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, - 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, - 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, - 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, - 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, - 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, - 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, - 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, - 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, - 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, - 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, - 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, - 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, - 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, - 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, - 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, - 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, - 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, - 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, - 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, - 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, - 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, - 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, - 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, - 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, - 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, - 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, - 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, - 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, - 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, - 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, - 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, - 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, - 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, - 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, - 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, - 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, - 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, - 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, - 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, - 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, - 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, - 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, - 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, - 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, - 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, - 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, - 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, - 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, - 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, - 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, - 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, - 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, - 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, - 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, - 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, - 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, - 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, - 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, - 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, - 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, - 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, - 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, - 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, - 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, - 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, - 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, - 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, - 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, - 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, - 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, - 0x48b8399200000000}, - {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, - 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, - 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, - 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, - 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, - 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, - 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, - 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, - 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, - 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, - 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, - 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, - 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, - 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, - 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, - 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, - 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, - 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, - 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, - 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, - 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, - 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, - 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, - 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, - 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, - 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, - 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, - 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, - 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, - 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, - 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, - 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, - 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, - 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, - 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, - 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, - 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, - 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, - 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, - 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, - 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, - 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, - 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, - 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, - 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, - 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, - 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, - 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, - 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, - 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, - 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, - 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, - 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, - 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, - 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, - 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, - 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, - 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, - 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, - 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, - 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, - 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, - 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, - 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, - 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, - 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, - 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, - 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, - 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, - 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, - 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, - 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, - 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, - 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, - 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, - 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, - 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, - 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, - 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, - 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, - 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, - 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, - 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, - 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, - 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, - 0x1af0957800000000}, - {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, - 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, - 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, - 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, - 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, - 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, - 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, - 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, - 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, - 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, - 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, - 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, - 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, - 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, - 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, - 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, - 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, - 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, - 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, - 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, - 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, - 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, - 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, - 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, - 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, - 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, - 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, - 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, - 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, - 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, - 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, - 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, - 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, - 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, - 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, - 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, - 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, - 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, - 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, - 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, - 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, - 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, - 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, - 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, - 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, - 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, - 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, - 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, - 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, - 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, - 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, - 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, - 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, - 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, - 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, - 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, - 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, - 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, - 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, - 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, - 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, - 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, - 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, - 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, - 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, - 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, - 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, - 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, - 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, - 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, - 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, - 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, - 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, - 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, - 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, - 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, - 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, - 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, - 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, - 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, - 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, - 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, - 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, - 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, - 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, - 0x8a6c1afd00000000}, - {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, - 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, - 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, - 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, - 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, - 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, - 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, - 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, - 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, - 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, - 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, - 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, - 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, - 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, - 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, - 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, - 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, - 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, - 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, - 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, - 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, - 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, - 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, - 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, - 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, - 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, - 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, - 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, - 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, - 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, - 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, - 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, - 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, - 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, - 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, - 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, - 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, - 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, - 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, - 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, - 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, - 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, - 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, - 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, - 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, - 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, - 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, - 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, - 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, - 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, - 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, - 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, - 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, - 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, - 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, - 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, - 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, - 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, - 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, - 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, - 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, - 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, - 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, - 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, - 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, - 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, - 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, - 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, - 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, - 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, - 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, - 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, - 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, - 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, - 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, - 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, - 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, - 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, - 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, - 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, - 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, - 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, - 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, - 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, - 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, - 0x5270900d00000000}, - {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, - 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, - 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, - 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, - 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, - 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, - 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, - 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, - 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, - 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, - 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, - 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, - 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, - 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, - 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, - 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, - 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, - 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, - 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, - 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, - 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, - 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, - 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, - 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, - 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, - 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, - 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, - 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, - 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, - 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, - 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, - 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, - 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, - 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, - 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, - 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, - 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, - 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, - 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, - 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, - 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, - 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, - 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, - 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, - 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, - 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, - 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, - 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, - 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, - 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, - 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, - 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, - 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, - 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, - 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, - 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, - 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, - 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, - 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, - 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, - 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, - 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, - 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, - 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, - 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, - 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, - 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, - 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, - 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, - 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, - 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, - 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, - 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, - 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, - 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, - 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, - 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, - 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, - 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, - 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, - 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, - 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, - 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, - 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, - 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, - 0xa8a0688500000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, - 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, - 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, - 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, - 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, - 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, - 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, - 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, - 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, - 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, - 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, - 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, - 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, - 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, - 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, - 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, - 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, - 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, - 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, - 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, - 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, - 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, - 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, - 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, - 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, - 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, - 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, - 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, - 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, - 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, - 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, - 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, - 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, - 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, - 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, - 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, - 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, - 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, - 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, - 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, - 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, - 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, - 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, - 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, - 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, - 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, - 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, - 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, - 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, - 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, - 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, - 0x48686b56}, - {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, - 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, - 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, - 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, - 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, - 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, - 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, - 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, - 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, - 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, - 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, - 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, - 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, - 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, - 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, - 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, - 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, - 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, - 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, - 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, - 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, - 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, - 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, - 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, - 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, - 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, - 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, - 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, - 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, - 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, - 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, - 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, - 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, - 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, - 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, - 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, - 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, - 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, - 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, - 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, - 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, - 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, - 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, - 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, - 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, - 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, - 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, - 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, - 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, - 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, - 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, - 0xcaa25178}, - {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, - 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, - 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, - 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, - 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, - 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, - 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, - 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, - 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, - 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, - 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, - 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, - 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, - 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, - 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, - 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, - 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, - 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, - 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, - 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, - 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, - 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, - 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, - 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, - 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, - 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, - 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, - 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, - 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, - 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, - 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, - 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, - 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, - 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, - 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, - 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, - 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, - 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, - 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, - 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, - 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, - 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, - 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, - 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, - 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, - 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, - 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, - 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, - 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, - 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, - 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, - 0x0c7ac97b}, - {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, - 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, - 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, - 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, - 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, - 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, - 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, - 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, - 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, - 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, - 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, - 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, - 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, - 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, - 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, - 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, - 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, - 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, - 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, - 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, - 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, - 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, - 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, - 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, - 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, - 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, - 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, - 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, - 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, - 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, - 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, - 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, - 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, - 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, - 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, - 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, - 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, - 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, - 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, - 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, - 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, - 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, - 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, - 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, - 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, - 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, - 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, - 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, - 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, - 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, - 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, - 0x5185cd09}}; - -#endif - -#endif - -#endif - -local const z_crc_t FAR x2n_table[] = { - 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, - 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, - 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, - 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, - 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, - 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, - 0xc40ba6d0, 0xc4e22c3c}; diff --git a/Library/OcCompressionLib/zlib/deflate.c b/Library/OcCompressionLib/zlib/deflate.c deleted file mode 100644 index 23aef1878..000000000 --- a/Library/OcCompressionLib/zlib/deflate.c +++ /dev/null @@ -1,2211 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.11.1 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV -# pragma message("Assembler code may have bugs -- use at your own risk") - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - do { \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, \ - (unsigned)(s->hash_size-1)*sizeof(*s->head)); \ - } while (0) - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -local void slide_hash(s) - deflate_state *s; -{ - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); - s->pending_buf_size = (ulg)s->lit_bufsize * 4; - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->sym_buf = s->pending_buf + s->lit_bufsize; - s->sym_end = (s->lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck (strm) - z_streamp strm; -{ - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - INIT_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = -2; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (deflateStateCheck(strm)) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE && s->wrap == 0) - s->status = BUSY_STATE; - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->sym_buf = ds->pending_buf + ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last = 0; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - s->insert = s->strstart; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - s->insert += MIN(used, s->w_size - s->insert); - } - s->block_start = s->strstart; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) - return finish_done; - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - s->insert += MIN(have, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/Library/OcCompressionLib/zlib/deflate.h b/Library/OcCompressionLib/zlib/deflate.h deleted file mode 100644 index d4cf1a98b..000000000 --- a/Library/OcCompressionLib/zlib/deflate.h +++ /dev/null @@ -1,346 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2016 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *sym_buf; /* buffer for distances and literals/lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt sym_next; /* running index in sym_buf */ - uInt sym_end; /* symbol table full when sym_next reaches this */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->sym_buf[s->sym_next++] = dist; \ - s->sym_buf[s->sym_next++] = dist >> 8; \ - s->sym_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/Library/OcCompressionLib/zlib/infback.c b/Library/OcCompressionLib/zlib/infback.c deleted file mode 100644 index 59679ecbf..000000000 --- a/Library/OcCompressionLib/zlib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/Library/OcCompressionLib/zlib/inffast.c b/Library/OcCompressionLib/zlib/inffast.c deleted file mode 100644 index 1fec7f363..000000000 --- a/Library/OcCompressionLib/zlib/inffast.c +++ /dev/null @@ -1,323 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code const *here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode + (hold & lmask); - dolen: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op == 0) { /* literal */ - Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here->val)); - *out++ = (unsigned char)(here->val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode + (hold & dmask); - dodist: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode + here->val + (hold & ((1U << op) - 1)); - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode + here->val + (hold & ((1U << op) - 1)); - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/Library/OcCompressionLib/zlib/inffast.h b/Library/OcCompressionLib/zlib/inffast.h deleted file mode 100644 index e5c1aa4ca..000000000 --- a/Library/OcCompressionLib/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/Library/OcCompressionLib/zlib/inffixed.h b/Library/OcCompressionLib/zlib/inffixed.h deleted file mode 100644 index d62832776..000000000 --- a/Library/OcCompressionLib/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/Library/OcCompressionLib/zlib/inflate.c b/Library/OcCompressionLib/zlib/inflate.c deleted file mode 100644 index a6b342ec2..000000000 --- a/Library/OcCompressionLib/zlib/inflate.c +++ /dev/null @@ -1,1607 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->flags = -1; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef OC_INFLATE_VERIFY_DATA -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; -#ifdef OC_INFLATE_VERIFY_DATA - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); -#endif - INITBITS(); - state->mode = FLAGS; - break; - } - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - state->flags = 0; /* indicate zlib header */ - Tracev((stderr, "inflate: zlib header ok\n")); -#ifdef OC_INFLATE_VERIFY_DATA - strm->adler = state->check = adler32(0L, Z_NULL, 0); -#endif - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); -#endif - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); -#endif - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); -#endif - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); -#endif - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); -#endif - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); -#endif - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); -#endif - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } -#endif - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } -#ifdef OC_INFLATE_VERIFY_DATA - strm->adler = state->check = crc32(0L, Z_NULL, 0); -#endif - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); -#ifdef OC_INFLATE_VERIFY_DATA - strm->adler = state->check = ZSWAP32(hold); -#endif - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } -#ifdef OC_INFLATE_VERIFY_DATA - strm->adler = state->check = adler32(0L, Z_NULL, 0); -#endif - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); -#endif - out = left; -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } -#endif - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; -#ifdef OC_INFLATE_VERIFY_DATA - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); -#endif - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; -#ifdef OC_INFLATE_VERIFY_DATA - unsigned long dictid; -#endif - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ -#ifdef OC_INFLATE_VERIFY_DATA - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } -#endif - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - int flags; /* temporary to save header status */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ - flags = state->flags; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->flags = flags; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check && state->wrap) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/Library/OcCompressionLib/zlib/inflate.h b/Library/OcCompressionLib/zlib/inflate.h deleted file mode 100644 index 98679fa9b..000000000 --- a/Library/OcCompressionLib/zlib/inflate.h +++ /dev/null @@ -1,126 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags, 0 if zlib, or - -1 if raw or no header yet */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/Library/OcCompressionLib/zlib/inftrees.c b/Library/OcCompressionLib/zlib/inftrees.c deleted file mode 100644 index 716c98842..000000000 --- a/Library/OcCompressionLib/zlib/inftrees.c +++ /dev/null @@ -1,304 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.11.1 Copyright 1995-2017 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 196}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/Library/OcCompressionLib/zlib/inftrees.h b/Library/OcCompressionLib/zlib/inftrees.h deleted file mode 100644 index baa53a0b1..000000000 --- a/Library/OcCompressionLib/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/Library/OcCompressionLib/zlib/trees.c b/Library/OcCompressionLib/zlib/trees.c deleted file mode 100644 index decaeb7c3..000000000 --- a/Library/OcCompressionLib/zlib/trees.c +++ /dev/null @@ -1,1182 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2017 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local const static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local const static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local const static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - if (stored_len) - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len<<3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->sym_next / 3)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->sym_buf[s->sym_next++] = dist; - s->sym_buf[s->sym_next++] = dist >> 8; - s->sym_buf[s->sym_next++] = lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - return (s->sym_next == s->sym_end); -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} diff --git a/Library/OcCompressionLib/zlib/trees.h b/Library/OcCompressionLib/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/Library/OcCompressionLib/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/Library/OcCompressionLib/zlib/uncompr.c b/Library/OcCompressionLib/zlib/uncompr.c deleted file mode 100644 index f03a1a865..000000000 --- a/Library/OcCompressionLib/zlib/uncompr.c +++ /dev/null @@ -1,93 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return uncompress2(dest, destLen, source, &sourceLen); -} diff --git a/Library/OcCompressionLib/zlib/zconf.h b/Library/OcCompressionLib/zlib/zconf.h deleted file mode 100644 index 128f45f4c..000000000 --- a/Library/OcCompressionLib/zlib/zconf.h +++ /dev/null @@ -1,80 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -#include - -// -// EDIT (Download-Fritz): Disable MSVC warnings preventing compilation. -// Include stddef.h for its wchar_t definition. -// -#if defined(_MSC_VER) - #include - #pragma warning ( disable : 4131 ) - #pragma warning ( disable : 4244 ) -#endif - -#define NO_GZIP 1 - -/* Maximum value for memLevel in deflateInit2 */ -#define MAX_MEM_LEVEL 9 - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#define MAX_WBITS 15 /* 32K LZ77 window */ - -#define Z_LARGE64 1 - -/* Type declarations */ - -#define OF(args) args -#define Z_ARG(args) args /* function prototypes for stdarg */ - -#define ZEXTERN extern -#define ZEXPORT -#define ZEXPORTVA -#define FAR - -#define z_const const - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ -typedef Byte Bytef; -typedef char charf; -typedef int intf; -typedef uInt uIntf; -typedef uLong uLongf; -typedef void const *voidpc; -typedef void *voidpf; -typedef void *voidp; - -typedef UINTN z_size_t; -typedef UINT32 z_crc_t; -#define z_off_t INTN -#define z_off64_t INTN -#define Z_U4 UINT32 -#define Z_U8 UINT64 - -#ifdef MIN -#undef MIN -#endif - -#ifdef _WIN32 -#undef _WIN32 -#endif - -#ifdef _WIN64 -#undef _WIN64 -#endif - -#endif /* ZCONF_H */ diff --git a/Library/OcCompressionLib/zlib/zlib.h b/Library/OcCompressionLib/zlib/zlib.h deleted file mode 100644 index 18ce4331b..000000000 --- a/Library/OcCompressionLib/zlib/zlib.h +++ /dev/null @@ -1,1936 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.11.1, January xxth, 2017 - - Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.11.1-motley" -#define ZLIB_VERNUM 0x12b1 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 -#define ZLIB_VER_SUBREVISION 1 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields zalloc, zfree and opaque must be initialized before by the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if there have been any deflate() calls since the - state was initialized or reset, then the input available so far is - compressed with the old level and strategy using deflate(strm, Z_BLOCK). - There are three approaches for the compression levels 0, 1..3, and 4..9 - respectively. The new level and strategy will take effect at the next call - of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will *not* automatically decode concatenated gzip members. - inflate() will return Z_STREAM_END at the end of the gzip member. The state - would need to be reset to continue decoding a subsequent gzip member. This - *must* be done if there is more data after a gzip member, in order for the - decompression to be compliant with the gzip standard (RFC 1952). - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - gzfwrite() writes nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. An Adler-32 value is in the range of a 32-bit - unsigned integer. If buf is Z_NULL, this function returns the required - initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. - If buf is Z_NULL, this function returns the required initial value for the - crc. Pre- and post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); - - Return the operator corresponding to length len2, to be used with - crc32_combine_op(). -*/ - -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); -/* - Give the same result as crc32_combine(), using op in place of len2. op is - is generated from len2 by crc32_combine_gen(). This will be faster than - crc32_combine() if the generated op is used more than once. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# define z_crc32_combine_gen z_crc32_combine64_gen -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# define crc32_combine_gen crc32_combine_gen64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/Library/OcCompressionLib/zlib/zlib_uefi.c b/Library/OcCompressionLib/zlib/zlib_uefi.c deleted file mode 100644 index 380ad77d5..000000000 --- a/Library/OcCompressionLib/zlib/zlib_uefi.c +++ /dev/null @@ -1,77 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "zutil.h" - -#include -#include - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - (void) opaque; - return (voidpf) AllocatePool (items * size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - (void) opaque; - FreePool (ptr); -} - -UINT8 * -CompressZLIB ( - OUT UINT8 *Dst, - IN UINT32 DstLen, - IN CONST UINT8 *Src, - IN UINT32 SrcLen - ) -{ - uLongf ResultingLen = DstLen; - - if (SrcLen > OC_COMPRESSION_MAX_LENGTH || DstLen > OC_COMPRESSION_MAX_LENGTH) { - return 0; - } - - if (compress (Dst, &ResultingLen, Src, SrcLen) == Z_OK) { - return Dst + ResultingLen; - } - - return NULL; -} - -UINTN -DecompressZLIB ( - OUT UINT8 *Dst, - IN UINTN DstLen, - IN CONST UINT8 *Src, - IN UINTN SrcLen - ) -{ - uLongf ResultingLen = DstLen; - - if (SrcLen > OC_COMPRESSION_MAX_LENGTH || DstLen > OC_COMPRESSION_MAX_LENGTH) { - return 0; - } - - if (uncompress (Dst, &ResultingLen, Src, SrcLen) == Z_OK) { - return ResultingLen; - } - - return 0; -} diff --git a/Library/OcCompressionLib/zlib/zutil.h b/Library/OcCompressionLib/zlib/zutil.h deleted file mode 100644 index 7306e9714..000000000 --- a/Library/OcCompressionLib/zlib/zutil.h +++ /dev/null @@ -1,86 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL - -#include "zlib.h" - -#define local static - -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -#define ERR_MSG(err) NULL - -#define ERR_RETURN(strm,err) \ - return (strm->msg = NULL, (err)) -/* To be used only when the state is known to be valid */ - -/* common constants */ - -#define DEF_WBITS MAX_WBITS -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#define DEF_MEM_LEVEL 8 -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - -/* target dependencies */ - -#define OS_CODE 3 /* assume Unix */ - -#define zmemcpy(Dst, Src, Size) CopyMem ((Dst), (Src), (Size)) -#define zmemcmp(Ptr1, Ptr2, Size) CompareMem ((Ptr1), (Ptr2), (Size)) -#define zmemzero(Dst, Size) ZeroMem ((Dst), (Size)) - -/* Diagnostic functions */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/Library/OcConsoleLib/ConsoleControl.c b/Library/OcConsoleLib/ConsoleControl.c deleted file mode 100644 index a1404c330..000000000 --- a/Library/OcConsoleLib/ConsoleControl.c +++ /dev/null @@ -1,136 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_CONSOLE_CONTROL_SCREEN_MODE -OcConsoleControlSetMode ( - IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - ) -{ - EFI_STATUS Status; - EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; - EFI_CONSOLE_CONTROL_SCREEN_MODE OldMode; - - Status = OcHandleProtocolFallback ( - &gST->ConsoleOutHandle, - &gEfiConsoleControlProtocolGuid, - (VOID *) &ConsoleControl - ); - - // - // No console control, assume already set. - // - if (EFI_ERROR(Status)) { - return Mode; - } - - Status = ConsoleControl->GetMode ( - ConsoleControl, - &OldMode, - NULL, - NULL - ); - - // - // Cannot get mode, assume already set. - // Same mode, do not waste time. - // - if (EFI_ERROR(Status) || OldMode == Mode) { - return Mode; - } - - ConsoleControl->SetMode ( - ConsoleControl, - Mode - ); - - return OldMode; -} - -EFI_STATUS -OcConsoleControlInstallProtocol ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *NewProtocol, - OUT EFI_CONSOLE_CONTROL_PROTOCOL *OldProtocol OPTIONAL, - OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *OldMode OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; - - Status = OcHandleProtocolFallback ( - &gST->ConsoleOutHandle, - &gEfiConsoleControlProtocolGuid, - (VOID *) &ConsoleControl - ); - - DEBUG (( - DEBUG_INFO, - "OCC: Install console control (%p/%p/%p), current - %r\n", - NewProtocol, - OldProtocol, - OldMode, - Status - )); - - // - // Native implementation exists, overwrite. - // - if (!EFI_ERROR(Status)) { - // - // Provide original mode if requested. - // - if (OldMode != NULL) { - ConsoleControl->GetMode (ConsoleControl, OldMode, NULL, NULL); - } - - if (OldProtocol != NULL) { - CopyMem ( - OldProtocol, - ConsoleControl, - sizeof (*OldProtocol) - ); - } - - CopyMem ( - ConsoleControl, - NewProtocol, - sizeof (*ConsoleControl) - ); - - return EFI_SUCCESS; - } - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gST->ConsoleOutHandle, - &gEfiConsoleControlProtocolGuid, - NewProtocol, - NULL - ); - - DEBUG ((DEBUG_INFO, "OCC: Install console control, new - %r\n", Status)); - - return Status; -} diff --git a/Library/OcConsoleLib/ConsoleGop.c b/Library/OcConsoleLib/ConsoleGop.c deleted file mode 100644 index 34fb4df99..000000000 --- a/Library/OcConsoleLib/ConsoleGop.c +++ /dev/null @@ -1,437 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_HANDLE_PROTOCOL -mOriginalHandleProtocol; - -STATIC -EFI_GRAPHICS_OUTPUT_PROTOCOL * -mConsoleGraphicsOutput; - -STATIC -FRAME_BUFFER_CONFIGURE * -mFramebufferContext; - -STATIC -EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE -mOriginalGopSetMode; - -STATIC -INT32 -mCachePolicy; - -STATIC -EFI_STATUS -EFIAPI -ConsoleHandleProtocol ( - IN EFI_HANDLE Handle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = mOriginalHandleProtocol (Handle, Protocol, Interface); - - if (Status != EFI_UNSUPPORTED) { - return Status; - } - - if (CompareGuid (&gEfiGraphicsOutputProtocolGuid, Protocol)) { - if (mConsoleGraphicsOutput != NULL) { - *Interface = mConsoleGraphicsOutput; - return EFI_SUCCESS; - } - } else if (CompareGuid (&gEfiUgaDrawProtocolGuid, Protocol)) { - // - // EfiBoot from 10.4 can only use UgaDraw protocol. - // - Status = gBS->LocateProtocol ( - &gEfiUgaDrawProtocolGuid, - NULL, - Interface - ); - if (!EFI_ERROR(Status)) { - return EFI_SUCCESS; - } - } - - return EFI_UNSUPPORTED; -} - -VOID -OcProvideConsoleGop( - IN BOOLEAN Route - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *OriginalGop = NULL; - EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - // - // Shell may replace gST->ConsoleOutHandle, so we have to ensure - // that HandleProtocol always reports valid chosen GOP. - // - if (Route) { - mOriginalHandleProtocol = gBS->HandleProtocol; - gBS->HandleProtocol = ConsoleHandleProtocol; - gBS->Hdr.CRC32 = 0; - gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32); - } - - OriginalGop = NULL; - Status = gBS->HandleProtocol ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **)&OriginalGop - ); - - if (!EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCC: GOP exists on ConsoleOutHandle and has %u modes\n", - (UINT32) OriginalGop->Mode->MaxMode - )); - - // - // This is not the case on MacPro5,1 with Mac EFI incompatible GPU. - // Here we need to uninstall ConOut GOP in favour of GPU GOP. - // - if (OriginalGop->Mode->MaxMode > 0) { - mConsoleGraphicsOutput = OriginalGop; - return; - } - - DEBUG (( - DEBUG_INFO, - "OCC: Looking for GOP replacement due to invalid mode count\n" - )); - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiGraphicsOutputProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: No handles with GOP protocol - %r\n", Status)); - return; - } - - Status = EFI_NOT_FOUND; - for (Index = 0; Index < HandleCount; ++Index) { - if (HandleBuffer[Index] != gST->ConsoleOutHandle) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &Gop - ); - break; - } - } - - DEBUG ((DEBUG_INFO, "OCC: Alternative GOP status is - %r\n", Status)); - FreePool (HandleBuffer); - - if (!EFI_ERROR(Status)) { - gBS->UninstallProtocolInterface ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - OriginalGop - ); - } - } else { - DEBUG ((DEBUG_INFO, "OCC: Installing GOP (%r) on ConsoleOutHandle...\n", Status)); - Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **) &Gop); - } - - if (!EFI_ERROR(Status)) { - Status = gBS->InstallMultipleProtocolInterfaces ( - &gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - Gop, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCC: Failed to install GOP on ConsoleOutHandle - %r\n", Status)); - } - - mConsoleGraphicsOutput = Gop; - } else { - DEBUG ((DEBUG_WARN, "OCC: Missing compatible GOP - %r\n", Status)); - } -} - -STATIC -FRAME_BUFFER_CONFIGURE * -EFIAPI -DirectGopFromTarget ( - IN EFI_PHYSICAL_ADDRESS FramebufferBase, - IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info - ) -{ - EFI_STATUS Status; - UINTN ConfigureSize; - FRAME_BUFFER_CONFIGURE *Context; - - ConfigureSize = 0; - Status = FrameBufferBltConfigure ( - (VOID *)(UINTN) FramebufferBase, - Info, - NULL, - &ConfigureSize - ); - if (Status != EFI_BUFFER_TOO_SMALL) { - return NULL; - } - - Context = AllocatePool (ConfigureSize); - if (Context == NULL) { - return NULL; - } - - Status = FrameBufferBltConfigure ( - (VOID *)(UINTN) FramebufferBase, - Info, - Context, - &ConfigureSize - ); - if (EFI_ERROR(Status)) { - FreePool (Context); - return NULL; - } - - return Context; -} - -STATIC -EFI_STATUS -EFIAPI -DirectGopSetMode ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN UINT32 ModeNumber - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - FRAME_BUFFER_CONFIGURE *Original; - - if (ModeNumber == This->Mode->Mode) { - return EFI_SUCCESS; - } - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - // - // Protect from invalid Blt calls during SetMode - // - Original = mFramebufferContext; - mFramebufferContext = NULL; - - Status = mOriginalGopSetMode (This, ModeNumber); - if (EFI_ERROR(Status)) { - mFramebufferContext = Original; - gBS->RestoreTPL (OldTpl); - return Status; - } - - if (Original != NULL) { - FreePool (Original); - } - - mFramebufferContext = DirectGopFromTarget (This->Mode->FrameBufferBase, This->Mode->Info); - if (mFramebufferContext == NULL) { - gBS->RestoreTPL (OldTpl); - return EFI_DEVICE_ERROR; - } - - if (mCachePolicy >= 0) { - MtrrSetMemoryAttribute ( - This->Mode->FrameBufferBase, - This->Mode->FrameBufferSize, - mCachePolicy - ); - } - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -DirectGopBlt ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, - IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta OPTIONAL - ) -{ - if (mFramebufferContext != NULL) { - return FrameBufferBlt ( - mFramebufferContext, - BltBuffer, - BltOperation, - SourceX, - SourceY, - DestinationX, - DestinationY, - Width, - Height, - Delta - ); - } - - return EFI_DEVICE_ERROR; -} - -VOID -OcReconnectConsole ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - // - // On some firmwares When we change mode on GOP, we need to reconnect the drivers - // which produce simple text out. Otherwise, they won't produce text based on the - // new resolution. - // - // Needy reports that boot.efi seems to work fine without this block of code. - // However, I believe that UEFI specification does not provide any standard way - // to inform TextOut protocol about resolution change, which means the firmware - // may not be aware of the change, especially when custom GOP is used. - // We can move this to quirks if it causes problems, but I believe the code below - // is legit. - // - // Note: on APTIO IV boards this block of code may result in black screen when launching - // OpenCore from Shell, thus it is optional. - // - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleTextOutProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (!EFI_ERROR(Status)) { - for (Index = 0; Index < HandleCount; ++Index) { - gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); - } - - for (Index = 0; Index < HandleCount; ++Index) { - gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - } - - FreePool (HandleBuffer); - - // - // It is implementation defined, which console mode is used by ConOut. - // Assume the implementation chooses most sensible value based on GOP resolution. - // If it does not, there is a separate ConsoleMode param, which expands to SetConsoleMode. - // - } else { - DEBUG ((DEBUG_WARN, "OCC: Failed to find any text output handles\n")); - } -} - -EFI_STATUS -OcUseDirectGop ( - IN INT32 CacheType - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; - - DEBUG ((DEBUG_INFO, "OCC: Switching to direct GOP renderer...\n")); - - Status = gBS->HandleProtocol ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &Gop - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: Cannot find console GOP for direct GOP - %r\n", Status)); - return Status; - } - - mFramebufferContext = DirectGopFromTarget (Gop->Mode->FrameBufferBase, Gop->Mode->Info); - if (mFramebufferContext == NULL) { - DEBUG ((DEBUG_INFO, "OCC: Delaying direct GOP configuration...\n")); - // - // This is possible at the start. - // - } - - mOriginalGopSetMode = Gop->SetMode; - Gop->SetMode = DirectGopSetMode; - Gop->Blt = DirectGopBlt; - mCachePolicy = -1; - - if (CacheType >= 0) { - Status = MtrrSetMemoryAttribute ( - Gop->Mode->FrameBufferBase, - Gop->Mode->FrameBufferSize, - CacheType - ); - DEBUG (( - DEBUG_INFO, - "OCC: FB (%Lx, %Lx) MTRR (%x) - %r\n", - (UINT64) Gop->Mode->FrameBufferBase, - (UINT64) Gop->Mode->FrameBufferSize, - CacheType, - Status - )); - if (!EFI_ERROR(Status)) { - mCachePolicy = CacheType; - } - } - - return EFI_SUCCESS; -} diff --git a/Library/OcConsoleLib/FramebufferInfo.c b/Library/OcConsoleLib/FramebufferInfo.c deleted file mode 100644 index d46fd51fc..000000000 --- a/Library/OcConsoleLib/FramebufferInfo.c +++ /dev/null @@ -1,131 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -STATIC -EFI_STATUS -EFIAPI -AppleFramebufferGetInfo ( - IN APPLE_FRAMEBUFFER_INFO_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *FramebufferBase, - OUT UINT32 *FramebufferSize, - OUT UINT32 *ScreenRowBytes, - OUT UINT32 *ScreenWidth, - OUT UINT32 *ScreenHeight, - OUT UINT32 *ScreenDepth - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - - if (This == NULL - || FramebufferBase == NULL - || FramebufferSize == NULL - || ScreenRowBytes == NULL - || ScreenWidth == NULL - || ScreenHeight == NULL - || ScreenDepth == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = gBS->HandleProtocol ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (EFI_ERROR(Status)) { - return EFI_UNSUPPORTED; - } - - Mode = GraphicsOutput->Mode; - Info = Mode->Info; - - if (Info == NULL) { - return EFI_UNSUPPORTED; - } - - // - // This is a bit inaccurate as it assumes 32-bit BPP, but will do for most cases. - // - *FramebufferBase = Mode->FrameBufferBase; - *FramebufferSize = (UINT32) Mode->FrameBufferSize; - *ScreenRowBytes = (UINT32) (Info->PixelsPerScanLine * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - *ScreenWidth = Info->HorizontalResolution; - *ScreenHeight = Info->VerticalResolution; - *ScreenDepth = DEFAULT_COLOUR_DEPTH; - - return EFI_SUCCESS; -} - -STATIC -APPLE_FRAMEBUFFER_INFO_PROTOCOL -mAppleFramebufferInfo = { - AppleFramebufferGetInfo -}; - -APPLE_FRAMEBUFFER_INFO_PROTOCOL * -OcAppleFbInfoInstallProtocol ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - APPLE_FRAMEBUFFER_INFO_PROTOCOL *Protocol; - - DEBUG ((DEBUG_VERBOSE, "OcAppleFbInfoInstallProtocol\n")); - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gAppleFramebufferInfoProtocolGuid); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCOS: Uninstall failed: %r\n", Status)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gAppleFramebufferInfoProtocolGuid, - NULL, - (VOID *) &Protocol - ); - - if (!EFI_ERROR(Status)) { - return Protocol; - } - } - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gAppleFramebufferInfoProtocolGuid, - (VOID *) &mAppleFramebufferInfo, - NULL - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - return &mAppleFramebufferInfo; -} diff --git a/Library/OcConsoleLib/OcConsoleLib.c b/Library/OcConsoleLib/OcConsoleLib.c deleted file mode 100644 index ac352a682..000000000 --- a/Library/OcConsoleLib/OcConsoleLib.c +++ /dev/null @@ -1,369 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_STATUS -OcSetConsoleResolutionForProtocol ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, - IN UINT32 Width, - IN UINT32 Height, - IN UINT32 Bpp OPTIONAL - ) -{ - EFI_STATUS Status; - - UINT32 MaxMode; - UINT32 ModeIndex; - INT64 ModeNumber; - UINTN SizeOfInfo; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - BOOLEAN SetMax; - - SetMax = Width == 0 && Height == 0; - - DEBUG (( - DEBUG_INFO, - "OCC: Requesting %ux%u@%u (max: %d) resolution, curr %u, total %u\n", - Width, - Height, - Bpp, - SetMax, - (UINT32) GraphicsOutput->Mode->Mode, - (UINT32) GraphicsOutput->Mode->MaxMode - )); - - // - // Find the resolution we need. - // - ModeNumber = -1; - MaxMode = GraphicsOutput->Mode->MaxMode; - for (ModeIndex = 0; ModeIndex < MaxMode; ++ModeIndex) { - Status = GraphicsOutput->QueryMode ( - GraphicsOutput, - ModeIndex, - &SizeOfInfo, - &Info - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: Mode %u failure - %r\n", ModeIndex, Status)); - continue; - } - - DEBUG (( - DEBUG_INFO, - "OCC: Mode %u - %ux%u:%u\n", - ModeIndex, - Info->HorizontalResolution, - Info->VerticalResolution, - Info->PixelFormat - )); - - if (!SetMax) { - // - // Custom resolution is requested. - // - if (Info->HorizontalResolution == Width - && Info->VerticalResolution == Height - && (Bpp == 0 || Bpp == 24 || Bpp == 32) - && (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor - || Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor - || (Info->PixelFormat == PixelBitMask - && (Info->PixelInformation.RedMask == 0xFF000000U - || Info->PixelInformation.RedMask == 0xFF0000U - || Info->PixelInformation.RedMask == 0xFF00U - || Info->PixelInformation.RedMask == 0xFFU)) - || Info->PixelFormat == PixelBltOnly)) { - ModeNumber = ModeIndex; - FreePool (Info); - break; - } - } else if (Info->HorizontalResolution > Width - || (Info->HorizontalResolution == Width && Info->VerticalResolution > Height)) { - Width = Info->HorizontalResolution; - Height = Info->VerticalResolution; - ModeNumber = ModeIndex; - } - - FreePool (Info); - } - - if (ModeNumber < 0) { - DEBUG ((DEBUG_WARN, "OCC: No compatible mode for %ux%u@%u (max: %u) resolution\n", Width, Height, Bpp, SetMax)); - return EFI_NOT_FOUND; - } - - if (ModeNumber == GraphicsOutput->Mode->Mode) { - DEBUG ((DEBUG_INFO, "OCC: Current mode matches desired mode %u\n", (UINT32) ModeNumber)); - return EFI_ALREADY_STARTED; - } - - // - // Current graphics mode is not set, or is not set to the mode found above. - // Set the new graphics mode. - // - DEBUG (( - DEBUG_INFO, - "OCC: Setting mode %u with %ux%u resolution\n", - (UINT32) ModeNumber, - Width, - Height - )); - - Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) ModeNumber); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_WARN, - "OCC: Failed to set mode %u (prev %u) with %ux%u resolution\n", - (UINT32) ModeNumber, - (UINT32) GraphicsOutput->Mode->Mode, - Width, - Height - )); - return Status; - } - - DEBUG ((DEBUG_INFO, "OCC: Changed resolution mode to %u\n", (UINT32) GraphicsOutput->Mode->Mode)); - - return Status; -} - -EFI_STATUS -OcSetConsoleModeForProtocol ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut, - IN UINT32 Width, - IN UINT32 Height - ) -{ - EFI_STATUS Status; - UINT32 MaxMode; - UINT32 ModeIndex; - INT64 ModeNumber; - UINTN Columns; - UINTN Rows; - BOOLEAN SetMax; - - SetMax = Width == 0 && Height == 0; - - DEBUG (( - DEBUG_INFO, - "OCC: Requesting %ux%u (max: %d) console mode, curr %u, max %u\n", - Width, - Height, - SetMax, - (UINT32) TextOut->Mode->Mode, - (UINT32) TextOut->Mode->MaxMode - )); - - // - // Find the resolution we need. - // - ModeNumber = -1; - MaxMode = TextOut->Mode->MaxMode; - for (ModeIndex = 0; ModeIndex < MaxMode; ++ModeIndex) { - Status = TextOut->QueryMode ( - TextOut, - ModeIndex, - &Columns, - &Rows - ); - - if (EFI_ERROR(Status)) { - continue; - } - - DEBUG (( - DEBUG_INFO, - "OCC: Mode %u - %ux%u\n", - ModeIndex, - (UINT32) Columns, - (UINT32) Rows - )); - - if (!SetMax) { - // - // Custom mode is requested. - // - if (Columns == Width && Rows == Height) { - ModeNumber = ModeIndex; - break; - } - } else if ((UINT32) Columns > Width - || ((UINT32) Columns == Width && (UINT32) Rows > Height)) { - Width = (UINT32) Columns; - Height = (UINT32) Rows; - ModeNumber = ModeIndex; - } - } - - if (ModeNumber < 0) { - DEBUG ((DEBUG_WARN, "OCC: No compatible mode for %ux%u (max: %u) console mode\n", Width, Height, SetMax)); - return EFI_NOT_FOUND; - } - - if (ModeNumber == TextOut->Mode->Mode) { - // - // This does not seem to affect systems anyhow, but for safety reasons - // we should refresh console mode after changing GOP resolution. - // - DEBUG (( - DEBUG_INFO, - "OCC: Current console mode matches desired mode %u, forcing update\n", - (UINT32) ModeNumber - )); - } - - // - // Current graphics mode is not set, or is not set to the mode found above. - // Set the new graphics mode. - // - DEBUG (( - DEBUG_INFO, - "OCC: Setting mode %u (prev %u) with %ux%u console mode\n", - (UINT32) ModeNumber, - (UINT32) TextOut->Mode->Mode, - Width, - Height - )); - - Status = TextOut->SetMode (TextOut, (UINTN) ModeNumber); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_WARN, - "OCC: Failed to set mode %u with %ux%u console mode\n", - (UINT32) ModeNumber, - Width, - Height - )); - return Status; - } - - DEBUG ((DEBUG_INFO, "OCC: Changed console mode to %u\n", (UINT32) TextOut->Mode->Mode)); - - return EFI_SUCCESS; -} - -EFI_STATUS -OcSetConsoleResolution ( - IN UINT32 Width, - IN UINT32 Height, - IN UINT32 Bpp OPTIONAL - ) -{ - EFI_STATUS Result; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - -#ifdef OC_CONSOLE_CHANGE_ALL_RESOLUTIONS - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - Result = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiGraphicsOutputProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - if (!EFI_ERROR (Result)) { - Result = EFI_NOT_FOUND; - - DEBUG ((DEBUG_INFO, "OCC: Found %u handles with GOP\n", (UINT32) HandleCount)); - - for (Index = 0; Index < HandleCount; ++Index) { - DEBUG ((DEBUG_INFO, "OCC: Trying handle %u - %p\n", (UINT32) Index, HandleBuffer[Index])); - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCC: Missing GOP on console - %r\n", Status)); - continue; - } - - Result = OcSetConsoleResolutionForProtocol (GraphicsOutput, Width, Height, Bpp); - } - - FreePool (HandleBuffer); - } else { - DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP - %r\n", Result)); - } -#else - Result = gBS->HandleProtocol ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (EFI_ERROR (Result)) { - DEBUG ((DEBUG_WARN, "OCC: Missing GOP on ConOut - %r\n", Result)); - return Result; - } - - Result = OcSetConsoleResolutionForProtocol (GraphicsOutput, Width, Height, Bpp); -#endif - - return Result; -} - -EFI_STATUS -OcSetConsoleMode ( - IN UINT32 Width, - IN UINT32 Height - ) -{ - return OcSetConsoleModeForProtocol (gST->ConOut, Width, Height); -} - -VOID -OcSetupConsole ( - IN OC_CONSOLE_RENDERER Renderer, - IN BOOLEAN IgnoreTextOutput, - IN BOOLEAN SanitiseClearScreen, - IN BOOLEAN ClearScreenOnModeSwitch, - IN BOOLEAN ReplaceTabWithSpace - ) -{ - if (Renderer == OcConsoleRendererBuiltinGraphics) { - OcUseBuiltinTextOutput (); - } else { - OcUseSystemTextOutput ( - Renderer, - IgnoreTextOutput, - SanitiseClearScreen, - ClearScreenOnModeSwitch, - ReplaceTabWithSpace - ); - } -} diff --git a/Library/OcConsoleLib/OcConsoleLib.inf b/Library/OcConsoleLib/OcConsoleLib.inf deleted file mode 100644 index c48d00b4d..000000000 --- a/Library/OcConsoleLib/OcConsoleLib.inf +++ /dev/null @@ -1,67 +0,0 @@ -## @file -# OcConsoleLib -# -# Copyright (c) 2019, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcConsoleLib - FILE_GUID = 509895E3-ABF8-4836-BB0C-919729A8C293 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcConsoleLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - -# -# VALID_ARCHITECTURES = X64 -# - -[Guids] - gEfiAppleNvramGuid - -[Protocols] - gAppleFramebufferInfoProtocolGuid - gEfiConsoleControlProtocolGuid - gEfiGraphicsOutputProtocolGuid - gEfiSimpleTextOutProtocolGuid - gEfiUgaDrawProtocolGuid - -[Sources] - ConsoleControl.c - ConsoleGop.c - FramebufferInfo.c - OcConsoleLib.c - OcConsoleLibInternal.h - ResolutionParsing.c - TextOutputBuiltin.c - TextOutputNull.c - TextOutputSystem.c - UgaPassThrough.c - ../../Include/Library/OcConsoleLib.h - -[Packages] - CloverPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - FrameBufferBltLib - MtrrLib - UefiBootServicesTableLib - UefiRuntimeServicesTableLib diff --git a/Library/OcConsoleLib/OcConsoleLibInternal.h b/Library/OcConsoleLib/OcConsoleLibInternal.h deleted file mode 100644 index 1299dfeba..000000000 --- a/Library/OcConsoleLib/OcConsoleLibInternal.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_CONSOLE_LIB_INTERNAL_H -#define OC_CONSOLE_LIB_INTERNAL_H - -#include -#include -#include -#include -#include - -#define DEFAULT_COLOUR_DEPTH 32 -#define DEFAULT_REFRESH_RATE 60 - -typedef struct { - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_UGA_DRAW_PROTOCOL Uga; -} OC_UGA_PROTOCOL; - -EFI_STATUS -OcSetConsoleResolutionForProtocol ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput, - IN UINT32 Width, - IN UINT32 Height, - IN UINT32 Bpp OPTIONAL - ); - -EFI_STATUS -OcSetConsoleModeForProtocol ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut, - IN UINT32 Width, - IN UINT32 Height - ); - -EFI_STATUS -OcConsoleControlInstallProtocol ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *NewProtocol, - OUT EFI_CONSOLE_CONTROL_PROTOCOL *OldProtocol OPTIONAL, - OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *OldMode OPTIONAL - ); - -VOID -OcUseBuiltinTextOutput ( - VOID - ); - -VOID -OcUseSystemTextOutput ( - IN OC_CONSOLE_RENDERER Renderer, - IN BOOLEAN IgnoreTextOutput, - IN BOOLEAN SanitiseClearScreen, - IN BOOLEAN ClearScreenOnModeSwitch, - IN BOOLEAN ReplaceTabWithSpace - ); - -#endif // OC_CONSOLE_LIB_INTERNAL_H diff --git a/Library/OcConsoleLib/ResolutionParsing.c b/Library/OcConsoleLib/ResolutionParsing.c deleted file mode 100644 index a6de3f97d..000000000 --- a/Library/OcConsoleLib/ResolutionParsing.c +++ /dev/null @@ -1,134 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include - -/** - Parse resolution string. - - @param[in] String Resolution in WxH@Bpp or WxH format. - @param[out] Width Parsed width or 0. - @param[out] Height Parsed height or 0. - @param[out] Bpp Parsed Bpp or 0, optional to force WxH format. - @param[out] Max Set to TRUE when String equals to Max. -**/ -STATIC -VOID -ParseResolution ( - IN CONST CHAR8 *String, - OUT UINT32 *Width, - OUT UINT32 *Height, - OUT UINT32 *Bpp OPTIONAL, - OUT BOOLEAN *Max - ) -{ - UINT32 TmpWidth; - UINT32 TmpHeight; - - *Width = 0; - *Height = 0; - *Max = FALSE; - - if (Bpp != NULL) { - *Bpp = 0; - } - - if (AsciiStrCmp (String, "Max") == 0) { - *Max = TRUE; - return; - } - - if (*String == '\0' || *String < '0' || *String > '9') { - return; - } - - TmpWidth = TmpHeight = 0; - - while (*String >= '0' && *String <= '9') { - if (OcOverflowMulAddU32 (TmpWidth, 10, *String++ - '0', &TmpWidth)) { - return; - } - } - - if (*String++ != 'x' || *String < '0' || *String > '9') { - return; - } - - while (*String >= '0' && *String <= '9') { - if (OcOverflowMulAddU32 (TmpHeight, 10, *String++ - '0', &TmpHeight)) { - return; - } - } - - if (*String != '\0' && (*String != '@' || Bpp == NULL)) { - return; - } - - *Width = TmpWidth; - *Height = TmpHeight; - - if (*String == '\0') { - return; - } - - TmpWidth = 0; - while (*String >= '0' && *String <= '9') { - if (OcOverflowMulAddU32 (TmpWidth, 10, *String++ - '0', &TmpWidth)) { - return; - } - } - - if (*String != '\0') { - return; - } - - *Bpp = TmpWidth; -} - -VOID -OcParseScreenResolution ( - IN CONST CHAR8 *String, - OUT UINT32 *Width, - OUT UINT32 *Height, - OUT UINT32 *Bpp, - OUT BOOLEAN *Max - ) -{ - ASSERT (String != NULL); - ASSERT (Width != NULL); - ASSERT (Height != NULL); - ASSERT (Bpp != NULL); - ASSERT (Max != NULL); - - ParseResolution (String, Width, Height, Bpp, Max); -} - -VOID -OcParseConsoleMode ( - IN CONST CHAR8 *String, - OUT UINT32 *Width, - OUT UINT32 *Height, - OUT BOOLEAN *Max - ) -{ - ASSERT (String != NULL); - ASSERT (Width != NULL); - ASSERT (Height != NULL); - ASSERT (Max != NULL); - - ParseResolution (String, Width, Height, NULL, Max); -} diff --git a/Library/OcConsoleLib/TextOutputBuiltin.c b/Library/OcConsoleLib/TextOutputBuiltin.c deleted file mode 100644 index 2eef819d4..000000000 --- a/Library/OcConsoleLib/TextOutputBuiltin.c +++ /dev/null @@ -1,963 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * ISO Latin-1 Font - * - * Copyright (c) 2000 - * Ka-Ping Yee - * - * This font may be freely used for any purpose. - */ - -#define ISO_CHAR_MIN 0x21 -#define ISO_CHAR_MAX 0x7E -#define ISO_CHAR_WIDTH 8 -#define ISO_CHAR_HEIGHT 16 - -STATIC UINT8 mIsoFontData[(ISO_CHAR_MAX - ISO_CHAR_MIN + 1)*(ISO_CHAR_HEIGHT - 2)] = { -/* 33 */ 0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, -/* 34 */ 0x00,0x6c,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/* 35 */ 0x00,0x00,0x36,0x36,0x7f,0x36,0x36,0x7f,0x36,0x36,0x00,0x00,0x00,0x00, -/* 36 */ 0x08,0x08,0x3e,0x6b,0x0b,0x0b,0x3e,0x68,0x68,0x6b,0x3e,0x08,0x08,0x00, -/* 37 */ 0x00,0x00,0x33,0x13,0x18,0x08,0x0c,0x04,0x06,0x32,0x33,0x00,0x00,0x00, -/* 38 */ 0x00,0x1c,0x36,0x36,0x1c,0x6c,0x3e,0x33,0x33,0x7b,0xce,0x00,0x00,0x00, -/* 39 */ 0x00,0x18,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/* 40 */ 0x00,0x30,0x18,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x18,0x30,0x00,0x00, -/* 41 */ 0x00,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x30,0x18,0x18,0x0c,0x00,0x00, -/* 42 */ 0x00,0x00,0x00,0x00,0x36,0x1c,0x7f,0x1c,0x36,0x00,0x00,0x00,0x00,0x00, -/* 43 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00, -/* 44 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0c,0x00,0x00, -/* 45 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/* 46 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00, -/* 47 */ 0x00,0x60,0x20,0x30,0x10,0x18,0x08,0x0c,0x04,0x06,0x02,0x03,0x00,0x00, -/* 48 */ 0x00,0x3e,0x63,0x63,0x63,0x6b,0x6b,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 49 */ 0x00,0x18,0x1e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, -/* 50 */ 0x00,0x3e,0x63,0x60,0x60,0x30,0x18,0x0c,0x06,0x03,0x7f,0x00,0x00,0x00, -/* 51 */ 0x00,0x3e,0x63,0x60,0x60,0x3c,0x60,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, -/* 52 */ 0x00,0x30,0x38,0x3c,0x36,0x33,0x7f,0x30,0x30,0x30,0x30,0x00,0x00,0x00, -/* 53 */ 0x00,0x7f,0x03,0x03,0x3f,0x60,0x60,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, -/* 54 */ 0x00,0x3c,0x06,0x03,0x03,0x3f,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 55 */ 0x00,0x7f,0x60,0x30,0x30,0x18,0x18,0x18,0x0c,0x0c,0x0c,0x00,0x00,0x00, -/* 56 */ 0x00,0x3e,0x63,0x63,0x63,0x3e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 57 */ 0x00,0x3e,0x63,0x63,0x63,0x7e,0x60,0x60,0x60,0x30,0x1e,0x00,0x00,0x00, -/* 58 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00, -/* 59 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x0c,0x00,0x00, -/* 60 */ 0x00,0x60,0x30,0x18,0x0c,0x06,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00, -/* 61 */ 0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, -/* 62 */ 0x00,0x06,0x0c,0x18,0x30,0x60,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00, -/* 63 */ 0x00,0x3e,0x63,0x60,0x30,0x30,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, -/* 64 */ 0x00,0x3c,0x66,0x73,0x7b,0x6b,0x6b,0x7b,0x33,0x06,0x3c,0x00,0x00,0x00, -/* 65 */ 0x00,0x3e,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, -/* 66 */ 0x00,0x3f,0x63,0x63,0x63,0x3f,0x63,0x63,0x63,0x63,0x3f,0x00,0x00,0x00, -/* 67 */ 0x00,0x3c,0x66,0x03,0x03,0x03,0x03,0x03,0x03,0x66,0x3c,0x00,0x00,0x00, -/* 68 */ 0x00,0x1f,0x33,0x63,0x63,0x63,0x63,0x63,0x63,0x33,0x1f,0x00,0x00,0x00, -/* 69 */ 0x00,0x7f,0x03,0x03,0x03,0x3f,0x03,0x03,0x03,0x03,0x7f,0x00,0x00,0x00, -/* 70 */ 0x00,0x7f,0x03,0x03,0x03,0x3f,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00, -/* 71 */ 0x00,0x3c,0x66,0x03,0x03,0x03,0x73,0x63,0x63,0x66,0x7c,0x00,0x00,0x00, -/* 72 */ 0x00,0x63,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, -/* 73 */ 0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00, -/* 74 */ 0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x33,0x1e,0x00,0x00,0x00, -/* 75 */ 0x00,0x63,0x33,0x1b,0x0f,0x07,0x07,0x0f,0x1b,0x33,0x63,0x00,0x00,0x00, -/* 76 */ 0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x7f,0x00,0x00,0x00, -/* 77 */ 0x00,0x63,0x63,0x77,0x7f,0x7f,0x6b,0x6b,0x63,0x63,0x63,0x00,0x00,0x00, -/* 78 */ 0x00,0x63,0x63,0x67,0x6f,0x6f,0x7b,0x7b,0x73,0x63,0x63,0x00,0x00,0x00, -/* 79 */ 0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 80 */ 0x00,0x3f,0x63,0x63,0x63,0x63,0x3f,0x03,0x03,0x03,0x03,0x00,0x00,0x00, -/* 81 */ 0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x63,0x6f,0x7b,0x3e,0x30,0x60,0x00, -/* 82 */ 0x00,0x3f,0x63,0x63,0x63,0x63,0x3f,0x1b,0x33,0x63,0x63,0x00,0x00,0x00, -/* 83 */ 0x00,0x3e,0x63,0x03,0x03,0x0e,0x38,0x60,0x60,0x63,0x3e,0x00,0x00,0x00, -/* 84 */ 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, -/* 85 */ 0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 86 */ 0x00,0x63,0x63,0x63,0x63,0x63,0x36,0x36,0x1c,0x1c,0x08,0x00,0x00,0x00, -/* 87 */ 0x00,0x63,0x63,0x6b,0x6b,0x6b,0x6b,0x7f,0x36,0x36,0x36,0x00,0x00,0x00, -/* 88 */ 0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x36,0x36,0x63,0x63,0x00,0x00,0x00, -/* 89 */ 0x00,0xc3,0xc3,0x66,0x66,0x3c,0x3c,0x18,0x18,0x18,0x18,0x00,0x00,0x00, -/* 90 */ 0x00,0x7f,0x30,0x30,0x18,0x18,0x0c,0x0c,0x06,0x06,0x7f,0x00,0x00,0x00, -/* 91 */ 0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00, -/* 92 */ 0x00,0x03,0x02,0x06,0x04,0x0c,0x08,0x18,0x10,0x30,0x20,0x60,0x00,0x00, -/* 93 */ 0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00, -/* 94 */ 0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/* 95 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, -/* 96 */ 0x00,0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/* 97 */ 0x00,0x00,0x00,0x00,0x3e,0x60,0x7e,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, -/* 98 */ 0x00,0x03,0x03,0x03,0x3b,0x67,0x63,0x63,0x63,0x67,0x3b,0x00,0x00,0x00, -/* 99 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00, -/* 100 */ 0x00,0x60,0x60,0x60,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, -/* 101 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x7f,0x03,0x63,0x3e,0x00,0x00,0x00, -/* 102 */ 0x00,0x3c,0x66,0x06,0x1f,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00, -/* 103 */ 0x00,0x00,0x00,0x00,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x60,0x63,0x3e, -/* 104 */ 0x00,0x03,0x03,0x03,0x3b,0x67,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, -/* 105 */ 0x00,0x0c,0x0c,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, -/* 106 */ 0x00,0x30,0x30,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x33,0x1e, -/* 107 */ 0x00,0x03,0x03,0x03,0x63,0x33,0x1b,0x0f,0x1f,0x33,0x63,0x00,0x00,0x00, -/* 108 */ 0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, -/* 109 */ 0x00,0x00,0x00,0x00,0x35,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x00,0x00,0x00, -/* 110 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00, -/* 111 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00, -/* 112 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x63,0x63,0x63,0x67,0x3b,0x03,0x03,0x03, -/* 113 */ 0x00,0x00,0x00,0x00,0x6e,0x73,0x63,0x63,0x63,0x73,0x6e,0x60,0xe0,0x60, -/* 114 */ 0x00,0x00,0x00,0x00,0x3b,0x67,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00, -/* 115 */ 0x00,0x00,0x00,0x00,0x3e,0x63,0x0e,0x38,0x60,0x63,0x3e,0x00,0x00,0x00, -/* 116 */ 0x00,0x00,0x0c,0x0c,0x3e,0x0c,0x0c,0x0c,0x0c,0x0c,0x38,0x00,0x00,0x00, -/* 117 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x73,0x6e,0x00,0x00,0x00, -/* 118 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x08,0x00,0x00,0x00, -/* 119 */ 0x00,0x00,0x00,0x00,0x63,0x6b,0x6b,0x6b,0x3e,0x36,0x36,0x00,0x00,0x00, -/* 120 */ 0x00,0x00,0x00,0x00,0x63,0x36,0x1c,0x1c,0x1c,0x36,0x63,0x00,0x00,0x00, -/* 121 */ 0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1c,0x1c,0x0c,0x0c,0x06,0x03, -/* 122 */ 0x00,0x00,0x00,0x00,0x7f,0x60,0x30,0x18,0x0c,0x06,0x7f,0x00,0x00,0x00, -/* 123 */ 0x00,0x70,0x18,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00, -/* 124 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, -/* 125 */ 0x00,0x0e,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00, -/* 126 */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; - -STATIC UINT32 mGraphicsEfiColors[16] = { - 0x00000000, // BLACK - 0x00000098, // LIGHTBLUE - 0x00009800, // LIGHTGREEN - 0x00009898, // LIGHTCYAN - 0x00980000, // LIGHTRED - 0x00980098, // MAGENTA - 0x00989800, // BROWN - 0x00bfbfbf, // LIGHTGRAY - 0x00303030, // DARKGRAY - BRIGHT BLACK - 0x000000ff, // BLUE - 0x0000ff00, // LIME - 0x0000ffff, // CYAN - 0x00ff0000, // RED - 0x00ff00ff, // FUCHSIA - 0x00ffff00, // YELLOW - 0x00ffffff // WHITE -}; - -STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL *mGraphicsOutput; -STATIC UINTN mConsoleWidth; -STATIC UINTN mConsoleHeight; -STATIC UINTN mConsoleMaxPosX; -STATIC UINTN mConsoleMaxPosY; -STATIC UINTN mPrivateColumn; ///< At least UEFI Shell trashes Mode values. -STATIC UINTN mPrivateRow; ///< At least UEFI Shell trashes Mode values. -STATIC UINT32 mConsoleGopMode; -STATIC UINT8 mFontScale; -STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mBackgroundColor; -STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mForegroundColor; -STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *mCharacterBuffer; -STATIC EFI_CONSOLE_CONTROL_SCREEN_MODE mConsoleMode = EfiConsoleControlScreenText; - -#define SCR_PADD 1 -#define TGT_CHAR_WIDTH ((UINTN)(ISO_CHAR_WIDTH) * mFontScale) -#define TGT_CHAR_HEIGHT ((UINTN)(ISO_CHAR_HEIGHT) * mFontScale) -#define TGT_CHAR_AREA ((TGT_CHAR_WIDTH) * (TGT_CHAR_HEIGHT)) -#define TGT_PADD_WIDTH ((TGT_CHAR_WIDTH) * (SCR_PADD)) -#define TGT_PADD_HEIGHT ((ISO_CHAR_HEIGHT) * (SCR_PADD)) -#define TGT_CURSOR_X mFontScale -#define TGT_CURSOR_Y ((TGT_CHAR_HEIGHT) - mFontScale) -#define TGT_CURSOR_WIDTH ((TGT_CHAR_WIDTH) - mFontScale*2) -#define TGT_CURSOR_HEIGHT (mFontScale) - -/** - Render character onscreen. - - @param[in] Char Character code. - @param[in] PosX Character X position. - @param[in] PosY Character Y position. -**/ -STATIC -VOID -RenderChar ( - IN CHAR16 Char, - IN UINTN PosX, - IN UINTN PosY - ) -{ - UINT32 *DstBuffer; - UINT8 *SrcBuffer; - UINT32 Line; - UINT32 Index; - UINT32 Index2; - UINT8 Mask; - - DstBuffer = &mCharacterBuffer[0].Raw; - - if ((Char >= 0 && Char < ISO_CHAR_MIN) || Char == ' ' || Char == CHAR_TAB || Char == 0x7F) { - SetMem32 (DstBuffer, TGT_CHAR_AREA * sizeof (DstBuffer[0]), mBackgroundColor.Raw); - } else { - - if (Char < 0 || Char > ISO_CHAR_MAX) { - Char = L'_'; - } - - SrcBuffer = mIsoFontData + ((Char - ISO_CHAR_MIN) * (ISO_CHAR_HEIGHT - 2)); - - SetMem32 (DstBuffer, TGT_CHAR_WIDTH * mFontScale * sizeof (DstBuffer[0]), mBackgroundColor.Raw); - DstBuffer += TGT_CHAR_WIDTH * mFontScale; - - for (Line = 0; Line < ISO_CHAR_HEIGHT - 2; ++Line) { - // - // Iterate, while the single bit drops to the right. - // - for (Index = 0; Index < mFontScale; ++Index) { - Mask = 1; - do { - for (Index2 = 0; Index2 < mFontScale; ++Index2) { - *DstBuffer = (*SrcBuffer & Mask) ? mForegroundColor.Raw : mBackgroundColor.Raw; - ++DstBuffer; - } - Mask <<= 1U; - } while (Mask != 0); - } - ++SrcBuffer; - } - - SetMem32 (DstBuffer, TGT_CHAR_WIDTH * mFontScale * sizeof (DstBuffer[0]), mBackgroundColor.Raw); - } - - mGraphicsOutput->Blt ( - mGraphicsOutput, - &mCharacterBuffer[0].Pixel, - EfiBltBufferToVideo, - 0, - 0, - TGT_PADD_WIDTH + PosX * TGT_CHAR_WIDTH, - TGT_PADD_HEIGHT + PosY * TGT_CHAR_HEIGHT, - TGT_CHAR_WIDTH, - TGT_CHAR_HEIGHT, - 0 - ); -} - -/** - Swap cursor visibility onscreen. - - @param[in] Enabled Whether cursor is visible. - @param[in] PosX Character X position. - @param[in] PosY Character Y position. -**/ -STATIC -VOID -FlushCursor ( - IN BOOLEAN Enabled, - IN UINTN PosX, - IN UINTN PosY - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Colour; - - if (!Enabled) { - return; - } - - // - // UEFI only has one cursor at a time. UEFI Shell edit command has a cursor and a mouse - // pointer, which are not connected. To be able to draw both at a time UEFI Shell constantly - // redraws both the cursor and the mouse pointer. To do that it constantly flips bg and fg - // colours as well as cursor visibility. - // It seems that the Shell implementation relies on an undocumented feature (is that a bug?) - // of hiding an already drawn cursor with a space with inverted attributes. - // This is weird but EDK II implementation seems to match the logic, and as a result we - // track cursor visibility or easily optimise this logic. - // - Status = mGraphicsOutput->Blt ( - mGraphicsOutput, - &Colour.Pixel, - EfiBltVideoToBltBuffer, - TGT_PADD_WIDTH + PosX * TGT_CHAR_WIDTH + TGT_CURSOR_X, - TGT_PADD_HEIGHT + PosY * TGT_CHAR_HEIGHT + TGT_CURSOR_Y, - 0, - 0, - 1, - 1, - 0 - ); - - if (EFI_ERROR(Status)) { - return; - } - - mGraphicsOutput->Blt ( - mGraphicsOutput, - Colour.Raw == mForegroundColor.Raw ? &mBackgroundColor.Pixel : &mForegroundColor.Pixel, - EfiBltVideoFill, - 0, - 0, - TGT_PADD_WIDTH + PosX * TGT_CHAR_WIDTH + TGT_CURSOR_X, - TGT_PADD_HEIGHT + PosY * TGT_CHAR_HEIGHT + TGT_CURSOR_Y, - TGT_CURSOR_WIDTH, - TGT_CURSOR_HEIGHT, - 0 - ); -} - -STATIC -VOID -RenderScroll ( - VOID - ) -{ - // - // Move data. - // - mGraphicsOutput->Blt ( - mGraphicsOutput, - NULL, - EfiBltVideoToVideo, - 0, - TGT_PADD_HEIGHT + TGT_CHAR_HEIGHT, - 0, - TGT_PADD_HEIGHT, - mGraphicsOutput->Mode->Info->HorizontalResolution, - TGT_CHAR_HEIGHT * (mConsoleHeight - 1), - 0 - ); - - // - // Erase last line. - // - mGraphicsOutput->Blt ( - mGraphicsOutput, - &mBackgroundColor.Pixel, - EfiBltVideoFill, - 0, - 0, - 0, - TGT_PADD_HEIGHT + TGT_CHAR_HEIGHT * (mConsoleHeight - 1), - mGraphicsOutput->Mode->Info->HorizontalResolution, - TGT_CHAR_HEIGHT, - 0 - ); -} - -STATIC -EFI_STATUS -RenderResync ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - ) -{ - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - - Info = mGraphicsOutput->Mode->Info; - - if (Info->HorizontalResolution < TGT_CHAR_WIDTH * 3 - || Info->VerticalResolution < TGT_CHAR_HEIGHT * 3) { - return EFI_DEVICE_ERROR; - } - - if (mCharacterBuffer != NULL) { - FreePool (mCharacterBuffer); - } - - mCharacterBuffer = AllocatePool (TGT_CHAR_AREA * sizeof (mCharacterBuffer[0])); - if (mCharacterBuffer == NULL) { - return EFI_DEVICE_ERROR; - } - - mConsoleGopMode = mGraphicsOutput->Mode->Mode; - mConsoleWidth = (Info->HorizontalResolution / TGT_CHAR_WIDTH) - 2 * SCR_PADD; - mConsoleHeight = (Info->VerticalResolution / TGT_CHAR_HEIGHT) - 2 * SCR_PADD; - mConsoleMaxPosX = 0; - mConsoleMaxPosY = 0; - - mPrivateColumn = mPrivateRow = 0; - This->Mode->CursorColumn = This->Mode->CursorRow = 0; - - mGraphicsOutput->Blt ( - mGraphicsOutput, - &mBackgroundColor.Pixel, - EfiBltVideoFill, - 0, - 0, - 0, - 0, - Info->HorizontalResolution, - Info->VerticalResolution, - 0 - ); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextReset ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - Status = OcHandleProtocolFallback ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &mGraphicsOutput - ); - - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return EFI_DEVICE_ERROR; - } - - This->Mode->MaxMode = 1; - This->Mode->Attribute = ARRAY_SIZE (mGraphicsEfiColors) / 2 - 1; - mBackgroundColor.Raw = mGraphicsEfiColors[0]; - mForegroundColor.Raw = mGraphicsEfiColors[ARRAY_SIZE (mGraphicsEfiColors) / 2 - 1]; - - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextOutputString ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String - ) -{ - UINTN Index; - EFI_TPL OldTpl; - EFI_STATUS Status; - - // - // Do not print text in graphics mode. - // - if (mConsoleMode != EfiConsoleControlScreenText) { - return EFI_UNSUPPORTED; - } - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - // - // Do not print in different modes. - // - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - // - // For whatever reason UEFI Shell trashes these values when executing commands like help -b. - // - This->Mode->CursorColumn = (INT32) mPrivateColumn; - This->Mode->CursorRow = (INT32) mPrivateRow; - - FlushCursor (This->Mode->CursorVisible, This->Mode->CursorColumn, This->Mode->CursorRow); - - for (Index = 0; String[Index] != '\0'; ++Index) { - // - // Carriage return should just move the cursor back. - // - if (String[Index] == CHAR_CARRIAGE_RETURN) { - This->Mode->CursorColumn = 0; - continue; - } - - if (String[Index] == CHAR_BACKSPACE) { - if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) { - This->Mode->CursorRow--; - This->Mode->CursorColumn = (INT32) (mConsoleWidth - 1); - RenderChar (' ', This->Mode->CursorColumn, This->Mode->CursorRow); - } else if (This->Mode->CursorColumn > 0) { - This->Mode->CursorColumn--; - RenderChar (' ', This->Mode->CursorColumn, This->Mode->CursorRow); - } - continue; - } - - // - // Newline should move the cursor lower. - // In case we are out of room it should scroll instead. - // - if (String[Index] == CHAR_LINEFEED) { - if ((UINTN) This->Mode->CursorRow < mConsoleHeight - 1) { - ++This->Mode->CursorRow; - mConsoleMaxPosY = MAX (mConsoleMaxPosY, (UINTN) This->Mode->CursorRow); - } else { - RenderScroll (); - } - continue; - } - - // - // Render normal symbol and decide on next cursor position. - // - RenderChar (String[Index], This->Mode->CursorColumn, This->Mode->CursorRow); - if ((UINTN) This->Mode->CursorColumn < mConsoleWidth - 1) { - // - // Continues on the same line. - // - ++This->Mode->CursorColumn; - mConsoleMaxPosX = MAX (mConsoleMaxPosX, (UINTN) This->Mode->CursorColumn); - } else if ((UINTN) This->Mode->CursorRow < mConsoleHeight - 1) { - // - // New line without scroll. - // - This->Mode->CursorColumn = 0; - ++This->Mode->CursorRow; - mConsoleMaxPosY = MAX (mConsoleMaxPosY, (UINTN) This->Mode->CursorRow); - } else { - // - // New line with scroll. - // - RenderScroll (); - This->Mode->CursorColumn = 0; - } - } - - FlushCursor (This->Mode->CursorVisible, This->Mode->CursorColumn, This->Mode->CursorRow); - - mPrivateColumn = (UINTN) This->Mode->CursorColumn; - mPrivateRow = (UINTN) This->Mode->CursorRow; - - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextTestString ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String - ) -{ - if (StrCmp (String, OC_CONSOLE_MARK_UNCONTROLLED) == 0) { - mConsoleMaxPosX = mGraphicsOutput->Mode->Info->HorizontalResolution / TGT_CHAR_WIDTH; - mConsoleMaxPosY = mGraphicsOutput->Mode->Info->VerticalResolution / TGT_CHAR_HEIGHT; - } else if (StrCmp (String, OC_CONSOLE_MARK_CONTROLLED) == 0) { - mConsoleMaxPosX = 0; - mConsoleMaxPosX = 0; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextQueryMode ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN ModeNumber, - OUT UINTN *Columns, - OUT UINTN *Rows - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - if (ModeNumber == 0) { - *Columns = mConsoleWidth; - *Rows = mConsoleHeight; - Status = EFI_SUCCESS; - } else { - Status = EFI_UNSUPPORTED; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextSetMode ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN ModeNumber - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - - if (ModeNumber != 0) { - return EFI_UNSUPPORTED; - } - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - Status = RenderResync (This); - gBS->RestoreTPL (OldTpl); - if (EFI_ERROR(Status)) { - return Status; - } - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextSetAttribute ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN Attribute - ) -{ - EFI_STATUS Status; - UINT32 FgColor; - UINT32 BgColor; - EFI_TPL OldTpl; - - if ((Attribute & ~0x7FU) != 0) { - return EFI_UNSUPPORTED; - } - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - if (Attribute != (UINTN) This->Mode->Attribute) { - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - - FgColor = BitFieldRead32 ((UINT32) Attribute, 0, 3); - BgColor = BitFieldRead32 ((UINT32) Attribute, 4, 6); - - // - // Once we change the background we should redraw everything. - // - if (mGraphicsEfiColors[BgColor] != mBackgroundColor.Raw) { - mConsoleMaxPosX = mConsoleWidth + SCR_PADD; - mConsoleMaxPosY = mConsoleHeight + SCR_PADD; - } - - mForegroundColor.Raw = mGraphicsEfiColors[FgColor]; - mBackgroundColor.Raw = mGraphicsEfiColors[BgColor]; - This->Mode->Attribute = (UINT32) Attribute; - - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - } - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextClearScreen ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - ) -{ - EFI_STATUS Status; - UINTN Width; - UINTN Height; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - // - // X coordinate points to the right most coordinate of the last printed - // character, but after this character we may also have cursor. - // Y coordinate points to the top most coordinate of the last printed row. - // - Width = TGT_PADD_WIDTH + (mConsoleMaxPosX + 1) * TGT_CHAR_WIDTH; - Height = TGT_PADD_HEIGHT + (mConsoleMaxPosY + 1) * TGT_CHAR_HEIGHT; - - mGraphicsOutput->Blt ( - mGraphicsOutput, - &mBackgroundColor.Pixel, - EfiBltVideoFill, - 0, - 0, - 0, - 0, - MIN (Width, mGraphicsOutput->Mode->Info->HorizontalResolution), - MIN (Height, mGraphicsOutput->Mode->Info->VerticalResolution), - 0 - ); - - // - // Handle cursor. - // - mPrivateColumn = mPrivateRow = 0; - This->Mode->CursorColumn = This->Mode->CursorRow = 0; - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - - // - // We do not reset max here, as we may still scroll (e.g. in shell via page buttons). - // - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextSetCursorPosition ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN Column, - IN UINTN Row - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - if (Column < mConsoleWidth && Row < mConsoleHeight) { - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - mPrivateColumn = Column; - mPrivateRow = Row; - This->Mode->CursorColumn = (INT32) mPrivateColumn; - This->Mode->CursorRow = (INT32) mPrivateRow; - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - mConsoleMaxPosX = MAX (mConsoleMaxPosX, Column); - mConsoleMaxPosY = MAX (mConsoleMaxPosY, Row); - Status = EFI_SUCCESS; - } else { - Status = EFI_UNSUPPORTED; - } - - gBS->RestoreTPL (OldTpl); - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -AsciiTextEnableCursor ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN BOOLEAN Visible - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - if (mConsoleGopMode != mGraphicsOutput->Mode->Mode) { - Status = RenderResync (This); - if (EFI_ERROR(Status)) { - gBS->RestoreTPL (OldTpl); - return Status; - } - } - - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - This->Mode->CursorVisible = Visible; - FlushCursor (This->Mode->CursorVisible, mPrivateColumn, mPrivateRow); - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - -STATIC -EFI_SIMPLE_TEXT_OUTPUT_MODE -mAsciiTextOutputMode; - -STATIC -EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL -mAsciiTextOutputProtocol = { - AsciiTextReset, - AsciiTextOutputString, - AsciiTextTestString, - AsciiTextQueryMode, - AsciiTextSetMode, - AsciiTextSetAttribute, - AsciiTextClearScreen, - AsciiTextSetCursorPosition, - AsciiTextEnableCursor, - &mAsciiTextOutputMode -}; - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlGetMode ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, - OUT BOOLEAN *GopUgaExists OPTIONAL, - OUT BOOLEAN *StdInLocked OPTIONAL - ) -{ - *Mode = mConsoleMode; - - if (GopUgaExists != NULL) { - *GopUgaExists = TRUE; - } - - if (StdInLocked != NULL) { - *StdInLocked = FALSE; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlSetMode ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - ) -{ - mConsoleMode = Mode; - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlLockStdIn ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN CHAR16 *Password - ) -{ - return EFI_DEVICE_ERROR; -} - -STATIC -EFI_CONSOLE_CONTROL_PROTOCOL -mConsoleControlProtocol = { - ConsoleControlGetMode, - ConsoleControlSetMode, - ConsoleControlLockStdIn -}; - -VOID -ConsoleControlInstall ( - VOID - ) -{ - EFI_STATUS Status; - EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; - - Status = OcHandleProtocolFallback ( - &gST->ConsoleOutHandle, - &gEfiConsoleControlProtocolGuid, - (VOID *) &ConsoleControl - ); - - if (!EFI_ERROR(Status)) { - ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics); - - CopyMem ( - ConsoleControl, - &mConsoleControlProtocol, - sizeof (mConsoleControlProtocol) - ); - } - - gBS->InstallMultipleProtocolInterfaces ( - &gST->ConsoleOutHandle, - &gEfiConsoleControlProtocolGuid, - &mConsoleControlProtocol, - NULL - ); -} - -VOID -OcUseBuiltinTextOutput ( - VOID - ) -{ - EFI_STATUS Status; - UINTN UiScaleSize; - - UiScaleSize = sizeof (mFontScale); - - Status = gRT->GetVariable ( - APPLE_UI_SCALE_VARIABLE_NAME, - &gEfiAppleNvramGuid, - NULL, - &UiScaleSize, - (VOID *) &mFontScale - ); - - if (EFI_ERROR(Status) || mFontScale != 2) { - mFontScale = 1; - } - - DEBUG ((DEBUG_INFO, "OCC: Using builtin text renderer with %d scale\n", mFontScale)); - - Status = AsciiTextReset (&mAsciiTextOutputProtocol, TRUE); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: Cannot setup ASCII output - %r\n", Status)); - return; - } - - OcConsoleControlSetMode (EfiConsoleControlScreenGraphics); - OcConsoleControlInstallProtocol (&mConsoleControlProtocol, NULL, NULL); - - gST->ConOut = &mAsciiTextOutputProtocol; - gST->Hdr.CRC32 = 0; - - gBS->CalculateCrc32 ( - gST, - gST->Hdr.HeaderSize, - &gST->Hdr.CRC32 - ); -} diff --git a/Library/OcConsoleLib/TextOutputNull.c b/Library/OcConsoleLib/TextOutputNull.c deleted file mode 100644 index d5a26331f..000000000 --- a/Library/OcConsoleLib/TextOutputNull.c +++ /dev/null @@ -1,180 +0,0 @@ -/** @file - -Copyright (c) 2017-2018, savvas -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_STATUS -EFIAPI -NullTextReset ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextOutputString ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextTestString ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextQueryMode ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN ModeNumber, - OUT UINTN *Columns, - OUT UINTN *Rows - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextSetMode ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN ModeNumber - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextSetAttribute ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN Attribute - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextClearScreen ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextSetCursorPosition ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN UINTN Column, - IN UINTN Row - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -NullTextEnableCursor ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN BOOLEAN Visible - ) -{ - return EFI_SUCCESS; -} - -STATIC -EFI_SIMPLE_TEXT_OUTPUT_MODE -mNullTextOutputMode; - -STATIC -EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL -mNullTextOutputProtocol = { - NullTextReset, - NullTextOutputString, - NullTextTestString, - NullTextQueryMode, - NullTextSetMode, - NullTextSetAttribute, - NullTextClearScreen, - NullTextSetCursorPosition, - NullTextEnableCursor, - &mNullTextOutputMode -}; - -EFI_SYSTEM_TABLE * -AllocateNullTextOutSystemTable ( - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_SYSTEM_TABLE *NewSystemTable; - EFI_STATUS Status; - - // - // Patch verbose - // - NewSystemTable = (EFI_SYSTEM_TABLE *) AllocateZeroPool (SystemTable->Hdr.HeaderSize); - - if (NewSystemTable == NULL) { - return NULL; - } - - CopyMem ((VOID *) NewSystemTable, SystemTable, SystemTable->Hdr.HeaderSize); - NewSystemTable->ConOut = &mNullTextOutputProtocol; - NewSystemTable->Hdr.CRC32 = 0; - - Status = gBS->CalculateCrc32 ( - NewSystemTable, - NewSystemTable->Hdr.HeaderSize, - &NewSystemTable->Hdr.CRC32 - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCC: Failed to calculated new system table CRC32 with Status: %r\n", Status)); - FreePool (NewSystemTable); - return NULL; - } - - return NewSystemTable; -} diff --git a/Library/OcConsoleLib/TextOutputSystem.c b/Library/OcConsoleLib/TextOutputSystem.c deleted file mode 100644 index adf6f9068..000000000 --- a/Library/OcConsoleLib/TextOutputSystem.c +++ /dev/null @@ -1,368 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Current reported console mode. -// -STATIC -EFI_CONSOLE_CONTROL_SCREEN_MODE -mConsoleMode = EfiConsoleControlScreenText; - -// -// Disable text output in graphics mode. -// -STATIC -BOOLEAN -mIgnoreTextInGraphics = FALSE; - -// -// Clear screen when switching from graphics mode to text mode. -// -STATIC -BOOLEAN -mClearScreenOnModeSwitch = FALSE; - -// -// Replace tab character with a space in output. -// -STATIC -BOOLEAN -mReplaceTabWithSpace = FALSE; - -// -// Original text output function. -// -STATIC -EFI_TEXT_STRING -mOriginalOutputString; - -// -// Original clear screen function. -// -STATIC -EFI_TEXT_CLEAR_SCREEN -mOriginalClearScreen; - -// -// Original console control protocol functions. -// -STATIC -EFI_CONSOLE_CONTROL_PROTOCOL -mOriginalConsoleControlProtocol; - -// -// EFI background colours. -// -STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiBackgroundColors[8] = { - // - // B G R reserved - // - {0x00, 0x00, 0x00, 0x00}, // BLACK - {0x98, 0x00, 0x00, 0x00}, // LIGHTBLUE - {0x00, 0x98, 0x00, 0x00}, // LIGHGREEN - {0x98, 0x98, 0x00, 0x00}, // LIGHCYAN - {0x00, 0x00, 0x98, 0x00}, // LIGHRED - {0x98, 0x00, 0x98, 0x00}, // MAGENTA - {0x00, 0x98, 0x98, 0x00}, // BROWN - {0x98, 0x98, 0x98, 0x00}, // LIGHTGRAY -}; - -STATIC -EFI_STATUS -EFIAPI -ControlledOutputString ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, - IN CHAR16 *String - ) -{ - UINTN Index; - UINTN Size; - CHAR16 *StringCopy; - EFI_STATUS Status; - - if (mConsoleMode == EfiConsoleControlScreenText || !mIgnoreTextInGraphics) { - if (mReplaceTabWithSpace) { - Size = StrSize (String); - - StringCopy = AllocatePool (Size); - if (StringCopy == NULL) { - return mOriginalOutputString (This, String); - } - - Size /= sizeof (CHAR16); - for (Index = 0; Index < Size; Index++) { - if (String[Index] == L'\t') { - StringCopy[Index] = L' '; - } else { - StringCopy[Index] = String[Index]; - } - } - Status = mOriginalOutputString (This, StringCopy); - FreePool(StringCopy); - return Status; - } - - return mOriginalOutputString (This, String); - } - - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -ControlledClearScreen ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - UINT32 Width; - UINT32 Height; - UINTN SizeOfInfo; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - - Status = OcHandleProtocolFallback ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (!EFI_ERROR(Status)) { - Status = GraphicsOutput->QueryMode ( - GraphicsOutput, - GraphicsOutput->Mode->Mode, - &SizeOfInfo, - &Info - ); - if (!EFI_ERROR(Status)) { - Width = Info->HorizontalResolution; - Height = Info->VerticalResolution; - FreePool (Info); - } else { - GraphicsOutput = NULL; - } - } else { - GraphicsOutput = NULL; - } - - // - // On APTIO V with large resolution (e.g. 2K or 4K) ClearScreen - // invocation resets resolution to 1024x768. To avoid the glitches - // we clear the screen manually, doing with other methods results - // in screen flashes and other problems. - // - - if (GraphicsOutput != NULL) { - Status = GraphicsOutput->Blt ( - GraphicsOutput, - &mEfiBackgroundColors[BitFieldRead32 ((UINT32) This->Mode->Attribute, 4, 6)], - EfiBltVideoFill, - 0, - 0, - 0, - 0, - Width, - Height, - 0 - ); - - This->SetCursorPosition (This, 0, 0); - } else { - Status = mOriginalClearScreen (This); - } - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlGetMode ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, - OUT BOOLEAN *GopUgaExists OPTIONAL, - OUT BOOLEAN *StdInLocked OPTIONAL - ) -{ - EFI_STATUS Status; - - if (mOriginalConsoleControlProtocol.GetMode != NULL) { - Status = mOriginalConsoleControlProtocol.GetMode ( - This, - Mode, - GopUgaExists, - StdInLocked - ); - - if (!EFI_ERROR(Status)) { - mConsoleMode = *Mode; - } - - return Status; - } - - *Mode = mConsoleMode; - - if (GopUgaExists != NULL) { - *GopUgaExists = TRUE; - } - - if (StdInLocked != NULL) { - *StdInLocked = FALSE; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlSetMode ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - ) -{ - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - - DEBUG ((DEBUG_INFO, "OCC: Setting cc mode %d -> %d\n", mConsoleMode, Mode)); - - mConsoleMode = Mode; - - if (mClearScreenOnModeSwitch && Mode == EfiConsoleControlScreenText) { - Status = OcHandleProtocolFallback ( - gST->ConsoleOutHandle, - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (!EFI_ERROR(Status)) { - Status = GraphicsOutput->Blt ( - GraphicsOutput, - &mEfiBackgroundColors[BitFieldRead32 ((UINT32) gST->ConOut->Mode->Attribute, 4, 6)], - EfiBltVideoFill, - 0, - 0, - 0, - 0, - GraphicsOutput->Mode->Info->HorizontalResolution, - GraphicsOutput->Mode->Info->VerticalResolution, - 0 - ); - } - } - - if (mOriginalConsoleControlProtocol.SetMode != NULL) { - return mOriginalConsoleControlProtocol.SetMode ( - This, - Mode - ); - } - - // - // Disable and hide flashing cursor when switching to graphics from text. - // This may be the case when we formerly handled text input or output. - // - if (Mode == EfiConsoleControlScreenGraphics) { - gST->ConOut->EnableCursor (gST->ConOut, FALSE); - gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -ConsoleControlLockStdIn ( - IN EFI_CONSOLE_CONTROL_PROTOCOL *This, - IN CHAR16 *Password - ) -{ - if (mOriginalConsoleControlProtocol.LockStdIn != NULL) { - return mOriginalConsoleControlProtocol.LockStdIn ( - This, - Password - ); - } - - return EFI_DEVICE_ERROR; -} - -STATIC -EFI_CONSOLE_CONTROL_PROTOCOL -mConsoleControlProtocol = { - ConsoleControlGetMode, - ConsoleControlSetMode, - ConsoleControlLockStdIn -}; - -VOID -OcUseSystemTextOutput ( - IN OC_CONSOLE_RENDERER Renderer, - IN BOOLEAN IgnoreTextOutput, - IN BOOLEAN SanitiseClearScreen, - IN BOOLEAN ClearScreenOnModeSwitch, - IN BOOLEAN ReplaceTabWithSpace - ) -{ - DEBUG (( - DEBUG_INFO, - "OCC: Configuring system console ignore %d san clear %d clear switch %d replace tab %d\n", - IgnoreTextOutput, - SanitiseClearScreen, - ClearScreenOnModeSwitch, - ReplaceTabWithSpace - )); - - if (Renderer == OcConsoleRendererSystemGraphics) { - OcConsoleControlSetMode (EfiConsoleControlScreenGraphics); - OcConsoleControlInstallProtocol (&mConsoleControlProtocol, NULL, &mConsoleMode); - } else if (Renderer == OcConsoleRendererSystemText) { - OcConsoleControlSetMode (EfiConsoleControlScreenText); - OcConsoleControlInstallProtocol (&mConsoleControlProtocol, NULL, &mConsoleMode); - } else { - OcConsoleControlInstallProtocol (&mConsoleControlProtocol, &mOriginalConsoleControlProtocol, &mConsoleMode); - } - - mIgnoreTextInGraphics = IgnoreTextOutput; - mClearScreenOnModeSwitch = ClearScreenOnModeSwitch; - mReplaceTabWithSpace = ReplaceTabWithSpace; - - if (IgnoreTextOutput || ReplaceTabWithSpace) { - mOriginalOutputString = gST->ConOut->OutputString; - gST->ConOut->OutputString = ControlledOutputString; - } - - if (SanitiseClearScreen) { - mOriginalClearScreen = gST->ConOut->ClearScreen; - gST->ConOut->ClearScreen = ControlledClearScreen; - } -} diff --git a/Library/OcConsoleLib/UgaPassThrough.c b/Library/OcConsoleLib/UgaPassThrough.c deleted file mode 100644 index 9960a4d58..000000000 --- a/Library/OcConsoleLib/UgaPassThrough.c +++ /dev/null @@ -1,253 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OcConsoleLibInternal.h" - -#include -#include -#include - -STATIC -EFI_STATUS -EFIAPI -OcUgaDrawGetMode ( - IN EFI_UGA_DRAW_PROTOCOL *This, - OUT UINT32 *HorizontalResolution, - OUT UINT32 *VerticalResolution, - OUT UINT32 *ColorDepth, - OUT UINT32 *RefreshRate - ) -{ - OC_UGA_PROTOCOL *OcUgaDraw; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - - DEBUG ((DEBUG_INFO, "OCC: OcUgaDrawGetMode %p\n", This)); - - if (This == NULL - || HorizontalResolution == NULL - || VerticalResolution == NULL - || ColorDepth == NULL - || RefreshRate == NULL) { - return EFI_INVALID_PARAMETER; - } - - OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga); - Info = OcUgaDraw->GraphicsOutput->Mode->Info; - - DEBUG (( - DEBUG_INFO, - "OCC: OcUgaDrawGetMode Info is %ux%u (%u)\n", - Info->HorizontalResolution, - Info->VerticalResolution, - Info->PixelFormat - )); - - if (Info->HorizontalResolution == 0 || Info->VerticalResolution == 0) { - return EFI_NOT_STARTED; - } - - *HorizontalResolution = Info->HorizontalResolution; - *VerticalResolution = Info->VerticalResolution; - *ColorDepth = DEFAULT_COLOUR_DEPTH; - *RefreshRate = DEFAULT_REFRESH_RATE; - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -OcUgaDrawSetMode ( - IN EFI_UGA_DRAW_PROTOCOL *This, - IN UINT32 HorizontalResolution, - IN UINT32 VerticalResolution, - IN UINT32 ColorDepth, - IN UINT32 RefreshRate - ) -{ - EFI_STATUS Status; - OC_UGA_PROTOCOL *OcUgaDraw; - - OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga); - - DEBUG (( - DEBUG_INFO, - "OCC: OcUgaDrawSetMode %p %ux%u@%u/%u\n", - This, - HorizontalResolution, - VerticalResolution, - ColorDepth, - RefreshRate - )); - - OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga); - - Status = OcSetConsoleResolutionForProtocol ( - OcUgaDraw->GraphicsOutput, - HorizontalResolution, - VerticalResolution, - ColorDepth - ); - - DEBUG ((DEBUG_INFO, "OCC: UGA SetConsoleResolutionOnHandle attempt - %r\n", Status)); - - if (EFI_ERROR(Status)) { - Status = OcSetConsoleResolutionForProtocol ( - OcUgaDraw->GraphicsOutput, - 0, - 0, - 0 - ); - DEBUG ((DEBUG_INFO, "OCC: UGA SetConsoleResolutionOnHandle max attempt - %r\n", Status)); - } - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -OcUgaDrawBlt ( - IN EFI_UGA_DRAW_PROTOCOL *This, - IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, - IN EFI_UGA_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta OPTIONAL - ) -{ - OC_UGA_PROTOCOL *OcUgaDraw; - - OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga); - - return OcUgaDraw->GraphicsOutput->Blt ( - OcUgaDraw->GraphicsOutput, - (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer, - (EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation, - SourceX, - SourceY, - DestinationX, - DestinationY, - Width, - Height, - Delta - ); -} - -EFI_STATUS -OcProvideUgaPassThrough ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_UGA_DRAW_PROTOCOL *UgaDraw; - OC_UGA_PROTOCOL *OcUgaDraw; - - // - // For now we do not use this, but as a side note: - // MacPro5,1 has 2 GOP protocols: - // - for GPU - // - for ConsoleOutput - // and 1 UGA protocol: - // - for unknown handle - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiUgaDrawProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - if (!EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA draw\n", (UINT32) HandleCount)); - FreePool (HandleBuffer); - } else { - DEBUG ((DEBUG_INFO, "OCC: Found NO handles with UGA draw\n")); - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiGraphicsOutputProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - if (!EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: Found %u handles with GOP for UGA check\n", (UINT32) HandleCount)); - - for (Index = 0; Index < HandleCount; ++Index) { - DEBUG ((DEBUG_INFO, "OCC: Trying handle %u - %p\n", (UINT32) Index, HandleBuffer[Index])); - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: No GOP protocol - %r\n", Status)); - continue; - } - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiUgaDrawProtocolGuid, - (VOID **) &UgaDraw - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCC: No UGA protocol - %r\n", Status)); - - OcUgaDraw = AllocateZeroPool (sizeof (*OcUgaDraw)); - if (OcUgaDraw == NULL) { - DEBUG ((DEBUG_INFO, "OCC: Failed to allocate UGA protocol\n")); - continue; - } - - OcUgaDraw->GraphicsOutput = GraphicsOutput; - OcUgaDraw->Uga.GetMode = OcUgaDrawGetMode; - OcUgaDraw->Uga.SetMode = OcUgaDrawSetMode; - OcUgaDraw->Uga.Blt = OcUgaDrawBlt; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &HandleBuffer[Index], - &gEfiUgaDrawProtocolGuid, - &OcUgaDraw->Uga, - NULL - ); - - DEBUG ((DEBUG_INFO, "OCC: Installed UGA protocol - %r\n", Status)); - } else { - DEBUG ((DEBUG_INFO, "OCC: Has UGA protocol, skip\n")); - continue; - } - } - - FreePool (HandleBuffer); - } else { - DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP\n")); - } - - return Status; -} diff --git a/Library/OcCpuLib/AppleCpuSupport.c b/Library/OcCpuLib/AppleCpuSupport.c deleted file mode 100644 index dc6c67bd6..000000000 --- a/Library/OcCpuLib/AppleCpuSupport.c +++ /dev/null @@ -1,627 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include - -#include "OcCpuInternals.h" - -UINT8 -InternalDetectAppleMajorType ( - IN CONST CHAR8 *BrandString - ) -{ - CONST CHAR8 *BrandInfix; - - BrandInfix = AsciiStrStr (BrandString, "Core"); - if (BrandInfix != NULL) { - while ((*BrandInfix != ' ') && (*BrandInfix != '\0')) { - ++BrandInfix; - } - - while (*BrandInfix == ' ') { - ++BrandInfix; - } - - if (AsciiStrnCmp (BrandInfix, "i7", L_STR_LEN ("i7")) == 0) { - return AppleProcessorMajorI7; - } - if (AsciiStrnCmp (BrandInfix, "i5", L_STR_LEN ("i5")) == 0) { - return AppleProcessorMajorI5; - } - if (AsciiStrnCmp (BrandInfix, "i3", L_STR_LEN ("i3")) == 0) { - return AppleProcessorMajorI3; - } - if (AsciiStrnCmp (BrandInfix, "i9", L_STR_LEN ("i9")) == 0) { - return AppleProcessorMajorI9; - } - if (AsciiStrnCmp (BrandInfix, "m3", L_STR_LEN ("m3")) == 0) { - return AppleProcessorMajorM3; - } - if (AsciiStrnCmp (BrandInfix, "m5", L_STR_LEN ("m5")) == 0) { - return AppleProcessorMajorM5; - } - if (AsciiStrnCmp (BrandInfix, "m7", L_STR_LEN ("m7")) == 0) { - return AppleProcessorMajorM7; - } - if (AsciiStrnCmp (BrandInfix, "M", L_STR_LEN ("M")) == 0) { - return AppleProcessorMajorM; - } - if (AsciiStrnCmp (BrandInfix, "Duo", L_STR_LEN ("Duo")) == 0) { - return AppleProcessorMajorCore2; - } - if (AsciiStrnCmp (BrandInfix, "Quad", L_STR_LEN ("Quad")) == 0) { - return AppleProcessorMajorXeonPenryn; - } - return AppleProcessorMajorCore; - } - - BrandInfix = AsciiStrStr (BrandString, "Xeon"); - if (BrandInfix != NULL) { - while ((*BrandInfix != ' ') && (*BrandInfix != '\0')) { - ++BrandInfix; - } - - while (*BrandInfix == ' ') { - ++BrandInfix; - } - - // - // Support Xeon Scalable chips: Xeon(R) Gold 6136 CPU - // - if (AsciiStrnCmp (BrandInfix, "Bronze", L_STR_LEN ("Bronze")) == 0 || - AsciiStrnCmp (BrandInfix, "Silver", L_STR_LEN ("Silver")) == 0 || - AsciiStrnCmp (BrandInfix, "Gold", L_STR_LEN ("Gold")) == 0 || - AsciiStrnCmp (BrandInfix, "Platinum", L_STR_LEN ("Platinum")) == 0) { - // Treat Xeon Scalable chips as their closest relatives, Xeon W - return AppleProcessorMajorXeonW; - } - - // - // Support both variants: Xeon(R) E5-1234 and Xeon(R) CPU E5-1234 - // - if (AsciiStrnCmp (BrandInfix, "CPU", L_STR_LEN ("CPU")) == 0) { - BrandInfix += L_STR_LEN ("CPU"); - while (*BrandInfix == ' ') { - ++BrandInfix; - } - } - - if (AsciiStrnCmp (BrandInfix, "E5", L_STR_LEN ("E5")) == 0) { - return AppleProcessorMajorXeonE5; - } - if (AsciiStrnCmp (BrandInfix, "W", L_STR_LEN ("W")) == 0) { - return AppleProcessorMajorXeonW; - } - return AppleProcessorMajorXeonNehalem; - } - - return AppleProcessorMajorUnknown; -} - -UINT16 -InternalDetectAppleProcessorType ( - IN UINT8 Model, - IN UINT8 Stepping, - IN UINT8 AppleMajorType - ) -{ - switch (Model) { - // - // Yonah: https://en.wikipedia.org/wiki/Yonah_(microprocessor)#Models_and_brand_names - // - // Used by Apple: - // Core Duo, Core Solo - // - // NOT used by Apple: - // Pentium, Celeron - // - // All 0x0201. - // - case CPU_MODEL_DOTHAN: // 0x0D - case CPU_MODEL_YONAH: // 0x0E - // IM41 (T2400/T2500), MM11 (Solo T1200 / Duo T2300/T2400), - // MBP11 (L2400/T2400/T2500/T2600), MBP12 (T2600), - // MB11 (T2400/T2500) - return AppleProcessorTypeCoreSolo; // 0x0201 - - // - // Merom: https://en.wikipedia.org/wiki/Merom_(microprocessor)#Variants - // Penryn: https://en.wikipedia.org/wiki/Penryn_(microprocessor)#Variants - // - // Used by Apple: - // Core 2 Extreme, Core 2 Duo (Merom), - // Core 2 Duo, (Penryn), - // certain Clovertown (Merom) / Harpertown (Penryn) based models - // - // Not used by Apple: - // Merom: Core 2 Solo, Pentium, Celeron M, Celeron - // Penryn: Core 2 Extreme, Core 2 Quad, Core 2 Solo, Pentium, Celeron - // - case CPU_MODEL_MEROM: // 0x0F - case CPU_MODEL_PENRYN: // 0x17 - if (AppleMajorType == AppleProcessorMajorCore2) { - // TODO: add check for models above. (by changing the following "if (0)") - if (0) { - // ONLY MBA31 (SU9400/SU9600) and MBA32 (SL9400/SL9600) - return AppleProcessorTypeCore2DuoType2; // 0x0302 - } - // IM51 (T7200), IM61 (T7400), IM71 (T7300), IM81 (E8435), IM101 (E7600), - // MM21 (unknown), MM31 (P7350), - // MBP21 (T7600), MBP22 (unknown), MBP31 (T7700), MBP41 (T8300), MBP71 (P8600), - // MBP51 (P8600), MBP52 (T9600), MBP53 (P8800), MBP54 (P8700), MBP55 (P7550), - // MBA11 (P7500), MBA21 (SL9600), - // MB21 (unknown), MB31 (T7500), MB41 (T8300), MB51 (P8600), MB52 (P7450), MB61 (P7550), MB71 (P8600) - return AppleProcessorTypeCore2DuoType1; // 0x0301 - } - if (AppleMajorType == AppleProcessorMajorXeonPenryn) { - // MP21 (2x X5365), MP31 (2x E5462) - 0x0402 - // FIXME: check when 0x0401 will be used. - return AppleProcessorTypeXeonPenrynType2; // 0x0402 - } - // here stands for models not used by Apple (Merom/Penryn), putting 0x0301 as lowest - return AppleProcessorTypeCore2DuoType1; // 0x0301 - - // - // Nehalem: https://en.wikipedia.org/wiki/Nehalem_(microarchitecture)#Server_and_desktop_processors - // Westmere: https://en.wikipedia.org/wiki/Westmere_(microarchitecture)#Server_/_Desktop_processors - // - // Used by Apple: - // Gainestown (Xeon), Bloomfield (Xeon), Lynnfield (i5/i7) [Nehalem] - // Gulftown (aka Westmere-EP, Xeon), Clarkdale (i3/i5), Arrandale (i5/i7) [Westmere] - // - // Not used by Apple: - // Beckton (Xeon), Jasper Forest (Xeon), Clarksfield (i7), Pentium, Celeron [Nehalem] - // Westmere-EX (Xeon E7), Pentium, Celeron [Westmere] - // - case CPU_MODEL_NEHALEM: // 0x1A - case CPU_MODEL_NEHALEM_EX: // 0x2E, not used by Apple - case CPU_MODEL_FIELDS: // 0x1E, Lynnfield, Clarksfield (part of Nehalem) - case CPU_MODEL_WESTMERE: // 0x2C - case CPU_MODEL_WESTMERE_EX: // 0x2F, not used by Apple - case CPU_MODEL_DALES_32NM: // 0x25, Clarkdale, Arrandale (part of Westmere) - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { - // MP41 & Xserve31 (2x E5520, CPU_MODEL_NEHALEM), MP51 (2x X5670, CPU_MODEL_WESTMERE) - return AppleProcessorTypeXeon; // 0x0501 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // IM112 (i3-540, 0x0901, CPU_MODEL_DALES_32NM) - return AppleProcessorTypeCorei3Type1; // 0x0901 - } - if (AppleMajorType == AppleProcessorMajorI5) { - // FIXME: no idea what it is on IM112 (i5-680) - // MBP61, i5-640M, 0x0602, CPU_MODEL_DALES_32NM - return AppleProcessorTypeCorei5Type2; // 0x0602 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // FIXME: used by Apple, no idea what to use, assuming 0x0702 for now (based off 0x0602 on i5) - return AppleProcessorTypeCorei7Type2; // 0x0702 - } - // here stands for Pentium and Celeron (Nehalem/Westmere), not used by Apple at all. - // putting 0x0901 (i3) as lowest - return AppleProcessorTypeCorei3Type1; // 0x0901 - - // - // Sandy Bridge: https://en.wikipedia.org/wiki/Sandy_Bridge#List_of_Sandy_Bridge_processors - // Sandy Bridge-E: https://en.wikipedia.org/wiki/Sandy_Bridge-E#Overview - // - // Used by Apple: - // Core i5/i7 / i3 (see NOTE below) - // - // NOTE: There seems to be one more i3-2100 used on IM121 (EDU), - // assuming it exists for now. - // - // Not used by Apple: - // Xeon v1 (E5/E3), - // SNB-E based Core i7 (and Extreme): 3970X, 3960X, 3930K, 3820, - // Pentium, Celeron - // - case CPU_MODEL_SANDYBRIDGE: // 0x2A - case CPU_MODEL_JAKETOWN: // 0x2D, SNB-E, not used by Apple - if (AppleMajorType == AppleProcessorMajorI3) { - // FIXME: used by Apple on iMac12,1 (EDU, i3-2100), not confirmed yet - return AppleProcessorTypeCorei3Type3; // 0x0903 - } - if (AppleMajorType == AppleProcessorMajorI5) { - // NOTE: two values are used here. (0x0602 and 0x0603) - // TODO: how to classify them. (by changing "if (0)") - if (0) { - // MM51 (i5-2415M), MM52 (i5-2520M), MBA41 (i5-2467M), MBA42 (i5-2557M) - return AppleProcessorTypeCorei5Type2; // 0x0602 - } - // IM121 (i5-2400S), MBP81 (i5-2415M) - return AppleProcessorTypeCorei5Type3; // 0x0603 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // IM122 (i7-2600), MBP82 (i7-2675QM), MBP83 (i7-2820QM) - // - // FIXME: will those i7 not used by Apple (see above), be identified as AppleProcessorMajorI7? - return AppleProcessorTypeCorei7Type3; // 0x0703 - } - if (AppleMajorType == AppleProcessorMajorXeonE5) { // see TODO below - // for Sandy Xeon E5, not used by Apple - // FIXME: is AppleProcessorMajorXeonE5, which seems to be for IVY-E only, compatible with SNB-E too? - // TODO: write some decent code to check SNB-E based Xeon E5. - return AppleProcessorTypeXeonE5; // 0x0A01 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Sandy Xeon E3 - // NOTE: Xeon E3 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for SNB based Xeon E3 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (Sandy), not used by Apple at all. - // putting 0x0903 (i3) as lowest - return AppleProcessorTypeCorei3Type3; // 0x0903 - - // - // Ivy Bridge: https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#List_of_Ivy_Bridge_processors - // Ivy Bridge-E: https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings_2 - // - // Used by Apple: - // Core i5/i7 / i3 (see NOTE below), - // Xeon E5 v2 - // - // NOTE: There seems to be an iMac13,1 (EDU version), or rather iMac13,3, with CPU i3-3225, - // assuming it exists for now. - // - // Not used by Apple: - // Xeon v2 (E7/E3), - // IVY-E based Core i7 (and Extreme): 4960X, 4930K, 4820K, - // Pentium, Celeron - // - case CPU_MODEL_IVYBRIDGE: // 0x3A - case CPU_MODEL_IVYBRIDGE_EP: // 0x3E - if (AppleMajorType == AppleProcessorMajorXeonE5) { - // MP61 (E5-1620 v2) - return AppleProcessorTypeXeonE5; // 0x0A01 - } - if (AppleMajorType == AppleProcessorMajorI5) { - // IM131 (i5-3470S), IM132 (i5-3470S), - // MBP92 (i5-3210M), MBP102 (i5-3210M) - // MBA51 (i6-3317U), MBA52 (i5-3427U) - return AppleProcessorTypeCorei5Type4; // 0x0604 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // MM62 (i7-3615QM), - // MBP91 (i7-3615QM), MBP101 (i7-3820QM) - // - // FIXME: will those i7 not used by Apple (see above), be identified as AppleProcessorMajorI7? - return AppleProcessorTypeCorei7Type4; // 0x0704 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // FIXME: used by Apple (if iMac13,3 were existent, i3-3225), not confirmed yet - // assuming it exists for now - return AppleProcessorTypeCorei3Type4; // 0x0904 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Ivy/Ivy-E E3/E7, not used by Apple - // NOTE: Xeon E3/E7 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for IVY based Xeon E3/E7 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (Ivy), not used by Apple at all. - // putting 0x0904 (i3) as lowest. - return AppleProcessorTypeCorei3Type4; // 0x0904 - - // - // Haswell: https://en.wikipedia.org/wiki/Haswell_(microarchitecture)#List_of_Haswell_processors - // Haswell-E: basically the same page. - // - // Used by Apple: - // Core i5/i7 - // - // Not used by Apple: - // Xeon v3 (E7/E5/E3), - // Core i3, - // Haswell-E based Core i7 Extreme: 5960X, 5930K, 5820K, - // Pentium, Celeron - // - case CPU_MODEL_HASWELL: // 0x3C - case CPU_MODEL_HASWELL_EP: // 0x3F - case CPU_MODEL_HASWELL_ULT: // 0x45 - if (AppleMajorType == AppleProcessorMajorI5) { - // IM141 (i5-4570R), IM142 (i5-4670), IM151 (i5-4690), - // MM71 (i5-4260U), - // MBA62 (i5-4250U) - return AppleProcessorTypeCorei5Type5; // 0x0605 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // MBP112 (i7-4770HQ), MBP113 (i7-4850HQ) - // - // FIXME: will those i7 not used by Apple (see above), be identified as AppleProcessorMajorI7? - return AppleProcessorTypeCorei7Type5; // 0x0705 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // for i3, not used by Apple, just for showing i3 in "About This Mac". - return AppleProcessorTypeCorei3Type5; // 0x0905 - } - if (AppleMajorType == AppleProcessorMajorXeonE5) { // see TODO below - // for Haswell-E Xeon E5, not used by Apple - // FIXME: is AppleProcessorMajorXeonE5, which seems to be for IVY-E only, compatible with Haswell-E too? - // TODO: write some decent code to check Haswell-E based Xeon E5. - return AppleProcessorTypeXeonE5; // 0x0A01 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Haswell/Haswell-E E3/E7, not used by Apple - // NOTE: Xeon E3/E7 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for Haswell/Haswell-E based Xeon E3/E7 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (Haswell), not used by Apple at all. - // putting 0x0905 (i3) as lowest. - return AppleProcessorTypeCorei3Type5; // 0x0905 - - // - // Broadwell: https://en.wikipedia.org/wiki/Broadwell_(microarchitecture)#List_of_Broadwell_processors - // Broadwell-E: https://en.wikipedia.org/wiki/Broadwell_(microarchitecture)#"Broadwell-E"_HEDT_(14_nm) - // - // NOTE: support table for BDW-E is missing in XNU, thus a CPUID patch might be needed. (See Clover FakeCPUID) - // - // Used by Apple: - // Core i5/i7, Core M - // - // Not used by Apple: - // Broadwell-E: i7 6950X/6900K/6850K/6800K, - // Xeon v4 (E5/E3), - // Core i3, - // Pentium, Celeron - // - case CPU_MODEL_BROADWELL: // 0x3D - case CPU_MODEL_BROADWELL_EP: // 0x4F - case CPU_MODEL_CRYSTALWELL: // 0x46 - case CPU_MODEL_BRYSTALWELL: // 0x47 - if (AppleMajorType == AppleProcessorMajorM) { - // MB81 (M 5Y51) - return AppleProcessorTypeCoreMType6; // 0x0B06 - } - if (AppleMajorType == AppleProcessorMajorI5) { - // IM161 (i5-5250U), IM162 (i5-5675R), - // MBP121 (i5-5257U), - // MBA71 (i5-5250U), MBA72 (unknown) - return AppleProcessorTypeCorei5Type6; // 0x0606 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // FIXME: 0x0706 is just an ideal value for i7, waiting for confirmation - // FIXME: will those i7 not used by Apple (see above), be identified as AppleProcessorMajorI7? - return AppleProcessorTypeCorei7Type6; // 0x0706 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // for i3, not used by Apple, just for showing i3 in "About This Mac". - // FIXME: 0x0906 is just an ideal value for i3, waiting for confirmation - return AppleProcessorTypeCorei3Type6; // 0x0906 - } - if (AppleMajorType == AppleProcessorMajorXeonE5) { // see TODO below - // for Broadwell-E Xeon E5, not used by Apple - // FIXME: is AppleProcessorMajorXeonE5, which seems to be for IVY-E only, compatible with Broadwell-E too? - // TODO: write some decent code to check Broadwell-E based Xeon E5. - return AppleProcessorTypeXeonE5; // 0x0A01 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Broadwell E3, not used by Apple - // NOTE: Xeon E3 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for Broadwell based Xeon E3 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (Broadwell), not used by Apple at all. - // putting 0x0906 (i3) as lowest. - return AppleProcessorTypeCorei3Type5; // 0x0906 - - // - // Skylake: https://en.wikipedia.org/wiki/Skylake_(microarchitecture)#List_of_Skylake_processor_models - // - // Used by Apple: - // Xeon W, Core m3, m5, m7, i5, i7 - // - // Not used by Apple: - // Core i3, - // all high-end models (Core i9, i7 Extreme): see https://en.wikipedia.org/wiki/Skylake_(microarchitecture)#High-end_desktop_processors - // Xeon E3 v5, Xeon Scalable - // Pentium, Celeron - // - case CPU_MODEL_SKYLAKE: // 0x4E - case CPU_MODEL_SKYLAKE_DT: // 0x5E - case CPU_MODEL_SKYLAKE_W: // 0x55, also SKL-X and SKL-SP - if (AppleMajorType == AppleProcessorMajorXeonW) { - // IMP11 (Xeon W 2140B) - return AppleProcessorTypeXeonW; // 0x0F01 - } - if (AppleMajorType == AppleProcessorMajorM3) { - // FIXME: we dont have any m3 (Skylake) dump! - // using an ideal value (0x0C07), which is used on MB101 (m3-7Y32) - return AppleProcessorTypeCoreM3Type7; // 0x0C07 - } - if (AppleMajorType == AppleProcessorMajorM5) { - // MB91 (m5 6Y54) - return AppleProcessorTypeCoreM5Type7; // 0x0D07 - } - if (AppleMajorType == AppleProcessorMajorM7) { - // FIXME: we dont have any m7 (Skylake) dump! - // using an ideal value (0x0E07) - return AppleProcessorTypeCoreM7Type7; // 0x0E07 - } - if (AppleMajorType == AppleProcessorMajorI5) { - return AppleProcessorTypeCorei5Type5; // 0x0605 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // FIXME: used by Apple, but not sure what to use... - // 0x0707 is used on MBP133 (i7-6700HQ), - // 0x0705 is not confirmed, just an ideal one comparing to 0x0605 (AppleProcessorTypeCorei5Type5) - // using 0x0705 for now - return AppleProcessorTypeCorei7Type5; // 0x0705 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // for i3, not used by Apple, just for showing i3 in "About This Mac". - return AppleProcessorTypeCorei3Type5; // 0x0905 - } - if (AppleMajorType == AppleProcessorMajorI9) { - // for i9 (SKL-X), not used by Apple, just for showing i9 in "About This Mac". - // FIXME: i9 was not introdced in this era but later (MBP151, Coffee Lake), - // will AppleProcessorMajorI9 work here? - // NOTE: using a mostly invalid value 0x1005 for now... - return AppleProcessorTypeCorei9Type5; // 0x1005 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Skylake E3 (there's no E5/E7 on Skylake), not used by Apple - // NOTE: Xeon E3 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for Skylake based Xeon E3 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (Skylake), not used by Apple at all. - // putting 0x0905 (i3) as lowest. - return AppleProcessorTypeCorei3Type5; // 0x0905 - - // - // Kaby Lake: https://en.wikipedia.org/wiki/Kaby_Lake#List_of_7th_generation_Kaby_Lake_processors - // Coffee Lake: https://en.wikipedia.org/wiki/Coffee_Lake#List_of_8th_generation_Coffee_Lake_processors - // - // Used by Apple: - // Core m3 [Kaby], - // Core i5/i7 [Kaby/Coffee], - // Core i9 [Coffee], - // - // Not used by Apple: - // Core i3 [Kaby/Coffee], - // Xeon E3 v6 [Kaby], - // Xeon E [Coffee], - // Pentium, Celeron - // - case CPU_MODEL_KABYLAKE: // 0x8E - case CPU_MODEL_COFFEELAKE: // 0x9E - case CPU_MODEL_COMETLAKE_S: // 0xA5 FIXME - unknown, for now - case CPU_MODEL_COMETLAKE_U: // 0xA6 FIXME - unknown, for now - case CPU_MODEL_ICELAKE_Y: // 0x7D FIXME - unknown, for now - case CPU_MODEL_ICELAKE_U: // 0x7E FIXME - unknown, for now - case CPU_MODEL_ICELAKE_SP: // 0x9F FIXME - unknown, for now - if (AppleMajorType == AppleProcessorMajorM3) { - // MB101 (m3 7Y32) - return AppleProcessorTypeCoreM3Type7; // 0x0C07 - } - if (AppleMajorType == AppleProcessorMajorI5) { - // Kaby has 0x9 stepping, and Coffee use 0xA / 0xB stepping. - if (Stepping == 9) { - // IM181 (i5-7360U), IM182 (i5-7400), IM183 (i5-7600), IM191 (i5-8600) [NOTE 1] - // MBP141 (i5-7360U), MBP142 (i5-7267U) - // - // NOTE 1: IM191 is Coffee and thus 0x0609 will be used, TODO. - return AppleProcessorTypeCorei5Type5; // 0x0605 - } - // MM81 (i5-8500B) - // MBP152 (i5-8259U) - return AppleProcessorTypeCorei5Type9; // 0x0609 - } - if (AppleMajorType == AppleProcessorMajorI7) { - // Kaby has 0x9 stepping, and Coffee use 0xA / 0xB stepping. - if (Stepping == 9) { - // FIXME: used by Apple, but not sure what to use... - // 0x0709 is used on MBP151 (i7-8850H), - // 0x0705 is not confirmed, just an ideal one comparing to 0x0605 (AppleProcessorTypeCorei5Type5) - // using 0x0705 for now - return AppleProcessorTypeCorei7Type5; // 0x0705 - } - // MM81 (i7-8700B) - return AppleProcessorTypeCorei7Type9; // 0x0709 - } - if (AppleMajorType == AppleProcessorMajorI9) { - // FIXME: find a dump from MBP151 with i9-8950HK, - // for now using an ideal value (0x1009), comparing to 0x0709 (used on MBP151, i7-8850H and MM81, i7-8700B) - return AppleProcessorTypeCorei9Type9; // 0x1009 - } - if (AppleMajorType == AppleProcessorMajorI3) { - // FIXME: find a dump from MM71 with i3... - // for now using an idea value (0x0905) - return AppleProcessorTypeCorei3Type5; // 0x0905 - } - if (AppleMajorType == AppleProcessorMajorXeonNehalem) { // see TODO below - // for Kaby Lake/Coffee Lake E3 (there's no E5/E7 on either), not used by Apple - // NOTE: Xeon E3 is not used by Apple at all and should be somehow treated as i7, - // but here we'd like to show Xeon in "About This Mac". - // TODO: CPU major type check for KBL/CFL based Xeon E3 - return AppleProcessorTypeXeon; // 0x0501 - } - // here stands for Pentium and Celeron (KBL/CFL), not used by Apple at all. - // putting 0x0905 (i3) as lowest. - return AppleProcessorTypeCorei3Type5; // 0x0905 - - default: - // NOTE: by default it is really unknown, but we fallback - return AppleProcessorTypeCorei5Type5; // 0x0605 - } -} - -UINT32 -OcCpuModelToAppleFamily ( - IN CPUID_VERSION_INFO_EAX VersionEax - ) -{ - UINT8 Model; - - if (VersionEax.Bits.FamilyId != 6) { - return CPUFAMILY_UNKNOWN; - } - - // - // This MUST be 1 to 1 with Apple XNU kernel implemenation. - // - - Model = (UINT8) VersionEax.Bits.Model | (UINT8) (VersionEax.Bits.ExtendedModelId << 4U); - - switch (Model) { - case CPU_MODEL_PENRYN: - return CPUFAMILY_INTEL_PENRYN; - case CPU_MODEL_NEHALEM: - case CPU_MODEL_FIELDS: - case CPU_MODEL_DALES: - case CPU_MODEL_NEHALEM_EX: - return CPUFAMILY_INTEL_NEHALEM; - case CPU_MODEL_DALES_32NM: - case CPU_MODEL_WESTMERE: - case CPU_MODEL_WESTMERE_EX: - return CPUFAMILY_INTEL_WESTMERE; - case CPU_MODEL_SANDYBRIDGE: - case CPU_MODEL_JAKETOWN: - return CPUFAMILY_INTEL_SANDYBRIDGE; - case CPU_MODEL_IVYBRIDGE: - case CPU_MODEL_IVYBRIDGE_EP: - return CPUFAMILY_INTEL_IVYBRIDGE; - case CPU_MODEL_HASWELL: - case CPU_MODEL_HASWELL_EP: - case CPU_MODEL_HASWELL_ULT: - case CPU_MODEL_CRYSTALWELL: - return CPUFAMILY_INTEL_HASWELL; - case CPU_MODEL_BROADWELL: - case CPU_MODEL_BROADWELL_EP: - case CPU_MODEL_BRYSTALWELL: - return CPUFAMILY_INTEL_BROADWELL; - case CPU_MODEL_SKYLAKE: - case CPU_MODEL_SKYLAKE_DT: - case CPU_MODEL_SKYLAKE_W: - return CPUFAMILY_INTEL_SKYLAKE; - case CPU_MODEL_KABYLAKE: - case CPU_MODEL_KABYLAKE_DT: - return CPUFAMILY_INTEL_KABYLAKE; - default: - return CPUFAMILY_UNKNOWN; - } -} diff --git a/Library/OcCpuLib/FrequencyDetect.c b/Library/OcCpuLib/FrequencyDetect.c deleted file mode 100644 index c7627700f..000000000 --- a/Library/OcCpuLib/FrequencyDetect.c +++ /dev/null @@ -1,546 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcCpuInternals.h" - -UINTN -InternalGetPmTimerAddr ( - OUT CONST CHAR8 **Type OPTIONAL - ) -{ - UINTN TimerAddr; - UINT32 CpuVendor; - - TimerAddr = 0; - - if (Type != NULL) { - *Type = "Failure"; - } - - // - // Intel timer support. - // Here we obtain the address of 24-bit or 32-bit PM1_TMR. - // TODO: I believe that there is little reason to enforce our timer lib to calculate - // CPU frequency through ACPI PM timer on modern Intel CPUs. Starting from Skylake - // we have crystal clock, which allows us to get quite reliable values. Perhaps - // this code should be put to OcCpuLib, and the best available source is to be used. - // - if (PciRead16 (PCI_ICH_LPC_ADDRESS (0)) == V_ICH_PCI_VENDOR_ID) { - // - // On legacy platforms PM1_TMR can be found in ACPI I/O space. - // 1. For platforms prior to Intel Skylake (Sunrisepoint PCH) iTCO watchdog - // resources reside in LPC device (D31:F0). - // 2. For platforms from Intel Skylake till Intel Kaby Lake inclusive they reside in - // PMC controller (D31:F2). - // Checking whether ACPI I/O space is enabled is done via ACPI_CNTL register bit 0. - // - // On modern platforms, starting from Intel Coffee Lake, the space is roughly the same, - // but it is referred to as PMC I/O space, and the addressing is done through BAR2. - // In addition to that on B360 and friends PMC controller may be just missing. - // - if ((PciRead8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNTL)) & B_ICH_LPC_ACPI_CNTL_ACPI_EN) != 0) { - TimerAddr = (PciRead16 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_BASE)) & B_ICH_LPC_ACPI_BASE_BAR) + R_ACPI_PM1_TMR; - if (Type != NULL) { - *Type = "LPC"; - } - } else if (PciRead16 (PCI_ICH_PMC_ADDRESS (0)) == V_ICH_PCI_VENDOR_ID) { - if ((PciRead8 (PCI_ICH_PMC_ADDRESS (R_ICH_PMC_ACPI_CNTL)) & B_ICH_PMC_ACPI_CNTL_ACPI_EN) != 0) { - TimerAddr = (PciRead16 (PCI_ICH_PMC_ADDRESS (R_ICH_PMC_ACPI_BASE)) & B_ICH_PMC_ACPI_BASE_BAR) + R_ACPI_PM1_TMR; - if (Type != NULL) { - *Type = "PMC ACPI"; - } - } else if ((PciRead16 (PCI_ICH_PMC_ADDRESS (R_ICH_PMC_BAR2_BASE)) & B_ICH_PMC_BAR2_BASE_BAR_EN) != 0) { - TimerAddr = (PciRead16 (PCI_ICH_PMC_ADDRESS (R_ICH_PMC_BAR2_BASE)) & B_ICH_PMC_BAR2_BASE_BAR) + R_ACPI_PM1_TMR; - if (Type != NULL) { - *Type = "PMC BAR2"; - } - } else if (Type != NULL) { - *Type = "Invalid INTEL PMC"; - } - } else if (Type != NULL) { - // - // This is currently the case for Z390 and B360 boards. - // - *Type = "Unknown INTEL"; - } - } - - // - // AMD timer support. - // - if (TimerAddr == 0) { - // - // In an ideal world I believe we should detect AMD SMBus controller... - // - CpuVendor = 0; - AsmCpuid (CPUID_SIGNATURE, NULL, &CpuVendor, NULL, NULL); - - if (CpuVendor == CPUID_VENDOR_AMD) { - TimerAddr = MmioRead32 ( - R_AMD_ACPI_MMIO_BASE + R_AMD_ACPI_MMIO_PMIO_BASE + R_AMD_ACPI_PM_TMR_BLOCK - ); - if (Type != NULL) { - *Type = "AMD"; - } - } - } - - return TimerAddr; -} - -UINT64 -InternalCalculateTSCFromPMTimer ( - IN BOOLEAN Recalculate - ) -{ - // - // Cache the result to speed up multiple calls. For example, we might need - // this frequency on module entry to initialise a TimerLib instance, and at - // a later point in time to gather CPU information. - // - STATIC UINT64 TSCFrequency = 0; - - UINTN TimerAddr; - UINTN VariableSize; - UINT64 Tsc0; - UINT64 Tsc1; - UINT32 AcpiTick0; - UINT32 AcpiTick1; - UINT32 AcpiTicksDelta; - UINT32 AcpiTicksTarget; - UINT32 TimerResolution; - EFI_TPL PrevTpl; - EFI_STATUS Status; - - // - // Do not use ACPI PM timer in ring 3 (e.g. emulator). - // - if ((AsmReadCs () & 3U) == 3) { - return EFI_UNSUPPORTED; - } - - // - // Decide whether we need to store the frequency. - // - if (TSCFrequency == 0) { - VariableSize = sizeof (TSCFrequency); - Status = gRT->GetVariable ( - OC_ACPI_CPU_FREQUENCY_VARIABLE_NAME, - &gOcVendorVariableGuid, - NULL, - &VariableSize, - &TSCFrequency - ); - } else { - Status = EFI_ALREADY_STARTED; - } - - if (Recalculate) { - TSCFrequency = 0; - } - - if (TSCFrequency == 0) { - TimerAddr = InternalGetPmTimerAddr (NULL); - TimerResolution = 10; - - if (TimerAddr != 0) { - // - // Check that timer is advancing (it does not on some virtual machines). - // - AcpiTick0 = IoRead32 (TimerAddr); - gBS->Stall (500); - AcpiTick1 = IoRead32 (TimerAddr); - - if (AcpiTick0 != AcpiTick1) { - // - // ACPI PM timers are usually of 24-bit length, but there are some less common cases of 32-bit length also. - // When the maximal number is reached, it overflows. - // The code below can handle overflow with AcpiTicksTarget of up to 24-bit size, - // on both available sizes of ACPI PM Timers (24-bit and 32-bit). - // - // 357954 clocks of ACPI timer (100ms) - // - AcpiTicksTarget = V_ACPI_TMR_FREQUENCY / TimerResolution; - - // - // Disable all events to ensure that nobody interrupts us. - // - PrevTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - AcpiTick0 = IoRead32 (TimerAddr); - Tsc0 = AsmReadTsc (); - - do { - CpuPause (); - - // - // Check how many AcpiTicks have passed since we started. - // - AcpiTick1 = IoRead32 (TimerAddr); - - if (AcpiTick0 <= AcpiTick1) { - // - // No overflow. - // - AcpiTicksDelta = AcpiTick1 - AcpiTick0; - } else if (AcpiTick0 - AcpiTick1 <= 0x00FFFFFF) { - // - // Overflow, 24-bit timer. - // - AcpiTicksDelta = 0x00FFFFFF - AcpiTick0 + AcpiTick1; - } else { - // - // Overflow, 32-bit timer. - // - AcpiTicksDelta = MAX_UINT32 - AcpiTick0 + AcpiTick1; - } - - // - // Keep checking AcpiTicks until target is reached. - // - } while (AcpiTicksDelta < AcpiTicksTarget); - - Tsc1 = AsmReadTsc (); - - // - // On some systems we may end up waiting for notably longer than 100ms, - // despite disabling all events. Divide by actual time passed as suggested - // by asava's Clover patch r2668. - // - TSCFrequency = DivU64x32 ( - MultU64x32 (Tsc1 - Tsc0, V_ACPI_TMR_FREQUENCY), AcpiTicksDelta - ); - - // - // Restore to normal TPL. - // - gBS->RestoreTPL (PrevTpl); - } - } - - DEBUG ((DEBUG_VERBOSE, "TscFrequency %lld\n", TSCFrequency)); - - // - // Set the variable if not present and valid. - // - if (TSCFrequency != 0 && Status == EFI_NOT_FOUND) { - gRT->SetVariable ( - OC_ACPI_CPU_FREQUENCY_VARIABLE_NAME, - &gOcVendorVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (TSCFrequency), - &TSCFrequency - ); - } - } - - return TSCFrequency; -} - -UINT64 -InternalCalculateARTFrequencyIntel ( - OUT UINT64 *CPUFrequency, - OUT UINT64 *TscAdjustPtr OPTIONAL, - IN BOOLEAN Recalculate - ) -{ - // - // Cache the result to speed up multiple calls. For example, we might need - // this frequency on module entry to initialise a TimerLib instance, and at - // a later point in time to gather CPU information. - // - STATIC UINT64 ARTFrequency = 0; - STATIC UINT64 CPUFrequencyFromART = 0; - - UINT32 MaxId; - UINT32 CpuVendor; - - UINT32 CpuidDenominatorEax; - UINT32 CpuidNumeratorEbx; - UINT32 CpuidARTFrequencyEcx; - CPUID_PROCESSOR_FREQUENCY_EAX CpuidFrequencyEax; - UINT64 TscAdjust; - UINT64 CPUFrequencyFromTSC; - CPUID_VERSION_INFO_EAX CpuidVerEax; - UINT8 Model; - - if (Recalculate) { - ARTFrequency = 0; - CPUFrequencyFromART = 0; - } - - if (ARTFrequency == 0) { - // - // Get vendor CPUID 0x00000000 - // - AsmCpuid (CPUID_SIGNATURE, &MaxId, &CpuVendor, NULL, NULL); - // - // Determine our core crystal clock frequency - // - if (CpuVendor == CPUID_VENDOR_INTEL && MaxId >= CPUID_TIME_STAMP_COUNTER) { - TscAdjust = AsmReadMsr64 (MSR_IA32_TSC_ADJUST); - DEBUG ((DEBUG_INFO, "OCCPU: TSC Adjust %Lu\n", TscAdjust)); - - if (TscAdjustPtr != NULL) { - *TscAdjustPtr = TscAdjust; - } - - AsmCpuid ( - CPUID_TIME_STAMP_COUNTER, - &CpuidDenominatorEax, - &CpuidNumeratorEbx, - &CpuidARTFrequencyEcx, - NULL - ); - if (CpuidARTFrequencyEcx > 0) { - ARTFrequency = CpuidARTFrequencyEcx; - DEBUG ((DEBUG_INFO, "OCCPU: Queried Core Crystal Clock Frequency %11LuHz\n", ARTFrequency)); - } else { - AsmCpuid (CPUID_VERSION_INFO, &CpuidVerEax.Uint32, NULL, NULL, NULL); - Model = (UINT8) CpuidVerEax.Bits.Model | (UINT8) (CpuidVerEax.Bits.ExtendedModelId << 4U); - // - // Fall back to identifying ART frequency based on known models - // - switch (Model) { - case CPU_MODEL_SKYLAKE: - case CPU_MODEL_SKYLAKE_DT: - case CPU_MODEL_KABYLAKE: - case CPU_MODEL_KABYLAKE_DT: - ARTFrequency = CLIENT_ART_CLOCK_SOURCE; // 24 Mhz - break; - case CPU_MODEL_DENVERTON: - ARTFrequency = SERVER_ART_CLOCK_SOURCE; // 25 Mhz - break; - case CPU_MODEL_GOLDMONT: - ARTFrequency = ATOM_ART_CLOCK_SOURCE; // 19.2 Mhz - break; - } - if (ARTFrequency > 0) { - DEBUG ((DEBUG_INFO, "OCCPU: Known Model Core Crystal Clock Frequency %11LuHz\n", ARTFrequency)); - } - } - - if (CpuidDenominatorEax > 0 && CpuidNumeratorEbx > 0) { - // - // Some Intel chips don't report their core crystal clock frequency. - // Calculate it by dividing the TSC frequency by the TSC ratio. - // - if (ARTFrequency == 0 && MaxId >= CPUID_PROCESSOR_FREQUENCY) { - CPUFrequencyFromTSC = InternalCalculateTSCFromPMTimer (Recalculate); - ARTFrequency = MultThenDivU64x64x32( - CPUFrequencyFromTSC, - CpuidDenominatorEax, - CpuidNumeratorEbx, - NULL - ); - if (ARTFrequency > 0ULL) { - DEBUG (( - DEBUG_INFO, - "OCCPU: Core Crystal Clock Frequency from TSC %11LuHz = %11LuHz * %u / %u\n", - ARTFrequency, - CPUFrequencyFromTSC, - CpuidDenominatorEax, - CpuidNumeratorEbx - )); - // - // Use the reported CPU frequency rather than deriving it from ARTFrequency - // - AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &CpuidFrequencyEax.Uint32, NULL, NULL, NULL); - CPUFrequencyFromART = MultU64x32 (CpuidFrequencyEax.Bits.ProcessorBaseFrequency, 1000000); - } - } - - // - // If we still can't determine the core crystal clock frequency, assume - // it's 24 Mhz like most Intel chips to date. - // - if (ARTFrequency == 0ULL) { - ARTFrequency = DEFAULT_ART_CLOCK_SOURCE; - DEBUG ((DEBUG_INFO, "OCCPU: Fallback Core Crystal Clock Frequency %11LuHz\n", ARTFrequency)); - } - - ASSERT (ARTFrequency > 0ULL); - if (CPUFrequencyFromART == 0ULL) { - CPUFrequencyFromART = MultThenDivU64x64x32 ( - ARTFrequency, - CpuidNumeratorEbx, - CpuidDenominatorEax, - NULL - ); - } - ASSERT (CPUFrequencyFromART > 0ULL); - DEBUG (( - DEBUG_INFO, - "OCCPU: CPUFrequencyFromART %11LuHz %5LuMHz = %Lu * %u / %u\n", - CPUFrequencyFromART, - DivU64x32 (CPUFrequencyFromART, 1000000), - ARTFrequency, - CpuidNumeratorEbx, - CpuidDenominatorEax - )); - } - } - } - - *CPUFrequency = CPUFrequencyFromART; - return ARTFrequency; -} - -UINT64 -InternalCalculateVMTFrequency ( - OUT UINT64 *FSBFrequency OPTIONAL, - OUT BOOLEAN *UnderHypervisor OPTIONAL - ) -{ - UINT32 CpuidEax; - UINT32 CpuidEbx; - UINT32 CpuidEcx; - UINT32 CpuidEdx; - CPUID_VERSION_INFO_ECX CpuidVerEcx; - - CHAR8 HvVendor[13]; - UINT64 Msr; - - AsmCpuid ( - CPUID_VERSION_INFO, - NULL, - NULL, - &CpuidVerEcx.Uint32, - NULL - ); - - if (FSBFrequency != NULL) { - *FSBFrequency = 0; - } - - if (UnderHypervisor != NULL) { - *UnderHypervisor = CpuidVerEcx.Bits.NotUsed != 0; - } - - // - // TODO: We do not have Hypervisor support in EDK II CPUID structure yet. - // See https://github.com/acidanthera/audk/pull/2. - // Get Hypervisor/Virtualization information. - // - if (CpuidVerEcx.Bits.NotUsed == 0) { - return 0; - } - - // - // If we are under virtualization and cpuid invtsc is enabled, we can just read - // TSCFrequency and FSBFrequency from VMWare Timing node instead of reading MSR - // (which hypervisors may not implemented yet), at least in QEMU/VMWare it works. - // Source: - // 1. CPUID usage for interaction between Hypervisors and Linux.: - // https://lwn.net/Articles/301888/ - // 2. [Qemu-devel] [PATCH v2 0/3] x86-kvm: Fix Mac guest timekeeping by exposi: - // https://lists.gnu.org/archive/html/qemu-devel/2017-01/msg04344.html - // - // Hyper-V only implements MSRs for TSC and FSB frequencies in Hz. - // See https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs - // - AsmCpuid (0x40000000, &CpuidEax, &CpuidEbx, &CpuidEcx, &CpuidEdx); - - CopyMem (&HvVendor[0], &CpuidEbx, sizeof (UINT32)); - CopyMem (&HvVendor[4], &CpuidEcx, sizeof (UINT32)); - CopyMem (&HvVendor[8], &CpuidEdx, sizeof (UINT32)); - HvVendor[12] = '\0'; - - if (AsciiStrCmp (HvVendor, "Microsoft Hv") == 0) { - // - // HV_X64_MSR_APIC_FREQUENCY - // - Msr = AsmReadMsr64 (0x40000023); - if (FSBFrequency != NULL) { - *FSBFrequency = Msr; - } - - // - // HV_X64_MSR_TSC_FREQUENCY - // - Msr = AsmReadMsr64 (0x40000022); - return Msr; - } - - // - // Other hypervisors implement TSC/FSB frequency as an additional CPUID leaf. - // - if (CpuidEax < 0x40000010) { - return 0; - } - - AsmCpuid (0x40000010, &CpuidEax, &CpuidEbx, NULL, NULL); - if (CpuidEax == 0 || CpuidEbx == 0) { - return 0; - } - - // - // We get kHZ from node and we should translate it first. - // - if (FSBFrequency != NULL) { - *FSBFrequency = CpuidEbx * 1000ULL; - } - - return CpuidEax * 1000ULL; -} - -UINT64 -OcGetTSCFrequency ( - VOID - ) -{ - UINT64 CPUFrequency; - // - // For Intel platforms (the vendor check is covered by the callee), prefer - // the CPU Frequency derieved from the ART, as the PM timer might not be - // available (e.g. 300 series chipsets). - // TODO: For AMD, the base clock can be determined from P-registers. - // - InternalCalculateARTFrequencyIntel (&CPUFrequency, NULL, FALSE); - if (CPUFrequency == 0) { - CPUFrequency = InternalCalculateVMTFrequency (NULL, NULL); - if (CPUFrequency == 0) { - CPUFrequency = InternalCalculateTSCFromPMTimer (FALSE); - if (CPUFrequency == 0) { - // - // Assume at least some frequency, so that we always work. - // - CPUFrequency = OC_FALLBACK_CPU_FREQUENCY; - } - } - } - // - // For all known models with an invariant TSC, its frequency is equal to the - // CPU's specified base clock. - // - return CPUFrequency; -} diff --git a/Library/OcCpuLib/Ia32/Atomic.nasm b/Library/OcCpuLib/Ia32/Atomic.nasm deleted file mode 100644 index 711a63716..000000000 --- a/Library/OcCpuLib/Ia32/Atomic.nasm +++ /dev/null @@ -1,34 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 32 -DEFAULT REL - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT32 -; EFIAPI -; AsmIncrementUint32 ( -; IN volatile UINT32 *Value -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(AsmIncrementUint32) -ASM_PFX(AsmIncrementUint32): - mov ecx, [esp + 4] - mov eax, 1 - lock xadd dword [ecx], eax - inc eax - ret diff --git a/Library/OcCpuLib/Ia32/Microcode.nasm b/Library/OcCpuLib/Ia32/Microcode.nasm deleted file mode 100644 index 634f95ef6..000000000 --- a/Library/OcCpuLib/Ia32/Microcode.nasm +++ /dev/null @@ -1,48 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 32 -DEFAULT REL - -MSR_IA32_BIOS_SIGN_ID equ 00000008Bh -CPUID_VERSION_INFO equ 1 - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT32 -; EFIAPI -; AsmReadIntelMicrocodeRevision ( -; VOID -; ); -;------------------------------------------------------------------------------ -align 8 -global ASM_PFX(AsmReadIntelMicrocodeRevision) -ASM_PFX(AsmReadIntelMicrocodeRevision): - ; Several Intel CPUs, notably Westmere, require a certain assembly - ; sequence to retrieve microcode revision. - ; Reference: https://github.com/acidanthera/bugtracker/issues/621. - push ebx - mov ecx, MSR_IA32_BIOS_SIGN_ID - xor eax, eax - xor edx, edx - wrmsr - mov eax, CPUID_VERSION_INFO - cpuid - mov ecx, MSR_IA32_BIOS_SIGN_ID - rdmsr - mov eax, edx - pop ebx - ret diff --git a/Library/OcCpuLib/OcCpuInternals.h b/Library/OcCpuLib/OcCpuInternals.h deleted file mode 100755 index 102cc8e81..000000000 --- a/Library/OcCpuLib/OcCpuInternals.h +++ /dev/null @@ -1,141 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_CPU_INTERNALS_H -#define OC_CPU_INTERNALS_H - -// -// Tolerance within which we consider two frequency values to be roughly -// equivalent. -// -#define OC_CPU_FREQUENCY_TOLERANCE 50000000LL // 50 Mhz - -/** - Internal CPU synchronisation structure. -**/ -typedef struct { - UINT64 Tsc; - volatile UINT32 CurrentCount; - UINT32 APThreadCount; -} OC_CPU_TSC_SYNC; - -/** - Returns microcode revision for Intel CPUs. - - @retval microcode revision. -**/ -UINT32 -EFIAPI -AsmReadIntelMicrocodeRevision ( - VOID - ); - -/** - Detect Apple CPU major type. - - @param[in] BrandString CPU Brand String from CPUID. - - @retval Apple CPU major type. -**/ -UINT8 -InternalDetectAppleMajorType ( - IN CONST CHAR8 *BrandString - ); - -/** - Detect Apple CPU type. - - @param[in] Model CPU model from CPUID. - @param[in] Stepping CPU stepping from CPUID. - @param[in] AppleMajorType Apple CPU major type. - - @retval Apple CPU type. -**/ -UINT16 -InternalDetectAppleProcessorType ( - IN UINT8 Model, - IN UINT8 Stepping, - IN UINT8 AppleMajorType - ); - -/** - Obtain ACPI PM timer address for this BSP. - - @param[out] Type Address source type, optional. - - @retval ACPI PM timer address or 0. -**/ -UINTN -InternalGetPmTimerAddr ( - OUT CONST CHAR8 **Type OPTIONAL - ); - -/** - Calculate the TSC frequency via PM timer - - @param[in] Recalculate Do not re-use previously cached information. - - @retval The calculated TSC frequency. -**/ -UINT64 -InternalCalculateTSCFromPMTimer ( - IN BOOLEAN Recalculate - ); - -/** - Calculate the ART frequency and derieve the CPU frequency for Intel CPUs - - @param[out] CPUFrequency The derieved CPU frequency. - @param[out] TscAdjustPtr Adjustment value for TSC, optional. - @param[in] Recalculate Do not re-use previously cached information. - - @retval The calculated ART frequency. -**/ -UINT64 -InternalCalculateARTFrequencyIntel ( - OUT UINT64 *CPUFrequency, - OUT UINT64 *TscAdjustPtr OPTIONAL, - IN BOOLEAN Recalculate - ); - -/** - Calculate the CPU frequency via VMT for hypervisors - - @param[out] FSBFrequency FSB frequency, optional. - @param[out] UnderHypervisor Hypervisor status, optional. - - @retval CPU frequency or 0. -**/ -UINT64 -InternalCalculateVMTFrequency ( - OUT UINT64 *FSBFrequency OPTIONAL, - OUT BOOLEAN *UnderHypervisor OPTIONAL - ); - -/** - Atomically increment 32-bit integer. - This is required to be locally implemented as we cannot use SynchronizationLib, - which depends on TimerLib, and our TimerLib depends on this library. - - @param[in] Value Pointer to 32-bit integer to increment. - - @retval value after incrementing. -**/ -UINT32 -EFIAPI -AsmIncrementUint32 ( - IN volatile UINT32 *Value - ); - -#endif // OC_CPU_INTERNALS_H diff --git a/Library/OcCpuLib/OcCpuLib.c b/Library/OcCpuLib/OcCpuLib.c deleted file mode 100755 index 5ba33fcc5..000000000 --- a/Library/OcCpuLib/OcCpuLib.c +++ /dev/null @@ -1,1052 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcCpuInternals.h" - -STATIC -EFI_STATUS -ScanMpServices ( - IN EFI_MP_SERVICES_PROTOCOL *MpServices, - OUT OC_CPU_INFO *Cpu, - OUT UINTN *NumberOfProcessors, - OUT UINTN *NumberOfEnabledProcessors - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_PROCESSOR_INFORMATION Info; - - ASSERT (MpServices != NULL); - ASSERT (Cpu != NULL); - ASSERT (NumberOfProcessors != NULL); - ASSERT (NumberOfEnabledProcessors != NULL); - - Status = MpServices->GetNumberOfProcessors ( - MpServices, - NumberOfProcessors, - NumberOfEnabledProcessors - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - if (*NumberOfProcessors == 0) { - return EFI_NOT_FOUND; - } - - // - // This code assumes that all CPUs have same amount of cores and threads. - // - for (Index = 0; Index < *NumberOfProcessors; ++Index) { - Status = MpServices->GetProcessorInfo (MpServices, Index, &Info); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCCPU: Failed to get info for processor %Lu - %r\n", - (UINT64) Index, - Status - )); - - continue; - } - - if (Info.Location.Package + 1 >= Cpu->PackageCount) { - Cpu->PackageCount = (UINT16) (Info.Location.Package + 1); - } - - if (Info.Location.Core + 1 >= Cpu->CoreCount) { - Cpu->CoreCount = (UINT16) (Info.Location.Core + 1); - } - - if (Info.Location.Thread + 1 >= Cpu->ThreadCount) { - Cpu->ThreadCount = (UINT16) (Info.Location.Thread + 1); - } - } - - return Status; -} - -STATIC -EFI_STATUS -ScanFrameworkMpServices ( - IN FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpServices, - OUT OC_CPU_INFO *Cpu, - OUT UINTN *NumberOfProcessors, - OUT UINTN *NumberOfEnabledProcessors - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_MP_PROC_CONTEXT Context; - UINTN ContextSize; - - ASSERT (FrameworkMpServices != NULL); - ASSERT (Cpu != NULL); - ASSERT (NumberOfProcessors != NULL); - ASSERT (NumberOfEnabledProcessors != NULL); - - Status = FrameworkMpServices->GetGeneralMPInfo ( - FrameworkMpServices, - NumberOfProcessors, - NULL, - NumberOfEnabledProcessors, - NULL, - NULL - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - if (*NumberOfProcessors == 0) { - return EFI_NOT_FOUND; - } - - // - // This code assumes that all CPUs have same amount of cores and threads. - // - for (Index = 0; Index < *NumberOfProcessors; ++Index) { - ContextSize = sizeof (Context); - - Status = FrameworkMpServices->GetProcessorContext ( - FrameworkMpServices, - Index, - &ContextSize, - &Context - ); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCCPU: Failed to get context for processor %Lu - %r\n", - (UINT64) Index, - Status - )); - - continue; - } - - if (Context.PackageNumber + 1 >= Cpu->PackageCount) { - Cpu->PackageCount = (UINT16) (Context.PackageNumber + 1); - } - - // - // According to the FrameworkMpServices header, EFI_MP_PROC_CONTEXT.NumberOfCores is the - // zero-indexed physical core number for the current processor. However, Apple appears to - // set this to the total number of physical cores (observed on Xserve3,1 with 2x Xeon X5550). - // - // This number may not be accurate; on MacPro5,1 with 2x Xeon X5690, NumberOfCores is 16 when - // it should be 12 (even though NumberOfProcessors is correct). Regardless, CoreCount and - // ThreadCount will be corrected in ScanIntelProcessor. - // - // We will follow Apple's implementation, as the FrameworkMpServices fallback was added for - // legacy Macs. - // - if (Context.NumberOfCores >= Cpu->CoreCount) { - Cpu->CoreCount = (UINT16) (Context.NumberOfCores); - } - - // - // Similarly, EFI_MP_PROC_CONTEXT.NumberOfThreads is supposed to be the zero-indexed logical - // thread number for the current processor. On Xserve3,1 and MacPro5,1 this was set to 2 - // (presumably to indicate that there are 2 threads per physical core). - // - if (Context.NumberOfCores * Context.NumberOfThreads >= Cpu->ThreadCount) { - Cpu->ThreadCount = (UINT16) (Context.NumberOfCores * Context.NumberOfThreads); - } - } - - return Status; -} - -STATIC -EFI_STATUS -ScanThreadCount ( - OUT OC_CPU_INFO *Cpu - ) -{ - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpServices; - FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpServices; - UINTN NumberOfProcessors; - UINTN NumberOfEnabledProcessors; - - Cpu->PackageCount = 1; - Cpu->CoreCount = 1; - Cpu->ThreadCount = 1; - NumberOfProcessors = 0; - NumberOfEnabledProcessors = 0; - - Status = gBS->LocateProtocol ( - &gEfiMpServiceProtocolGuid, - NULL, - (VOID **) &MpServices - ); - - if (EFI_ERROR(Status)) { - Status = gBS->LocateProtocol ( - &gFrameworkEfiMpServiceProtocolGuid, - NULL, - (VOID **) &FrameworkMpServices - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCCPU: No MP services - %r\n", Status)); - return Status; - } - - Status = ScanFrameworkMpServices ( - FrameworkMpServices, - Cpu, - &NumberOfProcessors, - &NumberOfEnabledProcessors - ); - } else { - Status = ScanMpServices ( - MpServices, - Cpu, - &NumberOfProcessors, - &NumberOfEnabledProcessors - ); - } - - DEBUG (( - DEBUG_INFO, - "OCCPU: MP services threads %Lu (enabled %Lu) - %r\n", - (UINT64) NumberOfProcessors, - (UINT64) NumberOfEnabledProcessors, - Status - )); - - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG (( - DEBUG_INFO, - "OCCPU: MP services Pkg %u Cores %u Threads %u - %r\n", - Cpu->PackageCount, - Cpu->CoreCount, - Cpu->ThreadCount, - Status - )); - - // - // Several implementations may not report virtual threads. - // - if (Cpu->ThreadCount < Cpu->CoreCount) { - Cpu->ThreadCount = Cpu->CoreCount; - } - - return Status; -} - -STATIC -VOID -ScanIntelProcessor ( - IN OUT OC_CPU_INFO *Cpu - ) -{ - UINT64 Msr; - CPUID_CACHE_PARAMS_EAX CpuidCacheEax; - CPUID_CACHE_PARAMS_EBX CpuidCacheEbx; - UINT8 AppleMajorType; - MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER PkgCstConfigControl; - MSR_IA32_PERF_STATUS_REGISTER PerfStatus; - MSR_NEHALEM_PLATFORM_INFO_REGISTER PlatformInfo; - OC_CPU_GENERATION CpuGeneration; - MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER TurboLimit; - UINT16 CoreCount; - CONST CHAR8 *TimerSourceType; - UINTN TimerAddr; - BOOLEAN Recalculate; - - AppleMajorType = InternalDetectAppleMajorType (Cpu->BrandString); - Cpu->AppleProcessorType = InternalDetectAppleProcessorType (Cpu->Model, Cpu->Stepping, AppleMajorType); - - DEBUG ((DEBUG_INFO, "OCCPU: Detected Apple Processor Type: %02X -> %04X\n", AppleMajorType, Cpu->AppleProcessorType)); - - if ((Cpu->Family != 0x06 || Cpu->Model < 0x0c) - && (Cpu->Family != 0x0f || Cpu->Model < 0x03)) { - return; - } - - // - // Some virtual machines like QEMU 5.0 with KVM will fail to read this value. - // REF: https://github.com/acidanthera/bugtracker/issues/914 - // - if (Cpu->Model >= CPU_MODEL_SANDYBRIDGE && !Cpu->Hypervisor) { - PkgCstConfigControl.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL); - Cpu->CstConfigLock = PkgCstConfigControl.Bits.CFGLock == 1; - } else { - Cpu->CstConfigLock = FALSE; - } - - DEBUG ((DEBUG_INFO, "OCCPU: EIST CFG Lock %d\n", Cpu->CstConfigLock)); - - // - // When the CPU is virtualized and cpuid invtsc is enabled, then we already get - // the information we want outside the function, skip anyway. - // Things may be different in other hypervisors, but should work with QEMU/VMWare for now. - // - if (Cpu->CPUFrequencyFromVMT == 0) { - // - // TODO: this may not be accurate on some older processors. - // - if (Cpu->Model >= CPU_MODEL_NEHALEM) { - PerfStatus.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS); - PlatformInfo.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_INFO); - Cpu->MinBusRatio = (UINT8) PlatformInfo.Bits.MaximumEfficiencyRatio; - Cpu->MaxBusRatio = (UINT8) PlatformInfo.Bits.MaximumNonTurboRatio; - CpuGeneration = OcCpuGetGeneration (); - - if (CpuGeneration == OcCpuGenerationNehalem - || CpuGeneration == OcCpuGenerationWestmere) { - Cpu->CurBusRatio = (UINT8) PerfStatus.Bits.State; - } else { - Cpu->CurBusRatio = (UINT8) (PerfStatus.Bits.State >> 8U); - } - } else { - PerfStatus.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS); - Cpu->MaxBusRatio = (UINT8) (RShiftU64 (PerfStatus.Uint64, 8) & 0x1FU); - // - // Undocumented values: - // Non-integer bus ratio for the max-multi. - // Non-integer bus ratio for the current-multi. - // - // MaxBusRatioDiv = (UINT8) (RShiftU64 (PerfStatus.Uint64, 46) & 0x01U); - // CurrDiv = (UINT8) (RShiftU64 (PerfStatus.Uint64, 14) & 0x01U); - // - } - - if (Cpu->Model >= CPU_MODEL_NEHALEM - && Cpu->Model != CPU_MODEL_NEHALEM_EX - && Cpu->Model != CPU_MODEL_WESTMERE_EX) { - TurboLimit.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TURBO_RATIO_LIMIT); - Cpu->TurboBusRatio1 = (UINT8) TurboLimit.Bits.Maximum1C; - Cpu->TurboBusRatio2 = (UINT8) TurboLimit.Bits.Maximum2C; - Cpu->TurboBusRatio3 = (UINT8) TurboLimit.Bits.Maximum3C; - Cpu->TurboBusRatio4 = (UINT8) TurboLimit.Bits.Maximum4C; - } - - DEBUG (( - DEBUG_INFO, - "OCCPU: Ratio Min %d Max %d Current %d Turbo %d %d %d %d\n", - Cpu->MinBusRatio, - Cpu->MaxBusRatio, - Cpu->CurBusRatio, - Cpu->TurboBusRatio1, - Cpu->TurboBusRatio2, - Cpu->TurboBusRatio3, - Cpu->TurboBusRatio4 - )); - - // - // For logging purposes (the first call to these functions might happen - // before logging is fully initialised), do not use the cached results in - // DEBUG builds. - // - Recalculate = FALSE; - - DEBUG_CODE_BEGIN (); - Recalculate = TRUE; - DEBUG_CODE_END (); - - // - // Determine our core crystal clock frequency - // - Cpu->ARTFrequency = InternalCalculateARTFrequencyIntel ( - &Cpu->CPUFrequencyFromART, - &Cpu->TscAdjust, - Recalculate - ); - - // - // Calculate the TSC frequency only if ART frequency is not available or we are in debug builds. - // - if (Cpu->CPUFrequencyFromART == 0 || Recalculate) { - DEBUG_CODE_BEGIN (); - TimerAddr = InternalGetPmTimerAddr (&TimerSourceType); - DEBUG ((DEBUG_INFO, "OCCPU: Timer address is %Lx from %a\n", (UINT64) TimerAddr, TimerSourceType)); - DEBUG_CODE_END (); - Cpu->CPUFrequencyFromTSC = InternalCalculateTSCFromPMTimer (Recalculate); - } - - // - // Calculate CPU frequency based on ART if present, otherwise TSC - // - Cpu->CPUFrequency = Cpu->CPUFrequencyFromART != 0 ? Cpu->CPUFrequencyFromART : Cpu->CPUFrequencyFromTSC; - - // - // Verify that our two CPU frequency calculations do not differ substantially. - // - if (Cpu->CPUFrequencyFromART > 0 && Cpu->CPUFrequencyFromTSC > 0 - && ABS((INT64) Cpu->CPUFrequencyFromART - (INT64) Cpu->CPUFrequencyFromTSC) > OC_CPU_FREQUENCY_TOLERANCE) { - DEBUG (( - DEBUG_WARN, - "OCCPU: ART based CPU frequency differs substantially from TSC: %11LuHz != %11LuHz\n", - Cpu->CPUFrequencyFromART, - Cpu->CPUFrequencyFromTSC - )); - } - - // - // There may be some quirks with virtual CPUs (VMware is fine). - // Formerly we checked Cpu->MinBusRatio > 0, but we have no MinBusRatio on Penryn. - // - if (Cpu->CPUFrequency > 0 && Cpu->MaxBusRatio > Cpu->MinBusRatio) { - Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio); - } else { - // - // TODO: It seems to be possible that CPU frequency == 0 here... - // - Cpu->FSBFrequency = 100000000; // 100 Mhz - } - } - // - // Calculate number of cores - // If we are under virtualization, then we should get the topology from CPUID the same was as with Penryn. - // - if (Cpu->MaxId >= CPUID_CACHE_PARAMS && (Cpu->Model <= CPU_MODEL_PENRYN || Cpu->Hypervisor)) { - AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CpuidCacheEax.Uint32, &CpuidCacheEbx.Uint32, NULL, NULL); - if (CpuidCacheEax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) { - CoreCount = (UINT16)GetPowerOfTwo32 (CpuidCacheEax.Bits.MaximumAddressableIdsForProcessorCores + 1); - if (CoreCount < CpuidCacheEax.Bits.MaximumAddressableIdsForProcessorCores + 1) { - CoreCount *= 2; - } - Cpu->CoreCount = CoreCount; - // - // We should not be blindly relying on Cpu->Features & CPUID_FEATURE_HTT. - // On Penryn CPUs it is set even without Hyper Threading. - // - if (Cpu->ThreadCount < Cpu->CoreCount) { - Cpu->ThreadCount = Cpu->CoreCount; - } - } - } else if (Cpu->Model == CPU_MODEL_WESTMERE) { - Msr = AsmReadMsr64 (MSR_CORE_THREAD_COUNT); - Cpu->CoreCount = (UINT16)BitFieldRead64 (Msr, 16, 19); - Cpu->ThreadCount = (UINT16)BitFieldRead64 (Msr, 0, 15); - } else { - Msr = AsmReadMsr64 (MSR_CORE_THREAD_COUNT); - Cpu->CoreCount = (UINT16)BitFieldRead64 (Msr, 16, 31); - Cpu->ThreadCount = (UINT16)BitFieldRead64 (Msr, 0, 15); - } - - if (Cpu->CoreCount == 0) { - Cpu->CoreCount = 1; - } - - if (Cpu->ThreadCount == 0) { - Cpu->ThreadCount = 1; - } -} - -STATIC -VOID -ScanAmdProcessor ( - IN OUT OC_CPU_INFO *Cpu - ) -{ - UINT32 CpuidEbx; - UINT32 CpuidEcx; - UINT64 CofVid; - UINT8 CoreFrequencyID; - UINT8 CoreDivisorID; - UINT8 Divisor; - BOOLEAN Recalculate; - - // - // For logging purposes (the first call to these functions might happen - // before logging is fully initialised), do not use the cached results in - // DEBUG builds. - // - Recalculate = FALSE; - - DEBUG_CODE_BEGIN (); - Recalculate = TRUE; - DEBUG_CODE_END (); - - // - // Faking an Intel Core i5 Processor. - // This value is purely cosmetic, but it makes sense to fake something - // that is somewhat representative of the kind of Processor that's actually - // in the system - // - Cpu->AppleProcessorType = AppleProcessorTypeCorei5Type5; - // - // get TSC Frequency calculated in OcTimerLib, unless we got it already from virtualization extensions. - // FIXME(1): This code assumes the CPU operates in P0. Either ensure it does - // and raise the mode on demand, or adapt the logic to consider - // both the operating and the nominal frequency, latter for - // the invariant TSC. - // - if (Cpu->CPUFrequencyFromVMT == 0) { - Cpu->CPUFrequencyFromTSC = InternalCalculateTSCFromPMTimer (Recalculate); - Cpu->CPUFrequency = Cpu->CPUFrequencyFromTSC; - } - // - // Get core and thread count from CPUID - // - if (Cpu->MaxExtId >= 0x80000008) { - AsmCpuid (0x80000008, NULL, NULL, &CpuidEcx, NULL); - Cpu->ThreadCount = (UINT16) (BitFieldRead32 (CpuidEcx, 0, 7) + 1); - } - - if (Cpu->Family == AMD_CPU_FAMILY) { - Divisor = 0; - CoreFrequencyID = 0; - CoreDivisorID = 0; - - switch (Cpu->ExtFamily) { - case AMD_CPU_EXT_FAMILY_17H: - if (Cpu->CPUFrequencyFromVMT == 0) { - CofVid = AsmReadMsr64 (K10_PSTATE_STATUS); - CoreFrequencyID = (UINT8)BitFieldRead64 (CofVid, 0, 7); - CoreDivisorID = (UINT8)BitFieldRead64 (CofVid, 8, 13); - if (CoreDivisorID > 0ULL) { - // - // Sometimes incorrect hypervisor configuration will lead to dividing by zero, - // but these variables will not be used under hypervisor, so just skip these. - // - Cpu->MaxBusRatio = (UINT8) (CoreFrequencyID / CoreDivisorID * 2); - } - } - // - // Get core count from CPUID - // - if (Cpu->MaxExtId >= 0x8000001E) { - AsmCpuid (0x8000001E, NULL, &CpuidEbx, NULL, NULL); - Cpu->CoreCount = - (UINT16) DivU64x32 ( - Cpu->ThreadCount, - (BitFieldRead32 (CpuidEbx, 8, 15) + 1) - ); - } - break; - case AMD_CPU_EXT_FAMILY_15H: - case AMD_CPU_EXT_FAMILY_16H: - if (Cpu->CPUFrequencyFromVMT == 0) { - // FIXME: Please refer to FIXME(1) for the MSR used here. - CofVid = AsmReadMsr64 (K10_COFVID_STATUS); - CoreFrequencyID = (UINT8)BitFieldRead64 (CofVid, 0, 5); - CoreDivisorID = (UINT8)BitFieldRead64 (CofVid, 6, 8); - Divisor = 1U << CoreDivisorID; - // - // BKDG for AMD Family 15h Models 10h-1Fh Processors (42300 Rev 3.12) - // Core current operating frequency in MHz. CoreCOF = 100 * - // (MSRC001_00[6B:64][CpuFid] + 10h) / (2 ^ MSRC001_00[6B:64][CpuDid]). - // - if (Divisor > 0ULL) { - // - // Sometimes incorrect hypervisor configuration will lead to dividing by zero, - // but these variables will not be used under hypervisor, so just skip these. - // - Cpu->MaxBusRatio = (UINT8)((CoreFrequencyID + 0x10) / Divisor); - } - } - // - // AMD 15h and 16h CPUs don't support hyperthreading, - // so the core count is equal to the thread count - // - Cpu->CoreCount = Cpu->ThreadCount; - break; - default: - return; - } - - DEBUG (( - DEBUG_INFO, - "OCCPU: FID %u DID %u Divisor %u MaxBR %u\n", - CoreFrequencyID, - CoreDivisorID, - Divisor, - Cpu->MaxBusRatio - )); - - // - // When under virtualization this information is already available to us. - // - if (Cpu->CPUFrequencyFromVMT == 0) { - // - // Sometimes incorrect hypervisor configuration will lead to dividing by zero. - // - if (Cpu->MaxBusRatio == 0) { - Cpu->FSBFrequency = 100000000; // 100 Mhz like Intel part. - Cpu->MaxBusRatio = 1; // TODO: Maybe unsafe too, we need more investigation. - } else { - Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio); - } - // - // CPUPM is not supported on AMD, meaning the current - // and minimum bus ratio are equal to the maximum bus ratio - // - Cpu->CurBusRatio = Cpu->MaxBusRatio; - Cpu->MinBusRatio = Cpu->MaxBusRatio; - } - - } -} - -/** Scan the processor and fill the cpu info structure with results - - @param[in] Cpu A pointer to the cpu info structure to fill with results - - @retval EFI_SUCCESS The scan was completed successfully. -**/ -VOID -OcCpuScanProcessor ( - IN OUT OC_CPU_INFO *Cpu - ) -{ - UINT32 CpuidEax; - UINT32 CpuidEbx; - UINT32 CpuidEcx; - UINT32 CpuidEdx; - - ASSERT (Cpu != NULL); - - ZeroMem (Cpu, sizeof (*Cpu)); - - // - // Get vendor CPUID 0x00000000 - // - AsmCpuid (CPUID_SIGNATURE, &CpuidEax, &Cpu->Vendor[0], &Cpu->Vendor[2], &Cpu->Vendor[1]); - - Cpu->MaxId = CpuidEax; - - // - // Get extended CPUID 0x80000000 - // - AsmCpuid (CPUID_EXTENDED_FUNCTION, &CpuidEax, &CpuidEbx, &CpuidEcx, &CpuidEdx); - - Cpu->MaxExtId = CpuidEax; - - // - // Get brand string CPUID 0x80000002 - 0x80000004 - // - if (Cpu->MaxExtId >= CPUID_BRAND_STRING3) { - // - // The brandstring 48 bytes max, guaranteed NULL terminated. - // - UINT32 *BrandString = (UINT32 *) Cpu->BrandString; - - AsmCpuid ( - CPUID_BRAND_STRING1, - BrandString, - (BrandString + 1), - (BrandString + 2), - (BrandString + 3) - ); - - AsmCpuid ( - CPUID_BRAND_STRING2, - (BrandString + 4), - (BrandString + 5), - (BrandString + 6), - (BrandString + 7) - ); - - AsmCpuid ( - CPUID_BRAND_STRING3, - (BrandString + 8), - (BrandString + 9), - (BrandString + 10), - (BrandString + 11) - ); - } - - ScanThreadCount (Cpu); - - // - // Get processor signature and decode - // - if (Cpu->MaxId >= CPUID_VERSION_INFO) { - if (Cpu->Vendor[0] == CPUID_VENDOR_INTEL) { - Cpu->MicrocodeRevision = AsmReadIntelMicrocodeRevision (); - } - - AsmCpuid ( - CPUID_VERSION_INFO, - &Cpu->CpuidVerEax.Uint32, - &Cpu->CpuidVerEbx.Uint32, - &Cpu->CpuidVerEcx.Uint32, - &Cpu->CpuidVerEdx.Uint32 - ); - - Cpu->Signature = Cpu->CpuidVerEax.Uint32; - Cpu->Stepping = (UINT8) Cpu->CpuidVerEax.Bits.SteppingId; - Cpu->ExtModel = (UINT8) Cpu->CpuidVerEax.Bits.ExtendedModelId; - Cpu->Model = (UINT8) Cpu->CpuidVerEax.Bits.Model | (UINT8) (Cpu->CpuidVerEax.Bits.ExtendedModelId << 4U); - Cpu->Family = (UINT8) Cpu->CpuidVerEax.Bits.FamilyId; - Cpu->Type = (UINT8) Cpu->CpuidVerEax.Bits.ProcessorType; - Cpu->ExtFamily = (UINT8) Cpu->CpuidVerEax.Bits.ExtendedFamilyId; - Cpu->Brand = (UINT8) Cpu->CpuidVerEbx.Bits.BrandIndex; - Cpu->Features = LShiftU64 (Cpu->CpuidVerEcx.Uint32, 32) | Cpu->CpuidVerEdx.Uint32; - - if (Cpu->Features & CPUID_FEATURE_HTT) { - Cpu->ThreadCount = (UINT16) Cpu->CpuidVerEbx.Bits.MaximumAddressableIdsForLogicalProcessors; - } - } - - DEBUG ((DEBUG_INFO, "OCCPU: Found %a\n", Cpu->BrandString)); - - DEBUG (( - DEBUG_INFO, - "OCCPU: Signature %0X Stepping %0X Model %0X Family %0X Type %0X ExtModel %0X ExtFamily %0X uCode %0X\n", - Cpu->Signature, - Cpu->Stepping, - Cpu->Model, - Cpu->Family, - Cpu->Type, - Cpu->ExtModel, - Cpu->ExtFamily, - Cpu->MicrocodeRevision - )); - - Cpu->CPUFrequencyFromVMT = InternalCalculateVMTFrequency ( - &Cpu->FSBFrequency, - &Cpu->Hypervisor - ); - - if (Cpu->Hypervisor) { - DEBUG ((DEBUG_INFO, "OCCPU: Hypervisor detected\n")); - } - - if (Cpu->CPUFrequencyFromVMT > 0) { - Cpu->CPUFrequency = Cpu->CPUFrequencyFromVMT; - // - // We can calculate Bus Ratio here - // - Cpu->MaxBusRatio = (UINT8) DivU64x32 (Cpu->CPUFrequency, (UINT32)Cpu->FSBFrequency); - // - // We don't have anything like turbo, so we just assign some variables here - // - Cpu->MinBusRatio = Cpu->MaxBusRatio; - Cpu->CurBusRatio = Cpu->MaxBusRatio; - - DEBUG (( - DEBUG_INFO, - "OCCPU: VMWare TSC: %11LuHz, %5LuMHz; FSB: %11LuHz, %5LuMHz; BusRatio: %d\n", - Cpu->CPUFrequency, - DivU64x32 (Cpu->CPUFrequency, 1000000), - Cpu->FSBFrequency, - DivU64x32 (Cpu->FSBFrequency, 1000000), - Cpu->MaxBusRatio - )); - } - - if (Cpu->Vendor[0] == CPUID_VENDOR_INTEL) { - ScanIntelProcessor (Cpu); - } else if (Cpu->Vendor[0] == CPUID_VENDOR_AMD) { - ScanAmdProcessor (Cpu); - } else { - DEBUG ((DEBUG_WARN, "OCCPU: Found unsupported CPU vendor: %0X", Cpu->Vendor[0])); - return; - } - - // - // SMBIOS Type4 ExternalClock field is assumed to have X*4 FSB frequency in MT/s. - // This value is cosmetics, but we still want to set it properly. - // Magic 4 value comes from 4 links in pretty much every modern Intel CPU. - // On modern CPUs this is now named Base clock (BCLK). - // Note, that this value was incorrect for most Macs since iMac12,x till iMac18,x inclusive. - // REF: https://github.com/acidanthera/bugtracker/issues/622#issuecomment-570811185 - // - Cpu->ExternalClock = (UINT16) DivU64x32 (Cpu->FSBFrequency, 1000000); - // - // This is again cosmetics by errors in FSBFrequency calculation. - // - if (Cpu->ExternalClock >= 99 && Cpu->ExternalClock <= 101) { - Cpu->ExternalClock = 100; - } else if (Cpu->ExternalClock >= 132 && Cpu->ExternalClock <= 134) { - Cpu->ExternalClock = 133; - } else if (Cpu->ExternalClock >= 265 && Cpu->ExternalClock <= 267) { - Cpu->ExternalClock = 266; - } - - DEBUG (( - DEBUG_INFO, - "OCCPU: CPUFrequencyFromTSC %11LuHz %5LuMHz\n", - Cpu->CPUFrequencyFromTSC, - DivU64x32 (Cpu->CPUFrequencyFromTSC, 1000000) - )); - - DEBUG (( - DEBUG_INFO, - "OCCPU: CPUFrequency %11LuHz %5LuMHz\n", - Cpu->CPUFrequency, - DivU64x32 (Cpu->CPUFrequency, 1000000) - )); - - DEBUG (( - DEBUG_INFO, - "OCCPU: FSBFrequency %11LuHz %5LuMHz\n", - Cpu->FSBFrequency, - DivU64x32 (Cpu->FSBFrequency, 1000000) - )); - - DEBUG (( - DEBUG_INFO, - "OCCPU: Pkg %u Cores %u Threads %u\n", - Cpu->PackageCount, - Cpu->CoreCount, - Cpu->ThreadCount - )); -} - -VOID -OcCpuCorrectFlexRatio ( - IN OC_CPU_INFO *Cpu - ) -{ - UINT64 Msr; - UINT64 FlexRatio; - - if (Cpu->Vendor[0] == CPUID_VENDOR_INTEL - && Cpu->Model != CPU_MODEL_GOLDMONT - && Cpu->Model != CPU_MODEL_AIRMONT - && Cpu->Model != CPU_MODEL_AVOTON) { - Msr = AsmReadMsr64 (MSR_FLEX_RATIO); - if (Msr & FLEX_RATIO_EN) { - FlexRatio = BitFieldRead64 (Msr, 8, 15); - if (FlexRatio == 0) { - // - // Disable Flex Ratio if current value is 0. - // - AsmWriteMsr64 (MSR_FLEX_RATIO, Msr & ~((UINT64) FLEX_RATIO_EN)); - } - } - } -} - -STATIC -VOID -EFIAPI -SyncTscOnCpu ( - IN VOID *Buffer - ) -{ - OC_CPU_TSC_SYNC *Sync; - Sync = Buffer; - AsmIncrementUint32 (&Sync->CurrentCount); - while (Sync->CurrentCount < Sync->APThreadCount) { - // - // Busy-wait on AP CPU cores. - // - } - AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, Sync->Tsc); -} - -STATIC -VOID -EFIAPI -ResetAdjustTsc ( - IN VOID *Buffer - ) -{ - OC_CPU_TSC_SYNC *Sync; - Sync = Buffer; - AsmIncrementUint32 (&Sync->CurrentCount); - while (Sync->CurrentCount < Sync->APThreadCount) { - // - // Busy-wait on AP CPU cores. - // - } - AsmWriteMsr64 (MSR_IA32_TSC_ADJUST, 0); -} - -EFI_STATUS -OcCpuCorrectTscSync ( - IN OC_CPU_INFO *Cpu, - IN UINTN Timeout - ) -{ - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpServices; - FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpServices; - OC_CPU_TSC_SYNC Sync; - EFI_TPL OldTpl; - BOOLEAN InterruptState; - - if (Cpu->ThreadCount <= 1) { - DEBUG ((DEBUG_INFO, "OCCPU: Thread count is too low for sync - %u\n", Cpu->ThreadCount)); - return EFI_UNSUPPORTED; - } - - Status = gBS->LocateProtocol ( - &gEfiMpServiceProtocolGuid, - NULL, - (VOID **) &MpServices - ); - - if (EFI_ERROR(Status)) { - MpServices = NULL; - Status = gBS->LocateProtocol ( - &gFrameworkEfiMpServiceProtocolGuid, - NULL, - (VOID **) &FrameworkMpServices - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCCPU: Failed to find mp services - %r\n", Status)); - return Status; - } - } - - Sync.CurrentCount = 0; - Sync.APThreadCount = Cpu->ThreadCount - 1; - - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - InterruptState = SaveAndDisableInterrupts (); - - if (Cpu->TscAdjust > 0) { - if (MpServices != NULL) { - Status = MpServices->StartupAllAPs (MpServices, ResetAdjustTsc, FALSE, NULL, Timeout, &Sync, NULL); - } else { - Status = FrameworkMpServices->StartupAllAPs (FrameworkMpServices, ResetAdjustTsc, FALSE, NULL, Timeout, &Sync, NULL); - } - - AsmWriteMsr64 (MSR_IA32_TSC_ADJUST, 0); - } else { - Sync.Tsc = AsmReadTsc (); - - if (MpServices != NULL) { - Status = MpServices->StartupAllAPs (MpServices, SyncTscOnCpu, FALSE, NULL, Timeout, &Sync, NULL); - } else { - Status = FrameworkMpServices->StartupAllAPs (FrameworkMpServices, SyncTscOnCpu, FALSE, NULL, Timeout, &Sync, NULL); - } - - AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, Sync.Tsc); - } - - SetInterruptState (InterruptState); - gBS->RestoreTPL (OldTpl); - - DEBUG ((DEBUG_INFO, "OCCPU: Completed TSC sync with code - %r\n", Status)); - - return Status; -} - -OC_CPU_GENERATION -OcCpuGetGeneration ( - VOID - ) -{ - CPU_MICROCODE_PROCESSOR_SIGNATURE Sig; - UINT32 CpuFamily; - UINT32 CpuModel; - OC_CPU_GENERATION CpuGeneration; - - Sig.Uint32 = 0; - - AsmCpuid (1, &Sig.Uint32, NULL, NULL, NULL); - - CpuFamily = Sig.Bits.Family; - if (CpuFamily == 15) { - CpuFamily += Sig.Bits.ExtendedFamily; - } - - CpuModel = Sig.Bits.Model; - if (CpuFamily == 15 || CpuFamily == 6) { - CpuModel |= Sig.Bits.ExtendedModel << 4; - } - - CpuGeneration = OcCpuGenerationUnknown; - if (CpuFamily == 6) { - switch (CpuModel) { - case CPU_MODEL_PENRYN: - CpuGeneration = OcCpuGenerationPenryn; - break; - case CPU_MODEL_NEHALEM: - case CPU_MODEL_FIELDS: - case CPU_MODEL_DALES: - case CPU_MODEL_NEHALEM_EX: - CpuGeneration = OcCpuGenerationNehalem; - break; - case CPU_MODEL_DALES_32NM: - case CPU_MODEL_WESTMERE: - case CPU_MODEL_WESTMERE_EX: - CpuGeneration = OcCpuGenerationWestmere; - break; - case CPU_MODEL_SANDYBRIDGE: - case CPU_MODEL_JAKETOWN: - CpuGeneration = OcCpuGenerationSandyBridge; - break; - case CPU_MODEL_IVYBRIDGE: - case CPU_MODEL_IVYBRIDGE_EP: - CpuGeneration = OcCpuGenerationIvyBridge; - break; - case CPU_MODEL_HASWELL: - case CPU_MODEL_HASWELL_EP: - case CPU_MODEL_HASWELL_ULT: - case CPU_MODEL_CRYSTALWELL: - CpuGeneration = OcCpuGenerationHaswell; - break; - case CPU_MODEL_BROADWELL: - case CPU_MODEL_BROADWELL_EP: - case CPU_MODEL_BRYSTALWELL: - CpuGeneration = OcCpuGenerationBroadwell; - break; - case CPU_MODEL_SKYLAKE: - case CPU_MODEL_SKYLAKE_DT: - case CPU_MODEL_SKYLAKE_W: - CpuGeneration = OcCpuGenerationSkylake; - break; - case CPU_MODEL_KABYLAKE: - case CPU_MODEL_KABYLAKE_DT: - // - // Kaby has 0x9 stepping, and Coffee use 0xA / 0xB stepping. - // - if (Sig.Bits.Stepping == 9) { - CpuGeneration = OcCpuGenerationKabyLake; - } else { - CpuGeneration = OcCpuGenerationCoffeeLake; - } - break; - case CPU_MODEL_CANNONLAKE: - CpuGeneration = OcCpuGenerationCannonLake; - break; - } - } - - DEBUG (( - DEBUG_VERBOSE, - "OCCPU: Discovered CpuFamily %d CpuModel %d CpuStepping %d CpuGeneration %d\n", - CpuFamily, - CpuModel, - Sig.Bits.Stepping, - CpuGeneration - )); - - return CpuGeneration; -} diff --git a/Library/OcCpuLib/OcCpuLib.inf b/Library/OcCpuLib/OcCpuLib.inf deleted file mode 100755 index dc1734a10..000000000 --- a/Library/OcCpuLib/OcCpuLib.inf +++ /dev/null @@ -1,62 +0,0 @@ -## @file -# -# Component description file for OcCpulibrary. -# -# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcCpuLib - FILE_GUID = 5F3FA330-4F32-4AC9-9407-B932CFECFDB2 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcCpuLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# VALID_ARCHITECTURES = IA32 X64 - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - -[LibraryClasses] - BaseLib - IoLib - UefiRuntimeServicesTableLib - -[Guids] - gOcVendorVariableGuid - -[Protocols] - gEfiMpServiceProtocolGuid - gFrameworkEfiMpServiceProtocolGuid - -[Sources] - AppleCpuSupport.c - FrequencyDetect.c - OcCpuLib.c - OcCpuInternals.h - ../../Include/Library/OcCpuLib.h - -[Sources.Ia32] - Ia32/Atomic.nasm - Ia32/Microcode.nasm - -[Sources.X64] - X64/Atomic.nasm - X64/Microcode.nasm diff --git a/Library/OcCpuLib/X64/Atomic.nasm b/Library/OcCpuLib/X64/Atomic.nasm deleted file mode 100644 index 47c76ae89..000000000 --- a/Library/OcCpuLib/X64/Atomic.nasm +++ /dev/null @@ -1,33 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 64 -DEFAULT REL - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT32 -; EFIAPI -; AsmIncrementUint32 ( -; IN volatile UINT32 *Value -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(AsmIncrementUint32) -ASM_PFX(AsmIncrementUint32): - mov eax, 1 - lock xadd dword [rcx], eax - inc eax - ret diff --git a/Library/OcCpuLib/X64/Microcode.nasm b/Library/OcCpuLib/X64/Microcode.nasm deleted file mode 100644 index a3f5b489f..000000000 --- a/Library/OcCpuLib/X64/Microcode.nasm +++ /dev/null @@ -1,48 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 64 -DEFAULT REL - -MSR_IA32_BIOS_SIGN_ID equ 00000008Bh -CPUID_VERSION_INFO equ 1 - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT32 -; EFIAPI -; AsmReadIntelMicrocodeRevision ( -; VOID -; ); -;------------------------------------------------------------------------------ -align 8 -global ASM_PFX(AsmReadIntelMicrocodeRevision) -ASM_PFX(AsmReadIntelMicrocodeRevision): - ; Several Intel CPUs, notably Westmere, require a certain assembly - ; sequence to retrieve microcode revision. - ; Reference: https://github.com/acidanthera/bugtracker/issues/621. - push rbx - mov ecx, MSR_IA32_BIOS_SIGN_ID - xor eax, eax - xor edx, edx - wrmsr - mov eax, CPUID_VERSION_INFO - cpuid - mov ecx, MSR_IA32_BIOS_SIGN_ID - rdmsr - mov eax, edx - pop rbx - ret diff --git a/Library/OcCryptoLib/Aes.c b/Library/OcCryptoLib/Aes.c deleted file mode 100755 index f3cca3b5f..000000000 --- a/Library/OcCryptoLib/Aes.c +++ /dev/null @@ -1,673 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2018, savvas - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -/** - -Copyright (c) 2014-2018, kokke - -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to - -**/ - -/** - -This is an implementation of the AES algorithm, specifically CTR and CBC mode. -Block size can be chosen in OcCryptoLib.h. - -The implementation is verified against the test vectors in: - National Institute of Standards and Technology Special Publication 800-38A 2001 ED - - -NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) - You should pad the end of the string with zeros if this is not the case. - For AES192/256 the key size is proportionally larger. - -**/ - -#include -#include - -// -// The number of columns comprising a state in AES (Nb). This is a CONSTant in AES. Value=4 -// The number of 32 bit words in a key (Nk). -// The number of rounds in AES Cipher (Nr). -// - -#define Nb 4 - -#if CONFIG_AES_KEY_SIZE == 32 -#define Nk 8 -#define Nr 14 -#elif CONFIG_AES_KEY_SIZE == 24 -#define Nk 6 -#define Nr 12 -#elif CONFIG_AES_KEY_SIZE == 16 -#define Nk 4 -#define Nr 10 -#endif - -// -// state - array holding the intermediate results during decryption. -// -typedef UINT8 AES_INTERNAL_STATE[4][4]; - -// -// The lookup-tables are marked CONST so they can be placed in read-only storage instead of RAM -// The numbers below can be computed dynamically trading ROM for RAM - -// This can be useful in (embedded) bootloader applications, where ROM is often limited. -// -STATIC CONST UINT8 Sbox[256] = { - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -STATIC CONST UINT8 RsBox[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -}; - -// -// The round CONSTant word array, Rcon[i], contains the values given by -// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) -// -STATIC CONST UINT8 Rcon[11] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 -}; - -/* - * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), - * that you can remove most of the elements in the Rcon array, because they are unused. - * - * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon - * - * "Only the first some of these CONSTants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed), - * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." - */ - - -// -// Private functions: -// -#define GetSboxValue(num) (Sbox[(num)]) -#define GetSBoxInvert(num) (RsBox[(num)]) - -// -// This function produces Nb(Nr+1) round keys. The round keys are used in each -// round to decrypt the states. -// -STATIC -VOID -KeyExpansion ( - OUT UINT8 *RoundKey, - IN CONST UINT8 *Key - ) -{ - UINT32 Index, J, K; - // - // Used for the column/row operations - // - UINT8 TempA[4]; - - // - // The first round key is the key itself. - // - for (Index = 0; Index < Nk; ++Index) { - RoundKey[(Index * 4) + 0] = Key[(Index * 4) + 0]; - RoundKey[(Index * 4) + 1] = Key[(Index * 4) + 1]; - RoundKey[(Index * 4) + 2] = Key[(Index * 4) + 2]; - RoundKey[(Index * 4) + 3] = Key[(Index * 4) + 3]; - } - - // - // All other round keys are found from the previous round keys. - // - for (Index = Nk; Index < Nb * (Nr + 1); ++Index) { - K = (Index - 1) * 4; - TempA[0] = RoundKey[K + 0]; - TempA[1] = RoundKey[K + 1]; - TempA[2] = RoundKey[K + 2]; - TempA[3] = RoundKey[K + 3]; - - if (Index % Nk == 0) { - // - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - // - - // - // Function RotWord() - // - K = TempA[0]; - TempA[0] = TempA[1]; - TempA[1] = TempA[2]; - TempA[2] = TempA[3]; - TempA[3] = (UINT8) K; - - // - // SubWord() is a function that takes a four-byte input word and - // applies the S-box to each of the four bytes to produce an output word. - // - - // - // Function Subword() - // - TempA[0] = GetSboxValue (TempA[0]); - TempA[1] = GetSboxValue (TempA[1]); - TempA[2] = GetSboxValue (TempA[2]); - TempA[3] = GetSboxValue (TempA[3]); - - TempA[0] = TempA[0] ^ Rcon[Index / Nk]; - } - -#if CONFIG_AES_KEY_SIZE == 32 - if (Index % Nk == 4) { - // - // Function Subword() - // - TempA[0] = GetSboxValue (TempA[0]); - TempA[1] = GetSboxValue (TempA[1]); - TempA[2] = GetSboxValue (TempA[2]); - TempA[3] = GetSboxValue (TempA[3]); - } -#endif - - J = Index * 4; K = (Index - Nk) * 4; - RoundKey[J + 0] = RoundKey[K + 0] ^ TempA[0]; - RoundKey[J + 1] = RoundKey[K + 1] ^ TempA[1]; - RoundKey[J + 2] = RoundKey[K + 2] ^ TempA[2]; - RoundKey[J + 3] = RoundKey[K + 3] ^ TempA[3]; - } -} - -VOID -AesInitCtxIv ( - OUT AES_CONTEXT *Context, - IN CONST UINT8 *Key, - IN CONST UINT8 *Iv - ) -{ - KeyExpansion (Context->RoundKey, Key); - CopyMem (Context->Iv, Iv, AES_BLOCK_SIZE); -} - -VOID -AesSetCtxIv ( - OUT AES_CONTEXT *Context, - IN CONST UINT8 *Iv - ) -{ - CopyMem (Context->Iv, Iv, AES_BLOCK_SIZE); -} - -// -// This function adds the round key to state. -// The round key is added to the state by an XOR function. -// -STATIC -VOID -AddRoundKey ( - IN UINT8 Round, - IN OUT AES_INTERNAL_STATE *State, - IN CONST UINT8 *RoundKey - ) -{ - UINT8 I, J; - - for (I = 0; I < 4; ++I) { - for (J = 0; J < 4; ++J) { - (*State)[I][J] ^= RoundKey[(Round * Nb * 4) + (I * Nb) + J]; - } - } -} - -// -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -// -STATIC -VOID -SubBytes ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 I, J; - - for (I = 0; I < 4; ++I) { - for (J = 0; J < 4; ++J) { - (*State)[J][I] = GetSboxValue((*State)[J][I]); - } - } -} - -// -// The ShiftRows() function shifts the rows in the state to the left. -// Each row is shifted with different offset. -// Offset = Row number. So the first row is not shifted. -// -STATIC -VOID -ShiftRows ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 Temp; - - // - // Rotate first row 1 columns to left - // - Temp = (*State)[0][1]; - (*State)[0][1] = (*State)[1][1]; - (*State)[1][1] = (*State)[2][1]; - (*State)[2][1] = (*State)[3][1]; - (*State)[3][1] = Temp; - - // - // Rotate second row 2 columns to left - // - Temp = (*State)[0][2]; - (*State)[0][2] = (*State)[2][2]; - (*State)[2][2] = Temp; - - Temp = (*State)[1][2]; - (*State)[1][2] = (*State)[3][2]; - (*State)[3][2] = Temp; - - // - // Rotate third row 3 columns to left - // - Temp = (*State)[0][3]; - (*State)[0][3] = (*State)[3][3]; - (*State)[3][3] = (*State)[2][3]; - (*State)[2][3] = (*State)[1][3]; - (*State)[1][3] = Temp; -} - -STATIC -UINT8 -XTime ( - IN UINT8 X - ) -{ - return (UINT8) (((UINT32) X << 1u) ^ ((((UINT32) X >> 7u) & 1u) * 0x1bu)); -} - -// -// MixColumns function mixes the columns of the state matrix -// -STATIC -VOID -MixColumns ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 I, Tmp, Tm, T; - - for (I = 0; I < 4; ++I) { - T = (*State)[I][0]; - Tmp = (UINT8) ((UINT32) ((*State) [I][0]) ^ (UINT32) ((*State) [I][1]) - ^ (UINT32) ((*State) [I][2]) ^ (UINT32) ((*State) [I][3])); - Tm = (*State) [I][0] ^ (*State) [I][1]; - Tm = XTime (Tm); - (*State) [I][0] ^= Tm ^ Tmp; - Tm = (*State)[I][1] ^ (*State)[I][2]; - Tm = XTime (Tm); - (*State) [I][1] ^= Tm ^ Tmp; - Tm = (*State) [I][2] ^ (*State) [I][3]; - Tm = XTime (Tm); - (*State) [I][2] ^= Tm ^ Tmp; - Tm = (*State)[I][3] ^ T ; - Tm = XTime (Tm); - (*State) [I][3] ^= Tm ^ Tmp ; - } -} - -// -// Multiply is used to multiply numbers in the field GF(2^8) -// Note: The last call to XTime() is unneeded, but often ends up generating a smaller binary -// The compiler seems to be able to vectorize the operation better this way. -// See https://github.com/kokke/tiny-AES-c/pull/34 -// -#define Multiply(x, y) \ - ( (((y) & 1u) * (x)) ^ \ - (((y)>>1u & 1u) * XTime(x)) ^ \ - (((y)>>2u & 1u) * XTime(XTime(x))) ^ \ - (((y)>>3u & 1u) * XTime(XTime(XTime(x)))) ^ \ - (((y)>>4u & 1u) * XTime(XTime(XTime(XTime(x)))))) \ - -// -// MixColumns function mixes the columns of the state matrix. -// The method used to multiply may be difficult to understand for the inexperienced. -// Please use the references to gain more information. -// -STATIC -VOID -InvMixColumns ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 I, A, B, C, D; - - for (I = 0; I < 4; ++I) { - A = (*State) [I][0]; - B = (*State) [I][1]; - C = (*State) [I][2]; - D = (*State) [I][3]; - - (*State)[I][0] = (UINT8) ((UINT32) Multiply(A, 0x0eu) ^ (UINT32) Multiply(B, 0x0bu) - ^ (UINT32) Multiply(C, 0x0du) ^ (UINT32) Multiply(D, 0x09u)); - (*State)[I][1] = (UINT8) ((UINT32) Multiply(A, 0x09u) ^ (UINT32) Multiply(B, 0x0eu) - ^ (UINT32) Multiply(C, 0x0bu) ^ (UINT32) Multiply(D, 0x0du)); - (*State)[I][2] = (UINT8) ((UINT32) Multiply(A, 0x0du) ^ (UINT32) Multiply(B, 0x09u) - ^ (UINT32) Multiply(C, 0x0eu) ^ (UINT32) Multiply(D, 0x0bu)); - (*State)[I][3] = (UINT8) ((UINT32) Multiply(A, 0x0bu) ^ (UINT32) Multiply(B, 0x0du) - ^ (UINT32) Multiply(C, 0x09u) ^ (UINT32) Multiply(D, 0x0eu)); - } -} - -// -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -// -STATIC -VOID -InvSubBytes ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 I, J; - - for (I = 0; I < 4; ++I) { - for (J = 0; J < 4; ++J) { - (*State)[J][I] = GetSBoxInvert ((*State)[J][I]); - } - } -} - -STATIC -VOID -InvShiftRows ( - IN OUT AES_INTERNAL_STATE *State - ) -{ - UINT8 Temp; - - // - // Rotate first row 1 columns to right - // - Temp = (*State)[3][1]; - (*State)[3][1] = (*State)[2][1]; - (*State)[2][1] = (*State)[1][1]; - (*State)[1][1] = (*State)[0][1]; - (*State)[0][1] = Temp; - - // - // Rotate second row 2 columns to right - // - Temp = (*State)[0][2]; - (*State)[0][2] = (*State)[2][2]; - (*State)[2][2] = Temp; - - Temp = (*State)[1][2]; - (*State)[1][2] = (*State)[3][2]; - (*State)[3][2] = Temp; - - // - // Rotate third row 3 columns to right - // - Temp = (*State)[0][3]; - (*State)[0][3] = (*State)[1][3]; - (*State)[1][3] = (*State)[2][3]; - (*State)[2][3] = (*State)[3][3]; - (*State)[3][3] = Temp; -} - -// -// Cipher is the main function that encrypts the PlainText. -// -STATIC -VOID -Cipher ( - IN OUT AES_INTERNAL_STATE *State, - IN CONST UINT8 *RoundKey - ) -{ - UINT8 Round; - - // - // Add the First round key to the state before starting the rounds. - // - AddRoundKey(0, State, RoundKey); - - // - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - // - for (Round = 1; Round < Nr; ++Round) { - SubBytes (State); - ShiftRows (State); - MixColumns (State); - AddRoundKey (Round, State, RoundKey); - } - - // - // The last round is given below. - // The MixColumns function is not here in the last round. - // - SubBytes (State); - ShiftRows (State); - AddRoundKey (Nr, State, RoundKey); -} - -STATIC -VOID -InvCipher ( - IN OUT AES_INTERNAL_STATE *State, - IN CONST UINT8 *RoundKey - ) -{ - UINT8 Round; - - // - // Add the First round key to the state before starting the rounds. - // - AddRoundKey (Nr, State, RoundKey); - - // - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - // - for (Round = (Nr - 1); Round > 0; --Round) { - InvShiftRows (State); - InvSubBytes (State); - AddRoundKey (Round, State, RoundKey); - InvMixColumns (State); - } - - // - // The last round is given below. - // The MixColumns function is not here in the last round. - // - InvShiftRows (State); - InvSubBytes (State); - AddRoundKey (0, State, RoundKey); -} - -STATIC -VOID -XorWithIv ( - IN OUT UINT8 *Buf, - IN CONST UINT8 *Iv - ) -{ - UINT8 I; - - // - // The block in AES is always 128bit no matter the key size - // - for (I = 0; I < AES_BLOCK_SIZE; ++I) { - Buf[I] ^= Iv[I]; - } -} - -// -// Public functions -// - -VOID -AesCbcEncryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ) -{ - UINT32 I; - UINT8 *Iv; - - Iv = Context->Iv; - - for (I = 0; I < Len; I += AES_BLOCK_SIZE) { - XorWithIv (Data, Iv); - Cipher ((AES_INTERNAL_STATE *) Data, Context->RoundKey); - Iv = Data; - Data += AES_BLOCK_SIZE; - } - - // - // Store Iv in Context for next call - // - CopyMem (Context->Iv, Iv, AES_BLOCK_SIZE); -} - -VOID -AesCbcDecryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ) -{ - UINT32 I; - UINT8 StoreNextIv[AES_BLOCK_SIZE]; - - for (I = 0; I < Len; I += AES_BLOCK_SIZE) { - CopyMem (StoreNextIv, Data, AES_BLOCK_SIZE); - InvCipher ((AES_INTERNAL_STATE *) Data, Context->RoundKey); - XorWithIv (Data, Context->Iv); - CopyMem (Context->Iv, StoreNextIv, AES_BLOCK_SIZE); - Data += AES_BLOCK_SIZE; - } -} - -// -// Symmetrical operation: same function for encrypting as for decrypting. -// Note any IV/nonce should never be reused with the same key -// -VOID -AesCtrXcryptBuffer ( - IN OUT AES_CONTEXT *Context, - IN OUT UINT8 *Data, - IN UINT32 Len - ) -{ - UINT8 Buffer[AES_BLOCK_SIZE]; - UINT32 I; - INT32 Bi; - - for (I = 0, Bi = AES_BLOCK_SIZE; I < Len; ++I, ++Bi) { - // - // We need to regen xor compliment in buffer - // - if (Bi == AES_BLOCK_SIZE) { - CopyMem (Buffer, Context->Iv, AES_BLOCK_SIZE); - Cipher ((AES_INTERNAL_STATE *) Buffer, Context->RoundKey); - - // - // Increment Iv and handle overflow - // - for (Bi = (AES_BLOCK_SIZE - 1); Bi >= 0; --Bi) { - // - // Inc will owerflow - // - if (Context->Iv[Bi] == 255) { - Context->Iv[Bi] = 0; - continue; - } - - Context->Iv[Bi] += 1; - break; - } - - Bi = 0; - } - - Data[I] = (Data[I] ^ Buffer[Bi]); - } -} diff --git a/Library/OcCryptoLib/BigNumLib.h b/Library/OcCryptoLib/BigNumLib.h deleted file mode 100644 index 9ef83c64d..000000000 --- a/Library/OcCryptoLib/BigNumLib.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - This library performs arbitrary precision arithmetic operations. - For more details, please refer to the source files and function headers. - - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef BIG_NUM_LIB_H -#define BIG_NUM_LIB_H - -#include - -/// -/// A BIGNUM word. This is at best an integer of the platform's natural size -/// to optimize memory accesses and arithmetic operation count. -/// -typedef UINTN OC_BN_WORD; -// -// Declarations regarding the Word size. -// -#define OC_BN_WORD_SIZE (sizeof (OC_BN_WORD)) -#define OC_BN_WORD_NUM_BITS ((OC_BN_NUM_BITS) (OC_BN_WORD_SIZE * OC_CHAR_BIT)) -// -// Declarations regarding the maximum size of OC_BN structures. -// -typedef UINT16 OC_BN_NUM_WORDS; -typedef UINT32 OC_BN_NUM_BITS; -#define OC_BN_MAX_SIZE MAX_UINT16 -#define OC_BN_MAX_LEN (OC_BN_MAX_SIZE / OC_BN_WORD_SIZE) - -// -// Primitives -// - -/** - Parses a data array into a number. The buffer size must be a multiple of the - Word size. The length of Result must precisely fit the required size. - - @param[in,out] Result The buffer to store the result in. - @param[in] NumWords The number of Words of Result. - @param[in] Buffer The buffer to parse. - @param[in] BufferSize The size, in bytes, of Buffer. - -**/ -VOID -BigNumParseBuffer ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST UINT8 *Buffer, - IN UINTN BufferSize - ); - -/** - Swaps the byte order of Word. - - @param[in] Word The Word to swap. - - @returns The byte-swapped value of Word. - -**/ -OC_BN_WORD -BigNumSwapWord ( - IN OC_BN_WORD Word - ); - -// -// Montgomery arithmetics -// - -/** - Calculates the Montgomery Inverse and R^2 mod N. - - @param[in,out] RSqrMod The buffer to return R^2 mod N into. - @param[in] NumWords The number of Words of RSqrMod and N. - @param[in] N The Montgomery Modulus. - - @returns The Montgomery Inverse of N. - -**/ -OC_BN_WORD -BigNumCalculateMontParams ( - IN OUT OC_BN_WORD *RSqrMod, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *N - ); - -/** - Caulculates the exponentiation of A with B mod N. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWords The number of Words of Result, A, N and RSqrMod. - @param[in] A The base. - @param[in] B The exponent. - @param[in] N The modulus. - @param[in] N0Inv The Montgomery Inverse of N. - @param[in] RSqrMod Montgomery's R^2 mod N. - - @returns Whether the operation was completes successfully. - -**/ -BOOLEAN -BigNumPowMod ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN UINT32 B, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv, - IN CONST OC_BN_WORD *RSqrMod - ); - -#endif // BIG_NUM_LIB_H diff --git a/Library/OcCryptoLib/BigNumLibInternal.h b/Library/OcCryptoLib/BigNumLibInternal.h deleted file mode 100644 index fe694fd3e..000000000 --- a/Library/OcCryptoLib/BigNumLibInternal.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef BIG_NUM_LIB_INTERNAL_H -#define BIG_NUM_LIB_INTERNAL_H - -#include "BigNumLib.h" - -/** - Calculates the product of A and B. - - @param[out] Hi Buffer in which the high Word of the result is returned. - @param[in] A The multiplicant. - @param[in] B The multiplier. - - @returns The low Word of the result. - -**/ -OC_BN_WORD -BigNumWordMul64 ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ); - -/** - Calculates the product of A and B. - - @param[out] Hi Buffer in which the high Word of the result is returned. - @param[in] A The multiplicant. - @param[in] B The multiplier. - - @returns The low Word of the result. - -**/ -OC_BN_WORD -BigNumWordMul ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ); - -/** - Calulates the difference of A and B. - A must have the same precision as B. Result must have a precision at most as - bit as A and B. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWords The number of Words of Result, minimum number of - Words of A and B. - @param[in] A The minuend. - @param[in] B The subtrahend. - -**/ -VOID -BigNumSub ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN CONST OC_BN_WORD *B - ); - -/** - Calculates the binary union of A and (Value << Exponent). - - @param[in,out] A The number to OR with and store the result into. - @param[in] NumWords The number of Words of A. - @param[in] Value The Word value to OR with. - @param[in] Exponent The Word shift exponent. - -**/ -VOID -BigNumOrWord ( - IN OUT OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords, - IN OC_BN_WORD Value, - IN UINTN Exponent - ); - -/** - Calculates the remainder of A and B. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsRest The number of Words of Result and B. - @param[in] A The dividend. - @param[in] NumWordsA The number of Words of A. - @param[in] B The divisor. - - @returns Whether the operation was completes successfully. - -**/ -BOOLEAN -BigNumMod ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsRest, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN CONST OC_BN_WORD *B - ); - -/** - Returns the relative order of A and B. A and B must have the same precision. - - @param[in] A The first number to compare. - @param[in] NumWords The number of Words to compare. - @param[in] B The second number to compare. - - @retval < 0 A is lower than B. - @retval 0 A is as big as B. - @retval > 0 A is greater than B. - -**/ -INTN -BigNumCmp ( - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *B - ); - -/** - Returns the number of significant bits in a number. - Logically matches OpenSSL's BN_num_bits. - - @param[in] A The number to gather the number of significant bits of. - @param[in] NumWords The number of Words of A. - - @returns The number of significant bits in A. - -**/ -OC_BN_NUM_BITS -BigNumSignificantBits ( - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords - ); - -#endif // BIG_NUM_LIB_INTERNAL_H diff --git a/Library/OcCryptoLib/BigNumMontgomery.c b/Library/OcCryptoLib/BigNumMontgomery.c deleted file mode 100644 index 2e2963925..000000000 --- a/Library/OcCryptoLib/BigNumMontgomery.c +++ /dev/null @@ -1,660 +0,0 @@ -/** - This library performs arbitrary precision Montgomery operations. - All results are returned into caller-provided buffers. The caller is - responsible to ensure the buffers can hold the full result of the operation. - - https://chromium.googlesource.com/chromiumos/platform/ec/+/master/common/rsa.c - has served as a template for several algorithmic ideas. - - This code is not to be considered general-purpose but solely to support - cryptographic operations such as RSA encryption. As such, there are arbitrary - limitations, such as requirement of equal precision, to limit the complexity - of the operations to the bare minimum required to support such use caes. - - SECURITY: Currently, no security measures have been taken. This code is - vulnerable to both timing and side channel attacks for value - leakage. However, its current purpose is the verification of public - binaries with public certificates, for which this is perfectly - acceptable, especially in regards to performance. - - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include - -#include "BigNumLibInternal.h" - -/** - Calculates the Montgomery Inverse -1 / A mod 2^#Bits(Word). - This algorithm is based on the Extended Euclidean Algorithm, which returns - 1 / A mod 2^#Bits(Word). - - @param[in] A The number to calculate the Montgomery Inverse of. - - @retval 0 The Montgomery Inverse of A could not be computed. - @retval other The Montgomery Inverse of A. - -**/ -STATIC -OC_BN_WORD -BigNumMontInverse ( - IN CONST OC_BN_WORD *A - ) -{ - OC_BN_WORD Dividend; - OC_BN_WORD Divisor; - OC_BN_WORD X; - OC_BN_WORD Y; - OC_BN_WORD Mod; - OC_BN_WORD Div; - OC_BN_WORD Tmp; - - ASSERT (A != NULL); - // - // We cannot compute the Montgomery Inverse of 0. - // - if (A[0] == 0) { - return 0; - } - - // - // The initial divisor 2^Bits(Word) obviously cannot be represented as a - // variable value. For this reason, the first two iterations of the loop are - // unrolled. 2^Bits(Word) is represented as 0 as those two values are - // congruent modulo 2^Bits(Word), which is the variable storage space. - // The modulo operation is therefor implemented as a subtraction loop. - // - - // - // === INITIALISATION === - // - // Divisor = 1U << sizeof(A->Words[0]) * OC_CHAR_BIT; - // Dividend = A->Words[0]; - // - // Y = 1; - // X = 0; - // - // === LOOP UNROLL 1) === - // - // Div = Dividend / Divisor; // => 0 - // Mod = Dividend % Divisor; // => A->Words[0] - // - // Dividend = Divisor; // => 2^Bits(Word) - // Divisor = Mod; // => A->Words[0] - // - Dividend = 0; - Divisor = A[0]; - // - // Tmp = Y - Div * X; // => 1 - // Y = X; // => 0 - // X = Tmp; // => 1 - // - // === LOOP UNROLL 2) === - // - // Div = Dividend / Divisor; - // Mod = Dividend % Divisor; - // - Div = 0; - do { - Dividend -= Divisor; - ++Div; - } while (Dividend >= Divisor); - - Mod = Dividend; - // - // Dividend = Divisor; - // Divisor = Mod; - // - Dividend = Divisor; - Divisor = Mod; - // - // Tmp = Y - Div * X; // => -Div - // Y = X; // => 1 - // X = Tmp; // => -Div - // - Y = 1; - X = (OC_BN_WORD)0U - Div; - - while (Divisor != 0) { - // - // FIXME: This needs a good source for an algorithm specification. - // - Div = Dividend / Divisor; - Mod = Dividend % Divisor; - - Dividend = Divisor; - Divisor = Mod; - - Tmp = Y - Div * X; - Y = X; - X = Tmp; - } - // - // When the loop ends, Dividend contains the Greatest Common Divisor. - // If it is not 1, we cannot compute the Montgomery Inverse. - // - if (Dividend != 1) { - return 0; - } - // - // As per above, Y is 1 / A mod 2^#Bits(Word), so invert the result to yield - // -1 / A mod 2^#Bits(Word). - // - return (OC_BN_WORD)0U - Y; -} - -OC_BN_WORD -BigNumCalculateMontParams ( - IN OUT OC_BN_WORD *RSqrMod, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *N - ) -{ - OC_BN_WORD N0Inv; - UINT32 NumBits; - UINTN SizeRSqr; - OC_BN_NUM_WORDS NumWordsRSqr; - OC_BN_WORD *RSqr; - - ASSERT (RSqrMod != NULL); - ASSERT (NumWords > 0); - ASSERT (N != NULL); - // - // Calculate the Montgomery Inverse. - // This is a reduced approach of the algorithmic -1 / N mod 2^#Bits(N), - // where the modulus is reduced from 2^#Bits(N) to 2^#Bits(Word). This - // reduces N to N[0] and yields an inverse valid in the Word domain. - // - N0Inv = BigNumMontInverse (N); - if (N0Inv == 0) { - return 0; - } - - NumBits = BigNumSignificantBits (N, NumWords); -/* - STATIC_ASSERT ( - OC_BN_MAX_SIZE * OC_CHAR_BIT <= ((MAX_UINTN - 1) / 2) - (OC_CHAR_BIT - 1), - "An overflow verification must be added" - ); - */ - // - // Considering NumBits can at most be MAX_UINT16 * OC_CHAR_BIT, this cannot - // overflow. OC_CHAR_BIT-1 is added to achieve rounding towards the next Byte - // boundary. - // - SizeRSqr = ALIGN_VALUE ( - ((2 * (NumBits + 1) + (OC_CHAR_BIT - 1)) / OC_CHAR_BIT), - OC_BN_WORD_SIZE - ); - if (SizeRSqr > OC_BN_MAX_SIZE) { - return 0; - } - - RSqr = AllocatePool (SizeRSqr); - if (RSqr == NULL) { - return 0; - } - NumWordsRSqr = (OC_BN_NUM_WORDS)(SizeRSqr / OC_BN_WORD_SIZE); - // - // Calculate Montgomery's R^2 mod N. - // - ZeroMem (RSqr, NumWordsRSqr * OC_BN_WORD_SIZE); - // - // 2 * NumBits cannot overflow as per above. - // - BigNumOrWord (RSqr, NumWordsRSqr, 1, 2 * NumBits); - BigNumMod (RSqrMod, NumWords, RSqr, NumWordsRSqr, N); - - FreePool (RSqr); - - return N0Inv; -} - -/** - Calculates the sum of C and the product of A and B. - - @param[out] Hi Buffer in which the high Word of the result is returned. - @param[in] C The addend. - @param[in] A The multiplicant. - @param[in] B The multiplier. - - @returns The low Word of the result. - -**/ -STATIC -OC_BN_WORD -BigNumWordAddMul ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD C, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ) -{ - OC_BN_WORD ResHi; - OC_BN_WORD ResLo; - - ASSERT (Hi != NULL); - - ResLo = BigNumWordMul (&ResHi, A, B) + C; - if (ResLo < C) { - ++ResHi; - } - - *Hi = ResHi; - return ResLo; -} - -/** - Calculates the sum of C, the product of A and B, and Carry. - - @param[out] Hi Buffer in which the high Word of the result is returned. - @param[in] C The addend. - @param[in] A The multiplicant. - @param[in] B The multiplier. - @param[in] Carry The carry of the previous multiplication. - - @returns The low Word of the result. - -**/ -STATIC -OC_BN_WORD -BigNumWordAddMulCarry ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD C, - IN OC_BN_WORD A, - IN OC_BN_WORD B, - IN OC_BN_WORD Carry - ) -{ - OC_BN_WORD MulResHi; - OC_BN_WORD MulResLo; - - ASSERT (Hi != NULL); - - MulResLo = BigNumWordAddMul (&MulResHi, C, A, B); - MulResLo += Carry; - if (MulResLo < Carry) { - ++MulResHi; - } - - *Hi = MulResHi; - return MulResLo; -} - -/** - Calculates a row of the product of A and B mod N. - - @param[in,out] Result The result buffer. - @param[in] NumWords The number of Words of Result, B and N. - @param[in] AWord The current row's Word of the multiplicant. - @param[in] B The multiplier. - @param[in] N The modulus. - @param[in] N0Inv The Montgomery Inverse of N. - -**/ -STATIC -VOID -BigNumMontMulRow ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN OC_BN_WORD AWord, - IN CONST OC_BN_WORD *B, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv - ) -{ - UINTN CompIndex; - - OC_BN_WORD CCurMulHi; - OC_BN_WORD CCurMulLo; - OC_BN_WORD CCurMontHi; - OC_BN_WORD CCurMontLo; - OC_BN_WORD TFirst; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (B != NULL); - ASSERT (N != NULL); - ASSERT (N0Inv != 0); - // - // Standard multiplication - // C = C + A*B - // - CCurMulLo = BigNumWordAddMul ( - &CCurMulHi, - Result[0], - AWord, - B[0] - ); - // - // Montgomery Reduction preparation - // As N_first is reduced mod 2^#Bits (word), we're operating in this domain - // and reduce both C and the result as well. - // t_first = C * N_first - // - TFirst = CCurMulLo * N0Inv; - // - // Montgomery Reduction - // 1. C = C + t_first * N - // 2. In the first step, only the carries are actually used, which implies - // division by R. - // - CCurMontLo = BigNumWordAddMul (&CCurMontHi, CCurMulLo, TFirst, N[0]); - - for (CompIndex = 1; CompIndex < NumWords; ++CompIndex) { - // - // Standard multiplication - // C = C + A*B + carry - // - CCurMulLo = BigNumWordAddMulCarry ( - &CCurMulHi, - Result[CompIndex], - AWord, - B[CompIndex], - CCurMulHi - ); - // - // Montgomery Reduction - // 1. C = C + t_first * N + carry - // - CCurMontLo = BigNumWordAddMulCarry ( - &CCurMontHi, - CCurMulLo, - TFirst, - N[CompIndex], - CCurMontHi - ); - // - // 2. The index shift translates to a bitshift equivalent to the division - // by R = 2^#Bits (word). - // C = C / R - // - Result[CompIndex - 1] = CCurMontLo; - } - // - // Assign the most significant byte the remaining carrys. - // - CCurMulLo = CCurMulHi + CCurMontHi; - Result[CompIndex - 1] = CCurMulLo; - // - // If the result has wrapped around, C >= N is true and we reduce mod N. - // - if (CCurMulLo < CCurMulHi) { - // - // The discarded most significant word must be the last borrow of the - // subtraction, as C_actual = (CCurMul >> WORD_BITS)||C. - // - BigNumSub (Result, NumWords, Result, N); - } -} - -/** - Calculates the Montgomery product of A and B mod N. - - @param[in,out] Result The result buffer. - @param[in] NumWords The number of Words of Result, A, B and N. - @param[in] A The multiplicant. - @param[in] B The multiplier. - @param[in] N The modulus. - @param[in] N0Inv The Montgomery Inverse of N. - -**/ -STATIC -VOID -BigNumMontMul ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN CONST OC_BN_WORD *B, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv - ) -{ - UINTN RowIndex; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (A != NULL); - ASSERT (B != NULL); - ASSERT (N != NULL); - ASSERT (N0Inv != 0); - - ZeroMem (Result, (UINTN)NumWords * OC_BN_WORD_SIZE); - // - // RowIndex is used as an index into the words of A. Because this domain - // operates in mod 2^#Bits (word), 'row results' do not require multiplication - // as the positional factor is stripped by the word-size modulus. - // - for (RowIndex = 0; RowIndex < NumWords; ++RowIndex) { - BigNumMontMulRow (Result, NumWords, A[RowIndex], B, N, N0Inv); - } - // - // As this implementation only reduces mod N on overflow and not for every - // yes-instance of C >= N, any sequence of Montgomery Multiplications must be - // completed with a final reduction step. - // -} - -/** - This is an optimized version of the call - BigNumMontMulRow (C, 0, A, N, N0Inv) - - Calculates a row of the product of 0 and A mod N. - - @param[in,out] Result The result buffer. - @param[in] NumWords The number of Words of Result and N. - @param[in] N The modulus. - @param[in] N0Inv The Montgomery Inverse of N. - -**/ -STATIC -VOID -BigNumMontMulRow0 ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv - ) -{ - UINTN CompIndex; - - OC_BN_WORD CCurMontHi; - OC_BN_WORD CCurMontLo; - OC_BN_WORD TFirst; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (N != NULL); - ASSERT (N0Inv != 0); - // - // Montgomery Reduction preparation - // As N_first is reduced mod 2^#Bits (word), we reduce C as well. - // Due to the reduction, the high bits are discarded safely. - // t_first = C * N_first - // - TFirst = Result[0] * N0Inv; - // - // Montgomery Reduction - // 1. C = C + t_first * N - // 2. In the first step, only the carries are actually used, so the - // division by R can be omited. - // - CCurMontLo = BigNumWordAddMul (&CCurMontHi, Result[0], TFirst, N[0]); - for (CompIndex = 1; CompIndex < NumWords; ++CompIndex) { - // - // Montgomery Reduction - // 1. C = C + t_first * N + carry - // - CCurMontLo = BigNumWordAddMulCarry ( - &CCurMontHi, - Result[CompIndex], - TFirst, - N[CompIndex], - CCurMontHi - ); - // - // 2. The index shift translates to a bitshift equivalent to the division - // by R = 2^#Bits (word). - // C = C / R - // - Result[CompIndex - 1] = CCurMontLo; - } - // - // Assign the most significant byte the remaining carry. - // - Result[CompIndex - 1] = CCurMontHi; -} - -/** - This is an optimized version of the call - BigNumMontMul (C, 1, A, N, N0Inv) - - @param[in,out] Result The result buffer. - @param[in] NumWords The number of Words of Result, A and N. - @param[in] A The multiplicant. - @param[in] N The modulus. - @param[in] N0Inv The Montgomery Inverse of N. - -**/ -STATIC -VOID -BigNumMontMul1 ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv - ) -{ - UINTN RowIndex; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (A != NULL); - ASSERT (N != NULL); - ASSERT (N0Inv != 0); - - ZeroMem (Result, (UINTN)NumWords * OC_BN_WORD_SIZE); - // - // Perform the entire standard multiplication and one Montgomery Reduction. - // - BigNumMontMulRow (Result, NumWords, 1, A, N, N0Inv); - // - // Perform the remaining Montgomery Reductions. - // - for (RowIndex = 1; RowIndex < NumWords; ++RowIndex) { - BigNumMontMulRow0 (Result, NumWords, N, N0Inv); - } - // - // As this implementation only reduces mod N on overflow and not for every - // yes-instance of C >= N, any sequence of Montgomery Multiplications must be - // completed with a final reduction step. - // -} - -BOOLEAN -BigNumPowMod ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN UINT32 B, - IN CONST OC_BN_WORD *N, - IN OC_BN_WORD N0Inv, - IN CONST OC_BN_WORD *RSqrMod - ) -{ - OC_BN_WORD *ATmp; - - UINTN Index; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (A != NULL); - ASSERT (N != NULL); - ASSERT (N0Inv != 0); - ASSERT (RSqrMod != NULL); - // - // Currently, only the most frequent exponents are supported. - // - if (B != 0x10001 && B != 3) { - DEBUG ((DEBUG_INFO, "OCCR: Unsupported exponent: %x\n", B)); - return FALSE; - } - - ATmp = AllocatePool ((UINTN)NumWords * OC_BN_WORD_SIZE); - if (ATmp == NULL) { - DEBUG ((DEBUG_INFO, "OCCR: Memory allocation failure in ModPow\n")); - return FALSE; - } - // - // Convert A into the Montgomery Domain. - // ATmp = MM (A, R^2 mod N) - // - BigNumMontMul (ATmp, NumWords, A, RSqrMod, N, N0Inv); - - if (B == 0x10001) { - // - // Squaring the intermediate results 16 times yields A'^ (2^16). - // - for (Index = 0; Index < 16; Index += 2) { - // - // Result = MM (ATmp, ATmp) - // - BigNumMontMul (Result, NumWords, ATmp, ATmp, N, N0Inv); - // - // ATmp = MM (Result, Result) - // - BigNumMontMul (ATmp, NumWords, Result, Result, N, N0Inv); - } - // - // Because A is not within the Montgomery Domain, this implies another - // division by R, which takes the result out of the Montgomery Domain. - // C = MM (ATmp, A) - // - BigNumMontMul (Result, NumWords, ATmp, A, N, N0Inv); - } else { - // - // Result = MM (ATmp, ATmp) - // - BigNumMontMul (Result, NumWords, ATmp, ATmp, N, N0Inv); - // - // ATmp = MM (Result, ATmp) - // - BigNumMontMul (ATmp, NumWords, Result, ATmp, N, N0Inv); - // - // Perform a Montgomery Multiplication with 1, which effectively is a - // division by R, taking the result out of the Montgomery Domain. - // C = MM (ATmp, 1) - // TODO: Is this needed or can we just multiply with A above? - // - BigNumMontMul1 (Result, NumWords, ATmp, N, N0Inv); - } - // - // The Montgomery Multiplications above only ensure the result is mod N when - // it does not fit within #Bits(N). For N != 0, which is an obvious - // requirement, #Bits(N) can only ever fit values smaller than 2*N, so the - // result is at most one modulus too large. - // C = C mod N - // - if (BigNumCmp (Result, NumWords, N) >= 0){ - BigNumSub (Result, NumWords, Result, N); - } - - FreePool (ATmp); - return TRUE; -} diff --git a/Library/OcCryptoLib/BigNumPrimitives.c b/Library/OcCryptoLib/BigNumPrimitives.c deleted file mode 100644 index f1bab9b1e..000000000 --- a/Library/OcCryptoLib/BigNumPrimitives.c +++ /dev/null @@ -1,801 +0,0 @@ -/** - This library performs unsigned arbitrary precision arithmetic operations. - All results are returned into caller-provided buffers. The caller is - responsible to ensure the buffers can hold a value of the precision it - desires. Too large results will be truncated without further notification for - public APIs. - - https://github.com/kokke/tiny-bignum-c has served as a template for several - algorithmic ideas. - - This code is not to be considered general-purpose but solely to support - cryptographic operations such as RSA encryption. As such, there are arbitrary - limitations, such as requirement of equal precision, to limit the complexity - of the operations to the bare minimum required to support such use caes. - - SECURITY: Currently, no security measures have been taken. This code is - vulnerable to both timing and side channel attacks for value - leakage. However, its current purpose is the verification of public - binaries with public certificates, for which this is perfectly - acceptable, especially in regards to performance. - - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include -#include - -#include "BigNumLibInternal.h" - -#define OC_BN_MAX_VAL ((OC_BN_WORD)0U - 1U) -/* -STATIC_ASSERT ( - OC_BN_WORD_SIZE == sizeof (UINT32) || OC_BN_WORD_SIZE == sizeof (UINT64), - "OC_BN_WORD_SIZE and OC_BN_WORD_NUM_BITS usages must be adapted." - ); -*/ -OC_BN_WORD -BigNumSwapWord ( - IN OC_BN_WORD Word - ) -{ - if (OC_BN_WORD_SIZE == sizeof (UINT32)) { - return (OC_BN_WORD)SwapBytes32 ((UINT32)Word); - } - - if (OC_BN_WORD_SIZE == sizeof (UINT64)) { - return (OC_BN_WORD)SwapBytes64 ((UINT64)Word); - } - - ASSERT (FALSE); -} - -/** - Shifts A left by Exponent Words. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in,out] A The number to be word-shifted. - @param[in] NumWordsA The number of Words of A. - @param[in] Exponent The Word shift exponent. - -**/ -STATIC -VOID -BigNumLeftShiftWords ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN Exponent - ) -{ - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - ASSERT (Exponent < NumWordsResult); - ASSERT (NumWordsResult - Exponent >= NumWordsA); - - CopyMem (&Result[Exponent], A, (NumWordsResult - Exponent) * OC_BN_WORD_SIZE); - ZeroMem (Result, Exponent * OC_BN_WORD_SIZE); - if (NumWordsResult - Exponent > NumWordsA) { - ZeroMem ( - &Result[NumWordsA + Exponent], - (NumWordsResult - Exponent - NumWordsA) * OC_BN_WORD_SIZE - ); - } -} - -/** - Shifts A left by Exponent Bits for 0 < Exponent < #Bits(Word). - Result must have the exact precision to carry the result. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in] A The base. - @param[in] NumWordsA The number of Words of A. - @param[in] NumWords The Word shift exponent. - @param[in] NumBits The Bit shift exponent. - -**/ -STATIC -VOID -BigNumLeftShiftWordsAndBits ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN NumWords, - IN UINT8 NumBits - ) -{ - UINTN Index; - - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - ASSERT (NumWordsResult == NumWordsA + NumWords + 1); - // - // NumBits must not be 0 because a shift of a Word by its Bit width or - // larger is Undefined Behaviour. - // - ASSERT (NumBits > 0); - ASSERT (NumBits < OC_BN_WORD_NUM_BITS); - // - // This is not an algorithmic requirement, but BigNumLeftShiftWords shall be - // called if TRUE. - // - ASSERT (NumWords > 0); - - for (Index = (NumWordsA - 1); Index > 0; --Index) { - Result[Index + NumWords] = (A[Index] << NumBits) | (A[Index - 1] >> (OC_BN_WORD_NUM_BITS - NumBits)); - } - // - // Handle the edge-cases at the beginning and the end of the value. - // - Result[NumWords] = A[0] << NumBits; - Result[NumWordsA + NumWords] = A[NumWordsA - 1] >> (OC_BN_WORD_NUM_BITS - NumBits); - // - // Zero everything outside of the previously set ranges. - // - ZeroMem (Result, NumWords * OC_BN_WORD_SIZE); -} - -/** - Calculates the left-shift of A by Exponent Bits. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in] A The number to shift. - @param[in] NumWordsA The number of Words of A. - @param[in] Exponent The amount of Bits to shift by. - -**/ -STATIC -VOID -BigNumLeftShift ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN Exponent - ) -{ - UINTN NumWords; - UINT8 NumBits; - - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - - NumWords = Exponent / OC_BN_WORD_NUM_BITS; - NumBits = Exponent % OC_BN_WORD_NUM_BITS; - - if (NumBits != 0) { - BigNumLeftShiftWordsAndBits ( - Result, - NumWordsResult, - A, - NumWordsA, - NumWords, - NumBits - ); - } else { - BigNumLeftShiftWords (Result, NumWordsResult, A, NumWordsA, NumWords); - } -} - -/** - Shifts A right by Exponent Words. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in,out] A The number to be word-shifted. - @param[in] NumWordsA The number of Words of A. - @param[in] Exponent The Word shift exponent. - -**/ -STATIC -VOID -BigNumRightShiftWords ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN Exponent - ) -{ - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - ASSERT (Exponent < NumWordsResult); - ASSERT (NumWordsResult - Exponent >= NumWordsA); - - CopyMem (Result, &A[Exponent], (NumWordsResult - Exponent) * OC_BN_WORD_SIZE); - ZeroMem (&Result[NumWordsResult - Exponent], Exponent * OC_BN_WORD_SIZE); -} - -/** - Shifts A right by Exponent Bits for 0 < Exponent < #Bits(Word). - - @param[in,out] A The base. - @param[in] NumWords The number of Words of A. - @param[in] Exponent The Bit shift exponent. - -**/ -STATIC -VOID -BigNumRightShiftBitsSmall ( - IN OUT OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords, - IN UINT8 Exponent - ) -{ - UINTN Index; - - ASSERT (A != NULL); - ASSERT (NumWords > 0); - // - // Exponent must not be 0 because a shift of a Word by its Bit width or - // larger is Undefined Behaviour. - // - ASSERT (Exponent > 0); - ASSERT (Exponent < OC_BN_WORD_NUM_BITS); - - for (Index = 0; Index < (NumWords - 1U); ++Index) { - A[Index] = (A[Index] >> Exponent) | (A[Index + 1] << (OC_BN_WORD_NUM_BITS - Exponent)); - } - A[Index] >>= Exponent; -} - -/** - Shifts A right by Exponent Bits for 0 < Exponent < #Bits(Word). - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in] A The base. - @param[in] NumWordsA The number of Words of A. - @param[in] NumWords The Word shift exponent. - @param[in] NumBits The Bit shift exponent. - -**/ -STATIC -VOID -BigNumRightShiftWordsAndBits ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN NumWords, - IN UINT8 NumBits - ) -{ - UINTN Index; - - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - ASSERT (NumWordsA >= NumWords); - // - // NumBits must not be 0 because a shift of a Word by its Bit width or - // larger is Undefined Behaviour. - // - ASSERT (NumBits > 0); - ASSERT (NumBits < OC_BN_WORD_NUM_BITS); - // - // This, assuming below, is required to avoid overflows, which purely - // internal calls should never produce. - // - ASSERT (NumWordsA - NumWords >= NumWordsResult); - // - // This is not an algorithmic requirement, but BigNumRightShiftWords shall be - // called if FALSE. - // - //ASSERT (NumWords > 0); - - for (Index = NumWords; Index < (UINTN) (NumWordsA - 1); ++Index) { - Result[Index - NumWords] = (A[Index] >> NumBits) | (A[Index + 1] << (OC_BN_WORD_NUM_BITS - NumBits)); - } - // - // Handle the edge-cases at the beginning and the end of the value. - // - Result[Index - NumWords] = (A[NumWordsA - 1] >> NumBits); - // - // Zero everything outside of the previously set ranges. - // - ZeroMem (&Result[Index - NumWords + 1], (NumWordsResult - (Index - NumWords + 1)) * OC_BN_WORD_SIZE); -} - -/** - Calculates the right-shift of A by Exponent Bits. - - @param[in,out] Result The buffer to return the result into. - @param[in] NumWordsResult The number of Words of Result. - @param[in] A The number to shift. - @param[in] NumWordsA The number of Words of A. - @param[in] Exponent The amount of Bits to shift by. - -**/ -STATIC -VOID -BigNumRightShift ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsResult, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN UINTN Exponent - ) -{ - UINTN NumWords; - UINT8 NumBits; - - ASSERT (Result != NULL); - ASSERT (NumWordsResult > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - - NumWords = Exponent / OC_BN_WORD_NUM_BITS; - NumBits = Exponent % OC_BN_WORD_NUM_BITS; - - if (NumBits != 0) { - BigNumRightShiftWordsAndBits ( - Result, - NumWordsResult, - A, - NumWordsA, - NumWords, - NumBits - ); - } else { - BigNumRightShiftWords (Result, NumWordsResult, A, NumWordsA, NumWords); - } -} - -/** - Calculates the product of A and B. - - @param[out] Hi Buffer in which the high Word of the result is returned. - @param[in] A The multiplicant. - @param[in] B The multiplier. - - @returns The low Word of the result. - -**/ -OC_BN_WORD -BigNumWordMul ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ) -{ - UINT64 Result64; - - ASSERT (Hi != NULL); - - if (OC_BN_WORD_SIZE == sizeof (UINT32)) { - Result64 = (UINT64)A * B; - // - // FIXME: The subtraction in the shift is a dirty hack to shut up MSVC. - // - *Hi = (OC_BN_WORD)(RShiftU64 (Result64, OC_BN_WORD_NUM_BITS)); - return (OC_BN_WORD)Result64; - } - - if (OC_BN_WORD_SIZE == sizeof (UINT64)) { - return BigNumWordMul64 (Hi, A, B); - } -} - -VOID -BigNumSub ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *A, - IN CONST OC_BN_WORD *B - ) -{ - OC_BN_WORD TmpResult; - OC_BN_WORD Tmp1; - OC_BN_WORD Tmp2; - UINTN Index; - UINT8 Borrow; - - ASSERT (Result != NULL); - ASSERT (NumWords > 0); - ASSERT (A != NULL); - ASSERT (B != NULL); - // - // As only the same indices are ever accessed at a step, it is safe to call - // this function with Result = A or Result = B. - // - Borrow = 0; - for (Index = 0; Index < NumWords; ++Index) { - Tmp1 = A[Index]; - Tmp2 = B[Index] + Borrow; - TmpResult = (Tmp1 - Tmp2); - // - // When a subtraction wraps around, the result must be bigger than either - // operand. - // - Borrow = (Tmp2 < Borrow) | (Tmp1 < TmpResult); - Result[Index] = TmpResult; - } -} - -/** - Returns the number of significant bits in a Word. - - @param[in] Word The word to gather the number of significant bits of. - - @returns The number of significant bits in Word. - -**/ -STATIC -UINT8 -BigNumSignificantBitsWord ( - IN OC_BN_WORD Word - ) -{ - UINT8 NumBits; - OC_BN_WORD Mask; - // - // The values we are receiving are very likely large, thus this approach - // should be reasonably fast. - // - NumBits = OC_BN_WORD_NUM_BITS; - Mask = (OC_BN_WORD)1U << (OC_BN_WORD_NUM_BITS - 1); - while (Mask != 0 && (Word & Mask) == 0) { - --NumBits; - Mask >>= 1U; - } - - return NumBits; -} - -/** - Returns the most significant word index of A. - - @param[in] A The number to gather the most significant Word index of. - @param[in] NumWords The number of Words of A. - - @returns The index of the most significant Word in A. - -**/ -STATIC -OC_BN_NUM_WORDS -BigNumMostSignificantWord ( - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords - ) -{ - OC_BN_NUM_WORDS Index; - - ASSERT (A != NULL); - ASSERT (NumWords > 0); - - Index = NumWords; - do { - --Index; - if (A[Index] != 0) { - return Index; - } - } while (Index != 0); - - return 0; -} - -OC_BN_NUM_BITS -BigNumSignificantBits ( - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords - ) -{ - OC_BN_NUM_BITS Index; - - ASSERT (A != NULL); - ASSERT (NumWords > 0); - - Index = BigNumMostSignificantWord (A, NumWords); - return ((Index * OC_BN_WORD_NUM_BITS) + BigNumSignificantBitsWord (A[Index])); -} - -VOID -BigNumOrWord ( - IN OUT OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords, - IN OC_BN_WORD Value, - IN UINTN Exponent - ) -{ - UINTN WordIndex; - UINT8 NumBits; - - ASSERT (A != NULL); - ASSERT (NumWords > 0); - ASSERT (Exponent / OC_BN_WORD_NUM_BITS < NumWords); - - WordIndex = Exponent / OC_BN_WORD_NUM_BITS; - if (WordIndex < NumWords) { - NumBits = Exponent % OC_BN_WORD_NUM_BITS; - A[WordIndex] |= (Value << NumBits); - } -} - -INTN -BigNumCmp ( - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWords, - IN CONST OC_BN_WORD *B - ) -{ - UINTN Index; - - ASSERT (A != NULL); - ASSERT (NumWords > 0); - ASSERT (B != NULL); - - Index = NumWords; - do { - --Index; - if (A[Index] > B[Index]) { - return 1; - } else if (A[Index] < B[Index]) { - return -1; - } - } while (Index != 0); - - return 0; -} - -BOOLEAN -BigNumMod ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWordsRest, - IN CONST OC_BN_WORD *A, - IN OC_BN_NUM_WORDS NumWordsA, - IN CONST OC_BN_WORD *B - ) -{ - INTN CmpResult; - - VOID *Memory; - - OC_BN_WORD *ModTmp; - OC_BN_NUM_BITS SigBitsModTmp; - OC_BN_NUM_WORDS SigWordsModTmp; - - OC_BN_NUM_BITS BigDivExp; - OC_BN_WORD *BigDiv; - OC_BN_NUM_BITS SigBitsBigDiv; - OC_BN_NUM_WORDS SigWordsBigDiv; - - OC_BN_NUM_BITS DeltaBits; - - ASSERT (Result != NULL); - ASSERT (NumWordsRest > 0); - ASSERT (A != NULL); - ASSERT (NumWordsA > 0); - ASSERT (B != NULL); - ASSERT (NumWordsA >= NumWordsRest); - // - // SigBitsModTmp is calculated manually to avoid calculating SigWordsModTmp - // by modulo. - // - SigWordsModTmp = BigNumMostSignificantWord (A, NumWordsA); - SigBitsModTmp = SigWordsModTmp * OC_BN_WORD_NUM_BITS + BigNumSignificantBitsWord (A[SigWordsModTmp]); - ++SigWordsModTmp; - /* - ASSERT (SigBitsModTmp == BigNumSignificantBits (A, SigWordsModTmp)); - - STATIC_ASSERT ( - OC_BN_MAX_SIZE <= MAX_UINTN / 2, - "An overflow verification must be added" - ); -*/ - Memory = AllocatePool (2 * SigWordsModTmp * OC_BN_WORD_SIZE); - if (Memory == NULL) { - return FALSE; - } - - ModTmp = Memory; - BigDiv = &ModTmp[SigWordsModTmp]; - SigWordsBigDiv = SigWordsModTmp; - // - // Invariant: BigDiv > ModTmp / 2 - // The invariant implies ModTmp / BigDiv <= 1 (latter in the strictest case). - // - // This loop iteratively subtracts multiples BigDiv of B from ModTmp := A [1], - // otherwise ModTmp is not modified. BigDiv is iteratively reduced such that - // ModTmp >= BigDiv [2]. The loop terminates once BigDiv < B yields true [3]. - // - CopyMem (ModTmp, A, SigWordsModTmp * OC_BN_WORD_SIZE); - // - // Initialisation: - // A bit-shift by x is equal to multiplying the operand with 2^x. - // BigDiv := B << x so that its MSB is equal to the MSB of A implies: - // 2*BigDiv > A <=> BigDiv > ModTmp / 2 with ModTmp = A. - // - SigBitsBigDiv = BigNumSignificantBits (B, NumWordsRest); - ASSERT (SigBitsModTmp >= SigBitsBigDiv); - BigDivExp = SigBitsModTmp - SigBitsBigDiv; - - BigNumLeftShift (BigDiv, SigWordsBigDiv, B, NumWordsRest, BigDivExp); - SigBitsBigDiv = SigBitsModTmp; - ASSERT (SigBitsBigDiv == BigNumSignificantBits (BigDiv, SigWordsBigDiv)); - - while (TRUE) { - // - // Because the invariant is maintained optimally, the MSB of BigDiv is - // either the MSB of ModTmp or one below. SigWords* are maintained - // precisely during the loop's execution, so when SigWordsModTmp is larger - // than SigWordsBigDiv, ModTmp is larger than BigDiv. - // - ASSERT (SigWordsModTmp == SigWordsBigDiv || SigWordsModTmp == SigWordsBigDiv + 1); - if (SigWordsModTmp > SigWordsBigDiv) { - ASSERT (ModTmp[SigWordsModTmp - 1] != 0); - CmpResult = 1; - } else { - CmpResult = BigNumCmp (ModTmp, SigWordsBigDiv, BigDiv); - } - - if (CmpResult >= 0) { - // - // Iteration 1: [1] ModTmp >= BigDiv means ModTmp is reduced. - // - // Subtract SigWordsModTmp words because the current divisor value may be - // shorter than the current modulus value. As both reside in buffers of - // equal length and no high word is stripped without being set to 0, this - // is safe. - // - BigNumSub (ModTmp, SigWordsModTmp, ModTmp, BigDiv); - - if (BigDivExp == 0) { - // - // Iteration 1: [3] BigDiv = B implies BigDiv < B would yield true - // after executing the reduction below. - // - ASSERT (BigNumCmp (BigDiv, SigWordsBigDiv, B) == 0); - break; - } - // - // SigBitsModTmp is calculated manually to avoid calculating - // SigWordsModTmp by modulo. - // - SigWordsModTmp = BigNumMostSignificantWord (ModTmp, SigWordsModTmp); - SigBitsModTmp = SigWordsModTmp * OC_BN_WORD_NUM_BITS + BigNumSignificantBitsWord (ModTmp[SigWordsModTmp]); - ++SigWordsModTmp; - ASSERT (SigBitsModTmp == BigNumSignificantBits (ModTmp, SigWordsModTmp)); - - ASSERT (SigBitsBigDiv >= SigBitsModTmp); - DeltaBits = SigBitsBigDiv - SigBitsModTmp; - if (DeltaBits > BigDivExp) { - // - // Iteration 1: [3] This implies BigDiv < B would yield true after - // executing the reduction below. - // - break; - } - // - // Iteration 1: [2] Please refer to Initialisation. - // - BigNumRightShift (BigDiv, SigWordsBigDiv, BigDiv, SigWordsBigDiv, DeltaBits); - - SigWordsBigDiv = (OC_BN_NUM_WORDS) ((SigBitsModTmp + (OC_BN_WORD_NUM_BITS - 1U)) / OC_BN_WORD_NUM_BITS); - SigBitsBigDiv = SigBitsModTmp; - - BigDivExp -= DeltaBits; - } else { - // - // Iteration 2: [1] BigDiv > ModTmp means ModTmp will be reduced next - // iteration. - // - if (BigDivExp == 0) { - // - // Iteration 2: [3] BigDiv = B implies BigDiv < B would yield true - // after executing the reduction below. - // - ASSERT (BigNumCmp (BigDiv, SigWordsBigDiv, B) == 0); - break; - } - // - // Iteration 2: [2] BigDiv > ModTmp means BigDiv is reduced to more - // strictly maintain the invariant BigDiv / 2 > ModTmp. - // - BigNumRightShiftBitsSmall (BigDiv, SigWordsBigDiv, 1); - - --SigBitsBigDiv; - --BigDivExp; - - if (SigBitsBigDiv % OC_BN_WORD_NUM_BITS == 0) { - // - // Every time the subtraction by 1 yields a multiplie of the word - // length, the most significant Byte has become zero and is stripped. - // - ASSERT (BigDiv[SigWordsBigDiv - 1] == 0); - --SigWordsBigDiv; - } - } - // - // ASSERT both branches maintain SigBitsBigDiv correctly. - // - ASSERT (SigBitsBigDiv == BigNumSignificantBits (BigDiv, SigWordsBigDiv)); - } - // - // Termination: - // Because BigDiv = B and, by invariant, BigDiv > ModTmp / 2 are true in the - // last iteration, B > ModTmp / 2 <=> 2 * B > ModTmp is true and thus - // conditionally subtracting B from ModTmp once more yields B > ModTmp, at - // which point ModTmp must carry the modulus of A / B. The final reduction - // of BigDiv yields BigDiv < B and thus the loop is terminated without - // further effects. - // - - // - // Assuming correctness, the modulus cannot be larger than the divisor. - // - ASSERT (BigNumMostSignificantWord (ModTmp, SigWordsModTmp) + 1 <= NumWordsRest); - CopyMem (Result, ModTmp, NumWordsRest * OC_BN_WORD_SIZE); - - FreePool (Memory); - return TRUE; -} - -VOID -BigNumParseBuffer ( - IN OUT OC_BN_WORD *Result, - IN OC_BN_NUM_WORDS NumWords, - IN CONST UINT8 *Buffer, - IN UINTN BufferSize - ) -{ - UINTN Index; - OC_BN_WORD Tmp; - - ASSERT (Result != NULL); - ASSERT (NumWords * OC_BN_WORD_SIZE == BufferSize); - ASSERT (Buffer != NULL); - ASSERT (BufferSize > 0); - ASSERT ((BufferSize % OC_BN_WORD_SIZE) == 0); - - for (Index = OC_BN_WORD_SIZE; Index <= BufferSize; Index += OC_BN_WORD_SIZE) { - if (OC_BN_WORD_SIZE == sizeof (UINT32)) { - Tmp = (OC_BN_WORD)( - ((UINT32)Buffer[(BufferSize - Index) + 0] << 24U) | - ((UINT32)Buffer[(BufferSize - Index) + 1] << 16U) | - ((UINT32)Buffer[(BufferSize - Index) + 2] << 8U) | - ((UINT32)Buffer[(BufferSize - Index) + 3] << 0U)); - } else if (OC_BN_WORD_SIZE == sizeof (UINT64)) { - Tmp = (OC_BN_WORD)( - ((UINT64)Buffer[(BufferSize - Index) + 0] << 56U) | - ((UINT64)Buffer[(BufferSize - Index) + 1] << 48U) | - ((UINT64)Buffer[(BufferSize - Index) + 2] << 40U) | - ((UINT64)Buffer[(BufferSize - Index) + 3] << 32U) | - ((UINT64)Buffer[(BufferSize - Index) + 4] << 24U) | - ((UINT64)Buffer[(BufferSize - Index) + 5] << 16U) | - ((UINT64)Buffer[(BufferSize - Index) + 6] << 8U) | - ((UINT64)Buffer[(BufferSize - Index) + 7] << 0U)); - } - - Result[(Index / OC_BN_WORD_SIZE) - 1] = Tmp; - } -} diff --git a/Library/OcCryptoLib/ChaCha.c b/Library/OcCryptoLib/ChaCha.c deleted file mode 100644 index 0b5424f55..000000000 --- a/Library/OcCryptoLib/ChaCha.c +++ /dev/null @@ -1,249 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2020, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -/* - chacha-merged.c version 20080118 - D. J. Bernstein - Public domain. - */ - -#include -#include -#include - -#define U32V(v) ((UINT32)(v) & 0xFFFFFFFFU) -#define ROTATE(v, c) (LRotU32 ((v), (c))) -#define XOR(v, w) ((v) ^ (w)) -#define PLUS(v, w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v), 1)) -#define LOAD32_LE(a) (ReadUnaligned32 ((UINT32 *)(a))) -#define STORE32_LE(a, v) (WriteUnaligned32 ((UINT32 *)(a), (v))) - -#define QUARTERROUND(a, b, c, d) \ - a = PLUS(a, b); \ - d = ROTATE(XOR(d, a), 16); \ - c = PLUS(c, d); \ - b = ROTATE(XOR(b, c), 12); \ - a = PLUS(a, b); \ - d = ROTATE(XOR(d, a), 8); \ - c = PLUS(c, d); \ - b = ROTATE(XOR(b, c), 7); - -VOID -ChaChaInitCtx ( - OUT CHACHA_CONTEXT *Context, - IN CONST UINT8 *Key, - IN CONST UINT8 *Iv, - IN UINT32 Counter - ) -{ - Context->Input[0] = 0x61707865U; - Context->Input[1] = 0x3320646EU; - Context->Input[2] = 0x79622d32U; - Context->Input[3] = 0x6B206574U; - Context->Input[4] = LOAD32_LE (Key + 0); - Context->Input[5] = LOAD32_LE (Key + 4); - Context->Input[6] = LOAD32_LE (Key + 8); - Context->Input[7] = LOAD32_LE (Key + 12); - Context->Input[8] = LOAD32_LE (Key + 16); - Context->Input[9] = LOAD32_LE (Key + 20); - Context->Input[10] = LOAD32_LE (Key + 24); - Context->Input[11] = LOAD32_LE (Key + 28); - Context->Input[12] = Counter; - Context->Input[13] = LOAD32_LE (Iv + 0); - Context->Input[14] = LOAD32_LE (Iv + 4); - Context->Input[15] = LOAD32_LE (Iv + 8); -} - -VOID -ChaChaCryptBuffer ( - IN OUT CHACHA_CONTEXT *Context, - IN CONST UINT8 *Source, - OUT UINT8 *Destination, - IN UINT32 Length - ) -{ - UINT32 X0; - UINT32 X1; - UINT32 X2; - UINT32 X3; - UINT32 X4; - UINT32 X5; - UINT32 X6; - UINT32 X7; - UINT32 X8; - UINT32 X9; - UINT32 X10; - UINT32 X11; - UINT32 X12; - UINT32 X13; - UINT32 X14; - UINT32 X15; - UINT32 J0; - UINT32 J1; - UINT32 J2; - UINT32 J3; - UINT32 J4; - UINT32 J5; - UINT32 J6; - UINT32 J7; - UINT32 J8; - UINT32 J9; - UINT32 J10; - UINT32 J11; - UINT32 J12; - UINT32 J13; - UINT32 J14; - UINT32 J15; - UINT8 *Ctarget; - UINT8 Tmp[64]; - UINT32 Index; - - Ctarget = NULL; - - if (Length == 0) { - return; - } - - J0 = Context->Input[0]; - J1 = Context->Input[1]; - J2 = Context->Input[2]; - J3 = Context->Input[3]; - J4 = Context->Input[4]; - J5 = Context->Input[5]; - J6 = Context->Input[6]; - J7 = Context->Input[7]; - J8 = Context->Input[8]; - J9 = Context->Input[9]; - J10 = Context->Input[10]; - J11 = Context->Input[11]; - J12 = Context->Input[12]; - J13 = Context->Input[13]; - J14 = Context->Input[14]; - J15 = Context->Input[15]; - - while (TRUE) { - if (Length < sizeof (Tmp)) { - CopyMem (Tmp, Source, Length); - ZeroMem (Tmp + Length, sizeof (Tmp) - Length); - Source = Tmp; - Ctarget = Destination; - Destination = Tmp; - } - - X0 = J0; - X1 = J1; - X2 = J2; - X3 = J3; - X4 = J4; - X5 = J5; - X6 = J6; - X7 = J7; - X8 = J8; - X9 = J9; - X10 = J10; - X11 = J11; - X12 = J12; - X13 = J13; - X14 = J14; - X15 = J15; - - for (Index = 20; Index > 0; Index -= 2) { - QUARTERROUND (X0, X4, X8, X12) - QUARTERROUND (X1, X5, X9, X13) - QUARTERROUND (X2, X6, X10, X14) - QUARTERROUND (X3, X7, X11, X15) - QUARTERROUND (X0, X5, X10, X15) - QUARTERROUND (X1, X6, X11, X12) - QUARTERROUND (X2, X7, X8, X13) - QUARTERROUND (X3, X4, X9, X14) - } - - X0 = PLUS (X0, J0); - X1 = PLUS (X1, J1); - X2 = PLUS (X2, J2); - X3 = PLUS (X3, J3); - X4 = PLUS (X4, J4); - X5 = PLUS (X5, J5); - X6 = PLUS (X6, J6); - X7 = PLUS (X7, J7); - X8 = PLUS (X8, J8); - X9 = PLUS (X9, J9); - X10 = PLUS (X10, J10); - X11 = PLUS (X11, J11); - X12 = PLUS (X12, J12); - X13 = PLUS (X13, J13); - X14 = PLUS (X14, J14); - X15 = PLUS (X15, J15); - - X0 = XOR (X0, LOAD32_LE (Source + 0)); - X1 = XOR (X1, LOAD32_LE (Source + 4)); - X2 = XOR (X2, LOAD32_LE (Source + 8)); - X3 = XOR (X3, LOAD32_LE (Source + 12)); - X4 = XOR (X4, LOAD32_LE (Source + 16)); - X5 = XOR (X5, LOAD32_LE (Source + 20)); - X6 = XOR (X6, LOAD32_LE (Source + 24)); - X7 = XOR (X7, LOAD32_LE (Source + 28)); - X8 = XOR (X8, LOAD32_LE (Source + 32)); - X9 = XOR (X9, LOAD32_LE (Source + 36)); - X10 = XOR (X10, LOAD32_LE (Source + 40)); - X11 = XOR (X11, LOAD32_LE (Source + 44)); - X12 = XOR (X12, LOAD32_LE (Source + 48)); - X13 = XOR (X13, LOAD32_LE (Source + 52)); - X14 = XOR (X14, LOAD32_LE (Source + 56)); - X15 = XOR (X15, LOAD32_LE (Source + 60)); - - J12 = PLUSONE (J12); - - if (J12 == 0) { - J13 = PLUSONE (J13); - } - - STORE32_LE (Destination + 0, X0); - STORE32_LE (Destination + 4, X1); - STORE32_LE (Destination + 8, X2); - STORE32_LE (Destination + 12, X3); - STORE32_LE (Destination + 16, X4); - STORE32_LE (Destination + 20, X5); - STORE32_LE (Destination + 24, X6); - STORE32_LE (Destination + 28, X7); - STORE32_LE (Destination + 32, X8); - STORE32_LE (Destination + 36, X9); - STORE32_LE (Destination + 40, X10); - STORE32_LE (Destination + 44, X11); - STORE32_LE (Destination + 48, X12); - STORE32_LE (Destination + 52, X13); - STORE32_LE (Destination + 56, X14); - STORE32_LE (Destination + 60, X15); - - if (Length <= sizeof (Tmp)) { - if (Length < sizeof (Tmp)) { - CopyMem (Ctarget, Destination, Length); - } - - Context->Input[12] = J12; - Context->Input[13] = J13; - - return; - } - - Length -= sizeof (Tmp); - Destination += sizeof (Tmp); - Source += sizeof (Tmp); - } -} diff --git a/Library/OcCryptoLib/Ia32/BigNumWordMul64.c b/Library/OcCryptoLib/Ia32/BigNumWordMul64.c deleted file mode 100644 index 480ae2529..000000000 --- a/Library/OcCryptoLib/Ia32/BigNumWordMul64.c +++ /dev/null @@ -1,64 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#include - -#include -#include - -#include "../BigNumLib.h" - -OC_BN_WORD -BigNumWordMul64 ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ) -{ - ASSERT (OC_BN_WORD_SIZE == sizeof (UINT64)); - ASSERT (Hi != NULL); - // - // This is to be used when the used compiler lacks support for both the - // __int128 type and a suiting intrinsic to perform the calculation. - // - // Source: https://stackoverflow.com/a/31662911 - // - CONST OC_BN_WORD SubWordShift = OC_BN_WORD_NUM_BITS / 2; - CONST OC_BN_WORD SubWordMask = ((OC_BN_WORD)1U << SubWordShift) - 1; - - OC_BN_WORD ALo; - OC_BN_WORD AHi; - OC_BN_WORD BLo; - OC_BN_WORD BHi; - - OC_BN_WORD P0; - OC_BN_WORD P1; - OC_BN_WORD P2; - OC_BN_WORD P3; - - OC_BN_WORD Cy; - - ALo = A & SubWordMask; - AHi = A >> SubWordShift; - BLo = B & SubWordMask; - BHi = B >> SubWordShift; - - P0 = ALo * BLo; - P1 = ALo * BHi; - P2 = AHi * BLo; - P3 = AHi * BHi; - - Cy = (((P0 >> SubWordShift) + (P1 & SubWordMask) + (P2 & SubWordMask)) >> SubWordShift) & SubWordMask; - - *Hi = P3 + (P1 >> SubWordShift) + (P2 >> SubWordShift) + Cy; - return P0 + (P1 << SubWordShift) + (P2 << SubWordShift); -} diff --git a/Library/OcCryptoLib/Md5.c b/Library/OcCryptoLib/Md5.c deleted file mode 100644 index 97eacb5f5..000000000 --- a/Library/OcCryptoLib/Md5.c +++ /dev/null @@ -1,237 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2018, savvas - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -/********************************************************************* -* Filename: md5.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Implementation of the MD5 hashing algorithm. - Algorithm specification can be found here: - * http://tools.ietf.org/html/rfc1321 - This implementation uses little endian byte order. -*********************************************************************/ - -#include -#include - -#define ROTLEFT(A,B) ((A << B) | (A >> (32 - B))) - -#define F(X,Y,Z) ((X & Y) | (~X & Z)) -#define G(X,Y,Z) ((X & Z) | (Y & ~Z)) -#define H(X,Y,Z) (X ^ Y ^ Z) -#define I(X,Y,Z) (Y ^ (X | ~Z)) - -#define FF(A,B,C,D,M,S,T) do { A += F(B,C,D) + M + T; \ - A = B + ROTLEFT(A,S); } while (0) -#define GG(A,B,C,D,M,S,T) do { A += G(B,C,D) + M + T; \ - A = B + ROTLEFT(A,S); } while (0) -#define HH(A,B,C,D,M,S,T) do { A += H(B,C,D) + M + T; \ - A = B + ROTLEFT(A,S); } while (0) -#define II(A,B,C,D,M,S,T) do { A += I(B,C,D) + M + T; \ - A = B + ROTLEFT(A,S); } while (0) -VOID -Md5Transform ( - MD5_CONTEXT *Ctx, - CONST UINT8 *Data - ) -{ - UINT32 A, B, C, D, M[16], Index1, Index2; - - // - // MD5 specifies big endian byte order, but this implementation assumes a little - // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them - // on output (in md5_final()). - // - for (Index1 = 0, Index2 = 0; Index1 < 16; ++Index1, Index2 += 4) { - M[Index1] = (Data[Index2]) + (Data[Index2 + 1] << 8) - + (Data[Index2 + 2] << 16) + (Data[Index2 + 3] << 24); - } - A = Ctx->State[0]; - B = Ctx->State[1]; - C = Ctx->State[2]; - D = Ctx->State[3]; - - FF (A, B, C, D, M[0], 7, 0xD76AA478); - FF (D, A, B, C, M[1], 12, 0xE8C7B756); - FF (C, D, A, B, M[2], 17, 0x242070DB); - FF (B, C, D, A, M[3], 22, 0xC1BDCEEE); - FF (A, B, C, D, M[4], 7, 0xF57C0FAF); - FF (D, A, B, C, M[5], 12, 0x4787C62A); - FF (C, D, A, B, M[6], 17, 0xA8304613); - FF (B, C, D, A, M[7], 22, 0xFD469501); - FF (A, B, C, D, M[8], 7, 0x698098D8); - FF (D, A, B, C, M[9], 12, 0x8B44F7AF); - FF (C, D, A, B, M[10], 17, 0xFFFF5BB1); - FF (B, C, D, A, M[11], 22, 0x895CD7BE); - FF (A, B, C, D, M[12], 7, 0x6B901122); - FF (D, A, B, C, M[13], 12, 0xFD987193); - FF (C, D, A, B, M[14], 17, 0xA679438E); - FF (B, C, D, A, M[15], 22, 0x49B40821); - - GG (A, B, C, D, M[1], 5, 0xF61E2562); - GG (D, A, B, C, M[6], 9, 0xC040B340); - GG (C, D, A, B, M[11], 14, 0x265E5A51); - GG (B, C, D, A, M[0], 20, 0xE9B6C7AA); - GG (A, B, C, D, M[5], 5, 0xD62F105D); - GG (D, A, B, C, M[10], 9, 0x02441453); - GG (C, D, A, B, M[15], 14, 0xD8A1E681); - GG (B, C, D, A, M[4], 20, 0xE7D3FBC8); - GG (A, B, C, D, M[9], 5, 0x21E1CDE6); - GG (D, A, B, C, M[14], 9, 0xC33707D6); - GG (C, D, A, B, M[3], 14, 0xF4D50D87); - GG (B, C, D, A, M[8], 20, 0x455A14ED); - GG (A, B, C, D, M[13], 5, 0xA9E3E905); - GG (D, A, B, C, M[2], 9, 0xFCEFA3F8); - GG (C, D, A, B, M[7], 14, 0x676F02D9); - GG (B, C, D, A, M[12], 20, 0x8D2A4C8A); - - HH (A, B, C, D, M[5], 4, 0xFFFA3942); - HH (D, A, B, C, M[8], 11, 0x8771F681); - HH (C, D, A, B, M[11], 16, 0x6D9D6122); - HH (B, C, D, A, M[14], 23, 0xFDE5380C); - HH (A, B, C, D, M[1], 4, 0xA4BEEA44); - HH (D, A, B, C, M[4], 11, 0x4BDECFA9); - HH (C, D, A, B, M[7], 16, 0xF6BB4B60); - HH (B, C, D, A, M[10], 23, 0xBEBFBC70); - HH (A, B, C, D, M[13], 4, 0x289B7EC6); - HH (D, A, B, C, M[0], 11, 0xEAA127FA); - HH (C, D, A, B, M[3], 16, 0xD4EF3085); - HH (B, C, D, A, M[6], 23, 0x04881D05); - HH (A, B, C, D, M[9], 4, 0xD9D4D039); - HH (D, A, B, C, M[12], 11, 0xE6DB99E5); - HH (C, D, A, B, M[15], 16, 0x1FA27CF8); - HH (B, C, D, A, M[2], 23, 0xC4AC5665); - - II (A, B, C, D, M[0], 6, 0xF4292244); - II (D, A, B, C, M[7], 10, 0x432AFF97); - II (C, D, A, B, M[14], 15, 0xAB9423A7); - II (B, C, D, A, M[5], 21, 0xFC93A039); - II (A, B, C, D, M[12], 6, 0x655B59C3); - II (D, A, B, C, M[3], 10, 0x8F0CCC92); - II (C, D, A, B, M[10], 15, 0xFFEFF47D); - II (B, C, D, A, M[1], 21, 0x85845DD1); - II (A, B, C, D, M[8], 6, 0x6FA87E4F); - II (D, A, B, C, M[15], 10, 0xFE2CE6E0); - II (C, D, A, B, M[6], 15, 0xA3014314); - II (B, C, D, A, M[13], 21, 0x4E0811A1); - II (A, B, C, D, M[4], 6, 0xF7537E82); - II (D, A, B, C, M[11], 10, 0xBD3AF235); - II (C, D, A, B, M[2], 15, 0x2AD7D2BB); - II (B, C, D, A, M[9], 21, 0xEB86D391); - - Ctx->State[0] += A; - Ctx->State[1] += B; - Ctx->State[2] += C; - Ctx->State[3] += D; -} - -VOID -Md5Init ( - MD5_CONTEXT *Ctx - ) -{ - Ctx->DataLen = 0; - Ctx->BitLen = 0; - Ctx->State[0] = 0x67452301; - Ctx->State[1] = 0xEFCDAB89; - Ctx->State[2] = 0x98BADCFE; - Ctx->State[3] = 0x10325476; -} - -VOID -Md5Update ( - MD5_CONTEXT *Ctx, - CONST UINT8 *Data, - UINTN Len - ) -{ - UINTN Index; - - for (Index = 0; Index < Len; ++Index) { - Ctx->Data[Ctx->DataLen] = Data[Index]; - Ctx->DataLen++; - if (Ctx->DataLen == 64) { - Md5Transform (Ctx, Ctx->Data); - Ctx->BitLen += 512; - Ctx->DataLen = 0; - } - } -} - -VOID -Md5Final ( - MD5_CONTEXT *Ctx, - UINT8 *Hash - ) -{ - UINTN Index = Ctx->DataLen; - - // - // Pad whatever Data is left in the buffer. - // - if (Ctx->DataLen < 56) { - Ctx->Data[Index++] = 0x80; - ZeroMem (Ctx->Data + Index, 56-Index); - } else if (Ctx->DataLen >= 56) { - Ctx->Data[Index++] = 0x80; - ZeroMem (Ctx->Data + Index, 64-Index); - Md5Transform (Ctx, Ctx->Data); - ZeroMem (Ctx->Data, 56); - } - - // - // Append to the padding the total message's length in bits and transform. - // - Ctx->BitLen += Ctx->DataLen * 8; - Ctx->Data[56] = (UINT8) (Ctx->BitLen); - Ctx->Data[57] = (UINT8) (Ctx->BitLen >> 8); - Ctx->Data[58] = (UINT8) (Ctx->BitLen >> 16); - Ctx->Data[59] = (UINT8) (Ctx->BitLen >> 24); - Ctx->Data[60] = (UINT8) (Ctx->BitLen >> 32); - Ctx->Data[61] = (UINT8) (Ctx->BitLen >> 40); - Ctx->Data[62] = (UINT8) (Ctx->BitLen >> 48); - Ctx->Data[63] = (UINT8) (Ctx->BitLen >> 56); - Md5Transform (Ctx, Ctx->Data); - - // - // Since this implementation uses little endian byte ordering and MD uses big endian, - // reverse all the bytes when copying the final State to the output Hash. - // - for (Index = 0; Index < 4; ++Index) { - Hash[Index] = (UINT8) ((Ctx->State[0] >> (Index * 8)) & 0x000000FF); - Hash[Index + 4] = (UINT8) ((Ctx->State[1] >> (Index * 8)) & 0x000000FF); - Hash[Index + 8] = (UINT8) ((Ctx->State[2] >> (Index * 8)) & 0x000000FF); - Hash[Index + 12] = (UINT8) ((Ctx->State[3] >> (Index * 8)) & 0x000000FF); - } -} - -VOID -Md5 ( - UINT8 *Hash, - UINT8 *Data, - UINTN Len - ) -{ - MD5_CONTEXT Ctx; - - Md5Init (&Ctx); - Md5Update (&Ctx, Data, Len); - Md5Final (&Ctx,Hash); - SecureZeroMem (&Ctx, sizeof (Ctx)); -} diff --git a/Library/OcCryptoLib/OcCryptoLib.inf b/Library/OcCryptoLib/OcCryptoLib.inf deleted file mode 100644 index 63a036b64..000000000 --- a/Library/OcCryptoLib/OcCryptoLib.inf +++ /dev/null @@ -1,67 +0,0 @@ -## @file -# OcCryptoLib -# -# Copyright (c) 2017-2018, savvas -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcCryptoLib - FILE_GUID = 56C05E0A-52BB-4B16-B472-6A816E82E5AD - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcCryptoLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - Aes.c - ChaCha.c - Md5.c - RsaDigitalSign.c - Sha1.c - Sha2.c - SecureMem.c - PasswordHash.c - BigNumLib.h - BigNumLibInternal.h - BigNumPrimitives.c - BigNumMontgomery.c - ../../Include/Library/OcCryptoLib.h - -[Sources.Ia32] - Ia32/BigNumWordMul64.c - -[Sources.X64] - X64/BigNumWordMul64.c - -[FixedPcd] - gOpenCorePkgTokenSpaceGuid.PcdOcCryptoAllowedRsaModuli - gOpenCorePkgTokenSpaceGuid.PcdOcCryptoAllowedSigHashTypes - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - UefiRuntimeServicesTableLib - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - BaseLib - UefiLib diff --git a/Library/OcCryptoLib/PasswordHash.c b/Library/OcCryptoLib/PasswordHash.c deleted file mode 100644 index 0407856ac..000000000 --- a/Library/OcCryptoLib/PasswordHash.c +++ /dev/null @@ -1,94 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include - -VOID -OcHashPasswordSha512 ( - IN CONST UINT8 *Password, - IN UINT32 PasswordSize, - IN CONST UINT8 *Salt, - IN UINT32 SaltSize, - OUT UINT8 *Hash - ) -{ - UINT32 Index; - SHA512_CONTEXT ShaContext; - - ASSERT (Password != NULL); - ASSERT (PasswordSize > 0); - ASSERT (Hash != NULL); - - Sha512Init (&ShaContext); - Sha512Update (&ShaContext, Password, PasswordSize); - Sha512Update (&ShaContext, Salt, SaltSize); - Sha512Final (&ShaContext, Hash); - // - // The hash function is applied iteratively to slow down bruteforce attacks. - // The iteration count has been chosen to take roughly three seconds on - // modern hardware. - // - for (Index = 0; Index < 5000000; ++Index) { - Sha512Init (&ShaContext); - Sha512Update (&ShaContext, Hash, SHA512_DIGEST_SIZE); - // - // Password and Salt are re-added into hashing to, in case of a hash - // collision, again yield a unique hash in the subsequent iteration. - // - Sha512Update (&ShaContext, Password, PasswordSize); - Sha512Update (&ShaContext, Salt, SaltSize); - Sha512Final (&ShaContext, Hash); - } - SecureZeroMem (&ShaContext, sizeof (ShaContext)); -} - -/** - Verify Password and Salt against RefHash. The used hash function is SHA-512, - thus the caller must ensure RefHash is at least 64 bytes in size. - - @param[in] Password The entered password to verify. - @param[in] PasswordSize The size, in bytes, of Password. - @param[in] Salt The cryptographic salt appended to Password on hash. - @param[in] SaltSize The size, in bytes, of Salt. - @param[in] RefHash The SHA-512 hash of the reference password and Salt. - - @returns Whether Password and Salt cryptographically match RefHash. - -**/ -BOOLEAN -OcVerifyPasswordSha512 ( - IN CONST UINT8 *Password, - IN UINT32 PasswordSize, - IN CONST UINT8 *Salt, - IN UINT32 SaltSize, - IN CONST UINT8 *RefHash - ) -{ - BOOLEAN Result; - UINT8 VerifyHash[SHA512_DIGEST_SIZE]; - - ASSERT (Password != NULL); - ASSERT (PasswordSize > 0); - ASSERT (RefHash != NULL); - - OcHashPasswordSha512 (Password, PasswordSize, Salt, SaltSize, VerifyHash); - Result = SecureCompareMem (RefHash, VerifyHash, SHA512_DIGEST_SIZE) == 0; - SecureZeroMem (VerifyHash, SHA512_DIGEST_SIZE); - - return Result; -} diff --git a/Library/OcCryptoLib/RsaDigitalSign.c b/Library/OcCryptoLib/RsaDigitalSign.c deleted file mode 100644 index 38d0b41d2..000000000 --- a/Library/OcCryptoLib/RsaDigitalSign.c +++ /dev/null @@ -1,623 +0,0 @@ -/** @file - This library performs RSA-based cryptography operations. - - SECURITY: Currently, no security measures have been taken. This code is - vulnerable to both timing and side channel attacks for value - leakage. However, its current purpose is the verification of public - binaries with public certificates, for which this is perfectly - acceptable, especially in regards to performance. - - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "BigNumLib.h" - -// -// RFC 3447, 9.2 EMSA-PKCS1-v1_5, Notes 1. -// -STATIC CONST UINT8 mPkcsDigestEncodingPrefixSha256[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 -}; - -STATIC CONST UINT8 mPkcsDigestEncodingPrefixSha384[] = { - 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 -}; - -STATIC CONST UINT8 mPkcsDigestEncodingPrefixSha512[] = { - 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, - 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 -}; - -/** - Returns whether the RSA modulus size is allowed. - - @param[in] ModulusSize The size, in bytes, of the RSA modulus. - -**/ -STATIC -BOOLEAN -InternalRsaModulusSizeIsAllowed ( - IN UINTN ModulusSize - ) -{ - // - // Verify ModulusSize is a two's potency. - // - if ((ModulusSize & (ModulusSize - 1U)) != 0) { - return FALSE; - } - - return (PcdGet16 (PcdOcCryptoAllowedRsaModuli) & ModulusSize) != 0; -} - -/** - Returns whether the signature hashing algorithm is allowed. - - @param[in] Type The signature hashing algorithm type. - -**/ -STATIC -BOOLEAN -InternalSigHashTypeIsAllowed ( - IN OC_SIG_HASH_TYPE Type - ) -{ - return (PcdGet16 (PcdOcCryptoAllowedSigHashTypes) & (1U << Type)) != 0; -} - -INTN -SigVerifyShaHashBySize ( - IN CONST VOID *Data, - IN UINTN DataSize, - IN CONST UINT8 *Hash, - IN UINTN HashSize - ) -{ - OC_SIG_HASH_TYPE Hashtype; - UINT8 DataDigest[OC_MAX_SHA_DIGEST_SIZE]; - - ASSERT (Data != NULL); - ASSERT (DataSize > 0); - ASSERT (Hash != NULL); - ASSERT (HashSize > 0); - ASSERT (HashSize <= sizeof (DataDigest)); - - switch (HashSize) { - case SHA512_DIGEST_SIZE: - { - Hashtype = OcSigHashTypeSha512; - Sha512 (DataDigest, Data, DataSize); - break; - } - - case SHA384_DIGEST_SIZE: - { - Hashtype = OcSigHashTypeSha384; - Sha384 (DataDigest, Data, DataSize); - break; - } - - case SHA256_DIGEST_SIZE: - { - Hashtype = OcSigHashTypeSha256; - Sha256 (DataDigest, Data, DataSize); - break; - } - - default: - { - return -1; - } - } - - if (!InternalSigHashTypeIsAllowed (Hashtype)) { - return -1; - } - - return CompareMem (DataDigest, Hash, HashSize); -} - -/** - Verify a RSA PKCS1.5 signature against an expected hash. - - @param[in] N The RSA modulus. - @param[in] N0Inv The Montgomery Inverse of N. - @param[in] RSqrMod Montgomery's R^2 mod N. - @param[in] NumWords The number of Words of N and RSqrMod. - @param[in] Exponent The RSA exponent. - @param[in] Signature The RSA signature to be verified. - @param[in] SignatureSize Size, in bytes, of Signature. - @param[in] Hash The Hash digest of the signed data. - @param[in] HashSize Size, in bytes, of Hash. - @param[in] Algorithm The RSA algorithm used. - - @returns Whether the signature has been successfully verified as valid. - -**/ -STATIC -BOOLEAN -RsaVerifySigHashFromProcessed ( - IN CONST OC_BN_WORD *N, - IN UINTN NumWords, - IN OC_BN_WORD N0Inv, - IN CONST OC_BN_WORD *RSqrMod, - IN UINT32 Exponent, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Hash, - IN UINTN HashSize, - IN OC_SIG_HASH_TYPE Algorithm - ) -{ - BOOLEAN Result; - INTN CmpResult; - - UINTN ModulusSize; - - VOID *Memory; - OC_BN_WORD *EncryptedSigNum; - OC_BN_WORD *DecryptedSigNum; - - CONST UINT8 *Padding; - UINTN PaddingSize; - UINTN DigestSize; - UINTN Index; - - OC_BN_WORD Tmp; -/* - ASSERT (N != NULL); - ASSERT (NumWords > 0); - ASSERT (RSqrMod != NULL); - ASSERT (Signature != NULL); - ASSERT (SignatureSize > 0); - ASSERT (Hash != NULL); - ASSERT (HashSize > 0); - - STATIC_ASSERT ( - OcSigHashTypeSha512 == OcSigHashTypeMax - 1, - "New switch cases have to be added for every introduced algorithm." - ); -*/ - if (NumWords > OC_BN_MAX_LEN) { - return FALSE; - } - - if (!InternalSigHashTypeIsAllowed (Algorithm)) { - return FALSE; - } - - switch (Algorithm) { - case OcSigHashTypeSha256: - { - ASSERT (HashSize == SHA256_DIGEST_SIZE); - - Padding = mPkcsDigestEncodingPrefixSha256; - PaddingSize = sizeof (mPkcsDigestEncodingPrefixSha256); - break; - } - - case OcSigHashTypeSha384: - { - ASSERT (HashSize == SHA384_DIGEST_SIZE); - - Padding = mPkcsDigestEncodingPrefixSha384; - PaddingSize = sizeof (mPkcsDigestEncodingPrefixSha384); - break; - } - - case OcSigHashTypeSha512: - { - ASSERT (HashSize == SHA512_DIGEST_SIZE); - - Padding = mPkcsDigestEncodingPrefixSha512; - PaddingSize = sizeof (mPkcsDigestEncodingPrefixSha512); - break; - } - - default: - { - ASSERT (FALSE); - Padding = NULL; - PaddingSize = 0; - } - } - // - // Verify the Signature size matches the Modulus size. - // This implicitly verifies it's a multiple of the Word size. - // - ModulusSize = NumWords * OC_BN_WORD_SIZE; - if (!InternalRsaModulusSizeIsAllowed (ModulusSize)) { - return FALSE; - } - - if (SignatureSize != ModulusSize) { - DEBUG ((DEBUG_INFO, "OCCR: Signature length does not match key length")); - return FALSE; - } - - Memory = AllocatePool (2 * ModulusSize); - if (Memory == NULL) { - DEBUG ((DEBUG_INFO, "OCCR: Memory allocation failure\n")); - return FALSE; - } - - EncryptedSigNum = Memory; - DecryptedSigNum = (OC_BN_WORD *)((UINTN)EncryptedSigNum + ModulusSize); - - BigNumParseBuffer ( - EncryptedSigNum, - (OC_BN_NUM_WORDS)NumWords, - Signature, - SignatureSize - ); - - Result = BigNumPowMod ( - DecryptedSigNum, - (OC_BN_NUM_WORDS)NumWords, - EncryptedSigNum, - Exponent, - N, - N0Inv, - RSqrMod - ); - if (!Result) { - FreePool (Memory); - return FALSE; - } - // - // Convert the result to a big-endian byte array. - // Re-use EncryptedSigNum as it is not required anymore. - // FIXME: Doing this as part of the comparison could speed up the process - // and clean up the code. - // - Index = NumWords; - while (Index > 0) { - --Index; - Tmp = BigNumSwapWord ( - DecryptedSigNum[NumWords - 1 - Index] - ); - EncryptedSigNum[Index] = Tmp; - } - Signature = (UINT8 *)EncryptedSigNum; - - // - // From RFC 3447, 9.2 EMSA-PKCS1-v1_5: - // - // 5. Concatenate PS, the DER encoding T, and other padding to form the - // encoded message EM as - // - // EM = 0x00 || 0x01 || PS || 0x00 || T. - // - - // - // 3. If emLen < tLen + 11, output "intended encoded message length too - // short" and stop. - // - // The additions cannot overflow because both PaddingSize and HashSize are - // sane at this point. - // - DigestSize = PaddingSize + HashSize; - if (SignatureSize < DigestSize + 11) { - FreePool (Memory); - return FALSE; - } - - if (Signature[0] != 0x00 || Signature[1] != 0x01) { - FreePool (Memory); - return FALSE; - } - // - // 4. Generate an octet string PS consisting of emLen - tLen - 3 octets with - // hexadecimal value 0xff. The length of PS will be at least 8 octets. - // - // The additions and subtractions cannot overflow as per 3. - // - for (Index = 2; Index < SignatureSize - DigestSize - 3 + 2; ++Index) { - if (Signature[Index] != 0xFF) { - FreePool (Memory); - return FALSE; - } - } - - if (Signature[Index] != 0x00) { - FreePool (Memory); - return FALSE; - } - - ++Index; - - CmpResult = CompareMem (&Signature[Index], Padding, PaddingSize); - if (CmpResult != 0) { - FreePool (Memory); - return FALSE; - } - - Index += PaddingSize; - - CmpResult = CompareMem (&Signature[Index], Hash, HashSize); - if (CmpResult != 0) { - FreePool (Memory); - return FALSE; - } - // - // The code above must have covered the entire Signature range. - // - ASSERT (Index + HashSize == SignatureSize); - - FreePool (Memory); - return TRUE; -} - -/** - Verify RSA PKCS1.5 signed data against its signature. - The modulus' size must be a multiple of the configured BIGNUM word size. - This will be true for any conventional RSA, which use two's potencies. - - @param[in] N The RSA modulus. - @param[in] NumWords The number of Words of N and RSqrMod. - @param[in] N0Inv The Montgomery Inverse of N. - @param[in] RSqrMod Montgomery's R^2 mod N. - @param[in] Exponent The RSA exponent. - @param[in] Signature The RSA signature to be verified. - @param[in] SignatureSize Size, in bytes, of Signature. - @param[in] Data The signed data to verify. - @param[in] DataSize Size, in bytes, of Data. - @param[in] Algorithm The RSA algorithm used. - - @returns Whether the signature has been successfully verified as valid. - -**/ -STATIC -BOOLEAN -RsaVerifySigDataFromProcessed ( - IN CONST OC_BN_WORD *N, - IN OC_BN_NUM_WORDS NumWords, - IN OC_BN_WORD N0Inv, - IN CONST OC_BN_WORD *RSqrMod, - IN UINT32 Exponent, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Data, - IN UINTN DataSize, - IN OC_SIG_HASH_TYPE Algorithm - ) -{ - UINT8 Hash[OC_MAX_SHA_DIGEST_SIZE]; - UINTN HashSize; -/* - ASSERT (N != NULL); - ASSERT (NumWords > 0); - ASSERT (RSqrMod != NULL); - ASSERT (Exponent > 0); - ASSERT (Signature != NULL); - ASSERT (SignatureSize > 0); - ASSERT (Data != NULL); - ASSERT (DataSize > 0); - - STATIC_ASSERT ( - OcSigHashTypeSha512 == OcSigHashTypeMax - 1, - "New switch cases have to be added for every introduced algorithm." - ); -*/ - switch (Algorithm) { - case OcSigHashTypeSha256: - { - Sha256 (Hash, Data, DataSize); - HashSize = SHA256_DIGEST_SIZE; - break; - } - - case OcSigHashTypeSha384: - { - Sha384 (Hash, Data, DataSize); - HashSize = SHA384_DIGEST_SIZE; - break; - } - - case OcSigHashTypeSha512: - { - Sha512 (Hash, Data, DataSize); - HashSize = SHA512_DIGEST_SIZE; - break; - } - - default: - { - // - // New switch cases have to be added for every introduced algorithm. - // - ASSERT (FALSE); - return FALSE; - } - } - - return RsaVerifySigHashFromProcessed ( - N, - NumWords, - N0Inv, - RSqrMod, - Exponent, - Signature, - SignatureSize, - Hash, - HashSize, - Algorithm - ); -} - -BOOLEAN -RsaVerifySigDataFromData ( - IN CONST UINT8 *Modulus, - IN UINTN ModulusSize, - IN UINT32 Exponent, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Data, - IN UINTN DataSize, - IN OC_SIG_HASH_TYPE Algorithm - ) -{ - UINTN ModulusNumWordsTmp; - OC_BN_NUM_WORDS ModulusNumWords; - - VOID *Memory; - OC_BN_WORD *N; - OC_BN_WORD *RSqrMod; - - OC_BN_WORD N0Inv; - BOOLEAN Result; -/* - ASSERT (Modulus != NULL); - ASSERT (ModulusSize > 0); - ASSERT (Exponent > 0); - ASSERT (Signature != NULL); - ASSERT (SignatureSize > 0); - ASSERT (Data != NULL); - ASSERT (DataSize > 0); -*/ - ModulusNumWordsTmp = ModulusSize / OC_BN_WORD_SIZE; - if (ModulusNumWordsTmp > OC_BN_MAX_LEN - || (ModulusSize % OC_BN_WORD_SIZE) != 0) { - return FALSE; - } - - ModulusNumWords = (OC_BN_NUM_WORDS)ModulusNumWordsTmp; -/* - STATIC_ASSERT ( - OC_BN_MAX_SIZE <= MAX_UINTN / 2, - "An overflow verification must be added" - ); -*/ - Memory = AllocatePool (2 * ModulusSize); - if (Memory == NULL) { - return FALSE; - } - - N = (OC_BN_WORD *)Memory; - RSqrMod = (OC_BN_WORD *)((UINTN)N + ModulusSize); - - BigNumParseBuffer (N, ModulusNumWords, Modulus, ModulusSize); - - N0Inv = BigNumCalculateMontParams (RSqrMod, ModulusNumWords, N); - if (N0Inv == 0) { - FreePool (Memory); - return FALSE; - } - - Result = RsaVerifySigDataFromProcessed ( - N, - ModulusNumWords, - N0Inv, - RSqrMod, - Exponent, - Signature, - SignatureSize, - Data, - DataSize, - Algorithm - ); - - FreePool (Memory); - return Result; -} - -BOOLEAN -RsaVerifySigHashFromKey ( - IN CONST OC_RSA_PUBLIC_KEY *Key, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Hash, - IN UINTN HashSize, - IN OC_SIG_HASH_TYPE Algorithm - ) -{ - /* - ASSERT (Key != NULL); - ASSERT (Signature != NULL); - ASSERT (SignatureSize > 0); - ASSERT (Hash != NULL); - ASSERT (HashSize > 0); - - STATIC_ASSERT ( - OC_BN_WORD_SIZE <= 8, - "The parentheses need to be changed to avoid truncation." - ); - */ - // - // When OC_BN_WORD is not UINT64, this violates the strict aliasing rule. - // However, due to packed-ness and byte order, this is perfectly safe. - // - return RsaVerifySigHashFromProcessed ( - (OC_BN_WORD *)Key->Data, - Key->Hdr.NumQwords * (8 / OC_BN_WORD_SIZE), - (OC_BN_WORD)Key->Hdr.N0Inv, - (OC_BN_WORD *)&Key->Data[Key->Hdr.NumQwords], - 0x10001, - Signature, - SignatureSize, - Hash, - HashSize, - Algorithm - ); -} - -BOOLEAN -RsaVerifySigDataFromKey ( - IN CONST OC_RSA_PUBLIC_KEY *Key, - IN CONST UINT8 *Signature, - IN UINTN SignatureSize, - IN CONST UINT8 *Data, - IN UINTN DataSize, - IN OC_SIG_HASH_TYPE Algorithm - ) -{ - /* - ASSERT (Key != NULL); - ASSERT (Signature != NULL); - ASSERT (SignatureSize > 0); - ASSERT (Data != NULL); - ASSERT (DataSize > 0); - - STATIC_ASSERT ( - OC_BN_WORD_SIZE <= 8, - "The parentheses need to be changed to avoid truncation." - ); - */ - // - // When OC_BN_WORD is not UINT64, this violates the strict aliasing rule. - // However, due to packed-ness and byte order, this is perfectly safe. - // - return RsaVerifySigDataFromProcessed ( - (OC_BN_WORD *)Key->Data, - Key->Hdr.NumQwords * (8 / OC_BN_WORD_SIZE), - (OC_BN_WORD)Key->Hdr.N0Inv, - (OC_BN_WORD *)&Key->Data[Key->Hdr.NumQwords], - 0x10001, - Signature, - SignatureSize, - Data, - DataSize, - Algorithm - ); -} diff --git a/Library/OcCryptoLib/SecureMem.c b/Library/OcCryptoLib/SecureMem.c deleted file mode 100644 index 53800f737..000000000 --- a/Library/OcCryptoLib/SecureMem.c +++ /dev/null @@ -1,95 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include - -INTN -SecureCompareMem ( - IN CONST VOID *DestinationBuffer, - IN CONST VOID *SourceBuffer, - IN UINTN Length - ) -{ - // - // Based on libsodium secure_memcmp function implementation. - // - UINTN Index; - // - // The loop variables are volatile to prevent compiler optimizations, such as - // security-hurting simplifications and intrinsics insertion. - // - volatile CONST UINT8 *volatile Destination; - volatile CONST UINT8 *volatile Source; - volatile UINT8 XorDiff; - - if (Length > 0) { - ASSERT (DestinationBuffer != NULL); - ASSERT (SourceBuffer != NULL); - ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) DestinationBuffer)); - ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) SourceBuffer)); - } - - Destination = (volatile CONST UINT8 *) DestinationBuffer; - Source = (volatile CONST UINT8 *) SourceBuffer; - - XorDiff = 0; - for (Index = 0; Index < Length; ++Index) { - // - // XOR is used to prevent comparison result based branches causing - // slightly different execution times. A XOR operation only yields 0 when - // both operands are equal. - // Do not break early on mismatch to not leak information about prefixes. - // The AND operation with 0xFFU is performed to have a result promotion to - // unsigned int rather than int to ensure a safe cast. - // - XorDiff |= (UINT8)((Destination[Index] ^ (Source[Index])) & 0xFFU); - } - // - // This is implemented as an arithmetic operation to have an uniform - // execution time for success and failure cases. - // - // For XorDiff = 0, the subtraction wraps around and leads to a value of - // UINT_MAX. All other values, as XorDiff is unsigned, must be greater than 0 - // and hence cannot wrap around. This means extracting bit 8 of the - // operation's result will always yield 1 for XorDiff = 0 and always yield 0 - // for XorDiff != 0. This is then cast to INTN, which is safe because it - // can only ever be 0 or 1, to finally yield the appropiate return value. - // - return ((INTN)(1U & ((XorDiff - 1U) >> 8U))) - 1; -} - -VOID * -SecureZeroMem ( - OUT VOID *Buffer, - IN UINTN Length - ) -{ - volatile UINT8 *Destination; - - if (Length == 0) { - return Buffer; - } - - ASSERT (Buffer != NULL); - ASSERT (Length <= (MAX_ADDRESS - (UINTN) Buffer + 1)); - - Destination = (volatile UINT8 *) Buffer; - - while (Length--) { - *Destination++ = 0; - } - - return Buffer; -} diff --git a/Library/OcCryptoLib/Sha1.c b/Library/OcCryptoLib/Sha1.c deleted file mode 100644 index 81065c112..000000000 --- a/Library/OcCryptoLib/Sha1.c +++ /dev/null @@ -1,198 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2018, savvas - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -/********************************************************************* -* Filename: sha1.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Implementation of the SHA1 hashing algorithm. - Algorithm specification can be found here: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf - This implementation uses little endian byte order. -*********************************************************************/ - -#include -#include - -#define ROTLEFT(a, b) ((a << b) | (a >> (32 - b))) - -VOID -Sha1Transform ( - SHA1_CONTEXT *Ctx, - CONST UINT8 *Data - ) -{ - UINT32 A, B, C, D, E, Index1, Index2, T, M[80]; - - for (Index1 = 0, Index2 = 0; Index1 < 16; ++Index1, Index2 += 4) { - M[Index1] = (Data[Index2] << 24) + (Data[Index2 + 1] << 16) - + (Data[Index2 + 2] << 8) + (Data[Index2 + 3]); - } - - for ( ; Index1 < 80; ++Index1) { - M[Index1] = (M[Index1 - 3] ^ M[Index1 - 8] ^ M[Index1 - 14] ^ M[Index1 - 16]); - M[Index1] = (M[Index1] << 1) | (M[Index1] >> 31); - } - - A = Ctx->State[0]; - B = Ctx->State[1]; - C = Ctx->State[2]; - D = Ctx->State[3]; - E = Ctx->State[4]; - - for (Index1 = 0; Index1 < 20; ++Index1) { - T = ROTLEFT (A, 5) + ((B & C) ^ (~B & D)) + E + Ctx->K[0] + M[Index1]; - E = D; - D = C; - C = ROTLEFT (B, 30); - B = A; - A = T; - } - for ( ; Index1 < 40; ++Index1) { - T = ROTLEFT (A, 5) + (B ^ C ^ D) + E + Ctx->K[1] + M[Index1]; - E = D; - D = C; - C = ROTLEFT (B, 30); - B = A; - A = T; - } - for ( ; Index1 < 60; ++Index1) { - T = ROTLEFT (A, 5) + ((B & C) ^ (B & D) ^ (C & D)) + E + Ctx->K[2] + M[Index1]; - E = D; - D = C; - C = ROTLEFT (B, 30); - B = A; - A = T; - } - for ( ; Index1 < 80; ++Index1) { - T = ROTLEFT (A, 5) + (B ^ C ^ D) + E + Ctx->K[3] + M[Index1]; - E = D; - D = C; - C = ROTLEFT (B, 30); - B = A; - A = T; - } - - Ctx->State[0] += A; - Ctx->State[1] += B; - Ctx->State[2] += C; - Ctx->State[3] += D; - Ctx->State[4] += E; -} - -VOID -Sha1Init ( - SHA1_CONTEXT *Ctx - ) -{ - Ctx->DataLen = 0; - Ctx->BitLen = 0; - Ctx->State[0] = 0x67452301; - Ctx->State[1] = 0xEFCDAB89; - Ctx->State[2] = 0x98BADCFE; - Ctx->State[3] = 0x10325476; - Ctx->State[4] = 0xC3D2E1F0; - Ctx->K[0] = 0x5A827999; - Ctx->K[1] = 0x6ED9EBA1; - Ctx->K[2] = 0x8F1BBCDC; - Ctx->K[3] = 0xCA62C1D6; -} - -VOID -Sha1Update ( - SHA1_CONTEXT *Ctx, - CONST UINT8 *Data, - UINTN Len - ) -{ - UINTN Index = 0; - - for (Index = 0; Index < Len; ++Index) { - Ctx->Data[Ctx->DataLen] = Data[Index]; - Ctx->DataLen++; - if (Ctx->DataLen == 64) { - Sha1Transform (Ctx, Ctx->Data); - Ctx->BitLen += 512; - Ctx->DataLen = 0; - } - } -} - -VOID -Sha1Final ( - SHA1_CONTEXT *Ctx, - UINT8 *Hash - ) -{ - UINT32 Index = Ctx->DataLen; - - // - // Pad whatever Data is left in the buffer. - // - if (Ctx->DataLen < 56) { - Ctx->Data[Index++] = 0x80; - ZeroMem (Ctx->Data + Index, 56-Index); - } else { - Ctx->Data[Index++] = 0x80; - ZeroMem (Ctx->Data + Index, 64-Index); - Sha1Transform (Ctx, Ctx->Data); - ZeroMem (Ctx->Data, 56); - } - - // - // Append to the padding the total message's length in bits and transform. - // - Ctx->BitLen += Ctx->DataLen * 8; - Ctx->Data[63] = (UINT8) (Ctx->BitLen); - Ctx->Data[62] = (UINT8) (Ctx->BitLen >> 8); - Ctx->Data[61] = (UINT8) (Ctx->BitLen >> 16); - Ctx->Data[60] = (UINT8) (Ctx->BitLen >> 24); - Ctx->Data[59] = (UINT8) (Ctx->BitLen >> 32); - Ctx->Data[58] = (UINT8) (Ctx->BitLen >> 40); - Ctx->Data[57] = (UINT8) (Ctx->BitLen >> 48); - Ctx->Data[56] = (UINT8) (Ctx->BitLen >> 56); - Sha1Transform (Ctx, Ctx->Data); - - // - // Since this implementation uses little endian byte ordering and MD uses big endian, - // reverse all the bytes when copying the final State to the output Hash. - // - for (Index = 0; Index < 4; ++Index) { - Hash[Index] = (UINT8) ((Ctx->State[0] >> (24 - Index * 8)) & 0x000000FF); - Hash[Index + 4] = (UINT8) ((Ctx->State[1] >> (24 - Index * 8)) & 0x000000FF); - Hash[Index + 8] = (UINT8) ((Ctx->State[2] >> (24 - Index * 8)) & 0x000000FF); - Hash[Index + 12] = (UINT8) ((Ctx->State[3] >> (24 - Index * 8)) & 0x000000FF); - Hash[Index + 16] = (UINT8) ((Ctx->State[4] >> (24 - Index * 8)) & 0x000000FF); - } -} - -VOID -Sha1 ( - UINT8 *Hash, - UINT8 *Data, - UINTN Len - ) -{ - SHA1_CONTEXT Ctx; - - Sha1Init (&Ctx); - Sha1Update (&Ctx, Data, Len); - Sha1Final (&Ctx,Hash); - SecureZeroMem (&Ctx, sizeof (Ctx)); -} diff --git a/Library/OcCryptoLib/Sha2.c b/Library/OcCryptoLib/Sha2.c deleted file mode 100644 index 305a9d1ab..000000000 --- a/Library/OcCryptoLib/Sha2.c +++ /dev/null @@ -1,606 +0,0 @@ -/** @file - -OcCryptoLib - -Copyright (c) 2018, savvas - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -/** -* Filename: sha256.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Implementation of the SHA-256 hashing algorithm. - SHA-256 is one of the three algorithms in the SHA2 - specification. The others, SHA-384 and SHA-512, are not - offered in this implementation. - Algorithm specification can be found here: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf - This implementation uses little endian byte order. -**/ - -#ifdef EFIAPI -#include -#include -#endif - -#include - - -#define UNPACK64(x, str) \ - do { \ - *((str) + 7) = (UINT8) (x); \ - *((str) + 6) = (UINT8) RShiftU64 ((x), 8); \ - *((str) + 5) = (UINT8) RShiftU64 ((x), 16); \ - *((str) + 4) = (UINT8) RShiftU64 ((x), 24); \ - *((str) + 3) = (UINT8) RShiftU64 ((x), 32); \ - *((str) + 2) = (UINT8) RShiftU64 ((x), 40); \ - *((str) + 1) = (UINT8) RShiftU64 ((x), 48); \ - *((str) + 0) = (UINT8) RShiftU64 ((x), 56); \ - } while(0) - -#define PACK64(str, x) \ - do { \ - *(x) = ((UINT64) *((str) + 7)) \ - | LShiftU64 (*((str) + 6), 8) \ - | LShiftU64 (*((str) + 5), 16) \ - | LShiftU64 (*((str) + 4), 24) \ - | LShiftU64 (*((str) + 3), 32) \ - | LShiftU64 (*((str) + 2), 40) \ - | LShiftU64 (*((str) + 1), 48) \ - | LShiftU64 (*((str) + 0), 56); \ - } while (0) - - -#define SHFR(a, b) (a >> b) -#define ROTLEFT(a, b) ((a << b) | (a >> ((sizeof(a) << 3) - b))) -#define ROTRIGHT(a, b) ((a >> b) | (a << ((sizeof(a) << 3) - b))) -#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) -#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -// -// Sha 256 -// -#define SHA256_EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22)) -#define SHA256_EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25)) -#define SHA256_SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ SHFR(x, 3)) -#define SHA256_SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ SHFR(x, 10)) - -// -// Sha 512 -// -#define SHA512_EP0(x) (ROTRIGHT(x, 28) ^ ROTRIGHT(x, 34) ^ ROTRIGHT(x, 39)) -#define SHA512_EP1(x) (ROTRIGHT(x, 14) ^ ROTRIGHT(x, 18) ^ ROTRIGHT(x, 41)) -#define SHA512_SIG0(x) (ROTRIGHT(x, 1) ^ ROTRIGHT(x, 8) ^ SHFR(x, 7)) -#define SHA512_SIG1(x) (ROTRIGHT(x, 19) ^ ROTRIGHT(x, 61) ^ SHFR(x, 6)) - -#define SHA512_SCR(Index) \ - do { \ - W[Index] = SHA512_SIG1(W[Index - 2]) + W[Index - 7] \ - + SHA512_SIG0(W[Index - 15]) + W[Index - 16]; \ - } while(0) - - - -STATIC CONST UINT32 SHA256_K[64] = { - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 -}; - - -STATIC UINT64 SHA512_K[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, - 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, - 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, - 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, - 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, - 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, - 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, - 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, - 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, - 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, - 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, - 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, - 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, - 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -// -// Sha 256 Init State -// -STATIC CONST UINT32 SHA256_H0[8] = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -}; - -// -// Sha 384 Init State -// -STATIC CONST UINT64 SHA384_H0[8] = { - 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, - 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, - 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, - 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL -}; - -// -// Sha 512 Init State -// -STATIC CONST UINT64 SHA512_H0[8] = { - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -// -// Sha 256 functions -// -VOID -Sha256Transform ( - SHA256_CONTEXT *Context, - CONST UINT8 *Data - ) -{ - UINT32 A, B, C, D, E, F, G, H, Index1, Index2, T1, T2; - UINT32 M[64]; - - for (Index1 = 0, Index2 = 0; Index1 < 16; Index1++, Index2 += 4) { - M[Index1] = ((UINT32)Data[Index2] << 24) - | ((UINT32)Data[Index2 + 1] << 16) - | ((UINT32)Data[Index2 + 2] << 8) - | ((UINT32)Data[Index2 + 3]); - } - - for ( ; Index1 < 64; ++Index1) { - M[Index1] = SHA256_SIG1 (M[Index1 - 2]) + M[Index1 - 7] - + SHA256_SIG0 (M[Index1 - 15]) + M[Index1 - 16]; - } - - A = Context->State[0]; - B = Context->State[1]; - C = Context->State[2]; - D = Context->State[3]; - E = Context->State[4]; - F = Context->State[5]; - G = Context->State[6]; - H = Context->State[7]; - - for (Index1 = 0; Index1 < 64; ++Index1) { - T1 = H + SHA256_EP1 (E) + CH (E, F, G) + SHA256_K[Index1] + M[Index1]; - T2 = SHA256_EP0 (A) + MAJ (A, B, C); - H = G; - G = F; - F = E; - E = D + T1; - D = C; - C = B; - B = A; - A = T1 + T2; - } - - Context->State[0] += A; - Context->State[1] += B; - Context->State[2] += C; - Context->State[3] += D; - Context->State[4] += E; - Context->State[5] += F; - Context->State[6] += G; - Context->State[7] += H; -} - -VOID -Sha256Init ( - SHA256_CONTEXT *Context - ) -{ - UINTN Index; - for (Index = 0; Index < 8; ++Index) { - Context->State[Index] = SHA256_H0[Index]; - } - Context->DataLen = 0; - Context->BitLen = 0; -} - -VOID -Sha256Update ( - SHA256_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ) -{ - UINT32 Index; - - for (Index = 0; Index < Len; ++Index) { - Context->Data[Context->DataLen] = Data[Index]; - Context->DataLen++; - if (Context->DataLen == 64) { - Sha256Transform (Context, Context->Data); - Context->BitLen += 512; - Context->DataLen = 0; - } - } -} - -VOID -Sha256Final ( - SHA256_CONTEXT *Context, - UINT8 *HashDigest - ) -{ - UINT32 Index = 0; - - Index = Context->DataLen; - - // - // Pad whatever data is left in the buffer. - // - if (Context->DataLen < 56) { - Context->Data[Index++] = 0x80; - ZeroMem (Context->Data + Index, 56-Index); - } else { - Context->Data[Index++] = 0x80; - ZeroMem (Context->Data + Index, 64-Index); - Sha256Transform (Context, Context->Data); - ZeroMem (Context->Data, 56); - } - - // - // Append to the padding the total Message's length in bits and transform. - // - Context->BitLen += Context->DataLen * 8; - Context->Data[63] = (UINT8) Context->BitLen; - Context->Data[62] = (UINT8) (Context->BitLen >> 8); - Context->Data[61] = (UINT8) (Context->BitLen >> 16); - Context->Data[60] = (UINT8) (Context->BitLen >> 24); - Context->Data[59] = (UINT8) (Context->BitLen >> 32); - Context->Data[58] = (UINT8) (Context->BitLen >> 40); - Context->Data[57] = (UINT8) (Context->BitLen >> 48); - Context->Data[56] = (UINT8) (Context->BitLen >> 56); - Sha256Transform (Context, Context->Data); - - // - // Since this implementation uses little endian byte ordering and SHA uses big endian, - // reverse all the bytes when copying the final State to the output hash. - // - for (Index = 0; Index < 4; ++Index) { - HashDigest[Index] = (UINT8) ((Context->State[0] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 4] = (UINT8) ((Context->State[1] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 8] = (UINT8) ((Context->State[2] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 12] = (UINT8) ((Context->State[3] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 16] = (UINT8) ((Context->State[4] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 20] = (UINT8) ((Context->State[5] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 24] = (UINT8) ((Context->State[6] >> (24 - Index * 8)) & 0x000000FF); - HashDigest[Index + 28] = (UINT8) ((Context->State[7] >> (24 - Index * 8)) & 0x000000FF); - } -} - -VOID -Sha256 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ) -{ - SHA256_CONTEXT Ctx; - - Sha256Init (&Ctx); - Sha256Update (&Ctx, Data, Len); - Sha256Final (&Ctx, Hash); - ZeroMem (&Ctx, sizeof (Ctx)); -} - - -// -// Sha 512 functions -// -VOID -Sha512Transform ( - SHA512_CONTEXT *Context, - CONST UINT8 *Data, - UINTN BlockNb - ) -{ - UINT64 W[80]; - UINT64 Wv[8]; - UINT64 T1; - UINT64 T2; - CONST UINT8 *SubBlock; - UINTN Index1; - UINTN Index2; - - for (Index1 = 0; Index1 < BlockNb; ++Index1) { - SubBlock = Data + (Index1 << 7); - - // - // Convert from big-endian byte order to host byte order - // - for (Index2 = 0; Index2 < 16; ++Index2) { - PACK64 (&SubBlock[Index2 << 3], &W[Index2]); - } - - // - // Initialize the 8 working registers - // - for (Index2 = 0; Index2 < 8; ++Index2) { - Wv[Index2] = Context->State[Index2]; - } - - for (Index2 = 0; Index2 < 80; ++Index2) { - // - // Prepare the message schedule - // - if (Index2 >= 16) { - SHA512_SCR (Index2); - } - - // - // Calculate T1 and T2 - // - T1 = Wv[7] + SHA512_EP1 (Wv[4]) - + CH (Wv[4], Wv[5], Wv[6]) + SHA512_K[Index2] - + W[Index2]; - - T2 = SHA512_EP0 (Wv[0]) + MAJ (Wv[0], Wv[1], Wv[2]); - - // - // Update the working registers - // - Wv[7] = Wv[6]; - Wv[6] = Wv[5]; - Wv[5] = Wv[4]; - Wv[4] = Wv[3] + T1; - Wv[3] = Wv[2]; - Wv[2] = Wv[1]; - Wv[1] = Wv[0]; - Wv[0] = T1 + T2; - } - // - // Update the hash value - // - for (Index2 = 0; Index2 < 8; ++Index2) { - Context->State[Index2] += Wv[Index2]; - } - } -} - -VOID -Sha512Init ( - SHA512_CONTEXT *Context - ) -{ - UINTN Index; - - // - // Set initial hash value - // - for (Index = 0; Index < 8; ++Index) { - Context->State[Index] = SHA512_H0[Index]; - } - - // - // Number of bytes in the buffer - // - Context->Length = 0; - - // - // Total length of the data - // - Context->TotalLength = 0; -} - -VOID -Sha512Update ( - SHA512_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ) -{ - UINTN BlockNb; - UINTN NewLen; - UINTN RemLen; - UINTN TmpLen; - CONST UINT8 *ShiftedMsg; - - TmpLen = SHA512_BLOCK_SIZE - Context->Length; - RemLen = Len < TmpLen ? Len : TmpLen; - - CopyMem (&Context->Block[Context->Length], Data, RemLen); - - if (Context->Length + Len < SHA512_BLOCK_SIZE) { - Context->Length += Len; - return; - } - - NewLen = Len - RemLen; - BlockNb = NewLen / SHA512_BLOCK_SIZE; - - ShiftedMsg = Data + RemLen; - - Sha512Transform (Context, Context->Block, 1); - Sha512Transform (Context, ShiftedMsg, BlockNb); - - RemLen = NewLen % SHA512_BLOCK_SIZE; - - CopyMem (Context->Block, &ShiftedMsg[BlockNb << 7], RemLen); - - Context->Length = RemLen; - Context->TotalLength += (BlockNb + 1) << 7; -} - -VOID -Sha512Final ( - SHA512_CONTEXT *Context, - UINT8 *HashDigest - ) -{ - UINTN BlockNb; - UINTN PmLen; - UINT64 LenB; - UINTN Index; - - BlockNb = ((SHA512_BLOCK_SIZE - 17) < (Context->Length % SHA512_BLOCK_SIZE)) + 1; - - LenB = (Context->TotalLength + Context->Length) << 3; - PmLen = BlockNb << 7; - - ZeroMem (Context->Block + Context->Length, PmLen - Context->Length); - Context->Block[Context->Length] = 0x80; - UNPACK64 (LenB, Context->Block + PmLen - 8); - - Sha512Transform (Context, Context->Block, BlockNb); - - for (Index = 0 ; Index < 8; ++Index) { - UNPACK64 (Context->State[Index], &HashDigest[Index << 3]); - } -} - -VOID -Sha512 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ) -{ - SHA512_CONTEXT Ctx; - - Sha512Init (&Ctx); - Sha512Update (&Ctx, Data, Len); - Sha512Final (&Ctx, Hash); - ZeroMem (&Ctx, sizeof (Ctx)); -} - - -// -// Sha 384 functions -// -VOID -Sha384Init ( - SHA384_CONTEXT *Context - ) -{ - UINTN Index; - - for (Index = 0; Index < 8; ++Index) { - Context->State[Index] = SHA384_H0[Index]; - } - - Context->Length = 0; - Context->TotalLength = 0; -} - -VOID -Sha384Update ( - SHA384_CONTEXT *Context, - CONST UINT8 *Data, - UINTN Len - ) -{ - UINTN BlockNb; - UINTN NewLen; - UINTN RemLen; - UINTN TmpLen; - CONST UINT8 *ShiftedMessage; - - TmpLen = SHA384_BLOCK_SIZE - Context->Length; - RemLen = Len < TmpLen ? Len : TmpLen; - - CopyMem (&Context->Block[Context->Length], Data, RemLen); - - if (Context->Length + Len < SHA384_BLOCK_SIZE) { - Context->Length += Len; - return; - } - - NewLen = Len - RemLen; - BlockNb = NewLen / SHA384_BLOCK_SIZE; - - ShiftedMessage = Data + RemLen; - - Sha512Transform (Context, Context->Block, 1); - Sha512Transform (Context, ShiftedMessage, BlockNb); - - RemLen = NewLen % SHA384_BLOCK_SIZE; - - CopyMem ( - Context->Block, - &ShiftedMessage[BlockNb << 7], - RemLen - ); - - Context->Length = RemLen; - Context->TotalLength += (BlockNb + 1) << 7; -} - -VOID -Sha384Final ( - SHA384_CONTEXT *Context, - UINT8 *HashDigest - ) -{ - UINTN BlockNb; - UINTN PmLen; - UINT64 LenB; - UINTN Index; - - BlockNb = ((SHA384_BLOCK_SIZE - 17) < (Context->Length % SHA384_BLOCK_SIZE)) + 1; - - LenB = (Context->TotalLength + Context->Length) << 3; - PmLen = BlockNb << 7; - - ZeroMem (Context->Block + Context->Length, PmLen - Context->Length); - - Context->Block[Context->Length] = 0x80; - UNPACK64 (LenB, Context->Block + PmLen - 8); - - Sha512Transform (Context, Context->Block, BlockNb); - - for (Index = 0 ; Index < 6; ++Index) { - UNPACK64 (Context->State[Index], &HashDigest[Index << 3]); - } -} - -VOID -Sha384 ( - UINT8 *Hash, - CONST UINT8 *Data, - UINTN Len - ) -{ - SHA384_CONTEXT Ctx; - - Sha384Init (&Ctx); - Sha384Update (&Ctx, Data, Len); - Sha384Final (&Ctx, Hash); - SecureZeroMem (&Ctx, sizeof (Ctx)); -} diff --git a/Library/OcCryptoLib/X64/BigNumWordMul64.c b/Library/OcCryptoLib/X64/BigNumWordMul64.c deleted file mode 100644 index 1e6a7a023..000000000 --- a/Library/OcCryptoLib/X64/BigNumWordMul64.c +++ /dev/null @@ -1,49 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#include - -#include -#include - -#include "../BigNumLib.h" - -#if defined(_MSC_VER) && !defined(__clang__) - #include - #pragma intrinsic(_umul128) -#endif - -OC_BN_WORD -BigNumWordMul64 ( - OUT OC_BN_WORD *Hi, - IN OC_BN_WORD A, - IN OC_BN_WORD B - ) -{ - ASSERT (OC_BN_WORD_SIZE == sizeof (UINT64)); - ASSERT (Hi != NULL); - -#if !defined(_MSC_VER) || defined(__clang__) - // - // Clang and GCC support the __int128 type for edk2 builds. - // - unsigned __int128 Result = (unsigned __int128)A * B; - *Hi = (OC_BN_WORD)(Result >> OC_BN_WORD_NUM_BITS); - return (OC_BN_WORD)Result; -#else - // - // MSVC does not support the __int128 type for edk2 builds, but a proprietary - // intrinsic function declared above. - // - return _umul128 (A, B, Hi); -#endif -} diff --git a/Library/OcDebugLogLib/DebugHelp.c b/Library/OcDebugLogLib/DebugHelp.c deleted file mode 100644 index 5804ab6a1..000000000 --- a/Library/OcDebugLogLib/DebugHelp.c +++ /dev/null @@ -1,65 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include -#include -#include - -VOID -#if defined(__GNUC__) || defined(__clang__) -__attribute__ ((noinline)) -#endif -DebugBreak ( - VOID - ) -{ - // - // This function has no code, debuggers may break on it. - // -} - -VOID -WaitForKeyPress ( - CONST CHAR16 *Message - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - volatile BOOLEAN Proceed; - - // - // Print message. - // - gST->ConOut->OutputString (gST->ConOut, (CHAR16 *) Message); - gST->ConOut->OutputString (gST->ConOut, (CHAR16 *) L"\r\n"); - - // - // Skip previously pressed characters. - // - do { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - } while (!EFI_ERROR(Status)); - - // - // Wait for debugger signal or key press. - // - Proceed = FALSE; - while (EFI_ERROR(Status) && !Proceed) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - DebugBreak (); - } -} diff --git a/Library/OcDebugLogLib/DebugPrint.c b/Library/OcDebugLogLib/DebugPrint.c deleted file mode 100644 index ecaf50514..000000000 --- a/Library/OcDebugLogLib/DebugPrint.c +++ /dev/null @@ -1,97 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include - -VOID -DebugPrintDevicePath ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Message, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - DEBUG_CODE_BEGIN(); - - CHAR16 *TextDevicePath; - - TextDevicePath = ConvertDevicePathToText (DevicePath, TRUE, FALSE); - DEBUG ((ErrorLevel, "%a - %s\n", Message, OC_HUMAN_STRING (TextDevicePath))); - if (TextDevicePath != NULL) { - FreePool (TextDevicePath); - } - - DEBUG_CODE_END(); -} - -VOID -DebugPrintHexDump ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Message, - IN UINT8 *Bytes, - IN UINTN Size - ) -{ - DEBUG_CODE_BEGIN(); - - UINTN Index; - UINTN Index2; - UINTN Count; - UINTN SizeLeft; - UINTN MaxPerLine; - CHAR8 *HexLine; - CHAR8 *HexLineCurrent; - - MaxPerLine = 64; - Count = (Size + MaxPerLine - 1) / MaxPerLine; - - HexLine = AllocatePool (MaxPerLine * 3 + 1); - if (HexLine == NULL) { - return; - } - - SizeLeft = Size; - - for (Index = 0; Index < Count; ++Index) { - HexLineCurrent = HexLine; - - for (Index2 = 0; SizeLeft > 0 && Index2 < MaxPerLine; ++Index2) { - if (Index2 > 0) { - *HexLineCurrent++ = ' '; - } - - *HexLineCurrent++ = OC_HEX_UPPER (*Bytes); - *HexLineCurrent++ = OC_HEX_LOWER (*Bytes); - --SizeLeft; - ++Bytes; - } - - *HexLineCurrent++ = '\0'; - - DEBUG (( - ErrorLevel, - "%a (%u/%u %u) - %a\n", - Message, - (UINT32) Index + 1, - (UINT32) Count, - (UINT32) Size, - HexLine - )); - } - - FreePool (HexLine); - - DEBUG_CODE_END(); -} diff --git a/Library/OcDebugLogLib/OcAppleLog.c b/Library/OcDebugLogLib/OcAppleLog.c deleted file mode 100644 index 4435484f4..000000000 --- a/Library/OcDebugLogLib/OcAppleLog.c +++ /dev/null @@ -1,314 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcLogInternal.h" - -STATIC -BOOLEAN -mAppleDebugLogEnable; - -STATIC -CHAR8 -mCurrentBuffer[1024]; - -STATIC -APPLE_PERF_DATA * -mApplePerfBuffer; - -STATIC -UINTN -mApplePerfBufferSize; - -STATIC -UINT32 -mApplePerfDumped; - -STATIC -EFI_STATUS -EFIAPI -AppleDebugLogPrintToOcLog ( - IN OC_LOG_PROTOCOL *OcLog, - IN CONST CHAR8 *Format, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Marker; - - VA_START (Marker, Format); - - Status = OcLog->AddEntry ( - OcLog, - DEBUG_INFO, - Format, - Marker - ); - - VA_END (Marker); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -AppleDebugLogPrint ( - IN CONST CHAR8 *Message - ) -{ - OC_LOG_PROTOCOL *OcLog; - EFI_STATUS Status; - UINTN Length; - CHAR8 *NewLinePos; - APPLE_PERF_ENTRY *Entry; - UINT32 Index; - - if (!mAppleDebugLogEnable) { - return FALSE; - } - - OcLog = InternalGetOcLog (); - if (OcLog == NULL) { - return EFI_NOT_FOUND; - } - - // - // Flush perf data. - // - if (mApplePerfBuffer != NULL - && mApplePerfBuffer->Signature == APPLE_PERF_DATA_SIGNATURE - && mApplePerfBuffer->NumberOfEntries > mApplePerfDumped) { - Entry = APPLE_PERF_FIRST_ENTRY (mApplePerfBuffer); - - for (Index = 0; Index < mApplePerfBuffer->NumberOfEntries; ++Index) { - if (Index == mApplePerfDumped) { - AppleDebugLogPrintToOcLog ( - OcLog, - "EBPF: [%u ms] %a\n", - (UINT32) Entry->TimestampMs, - Entry->EntryData - ); - ++mApplePerfDumped; - } - Entry = APPLE_PERF_NEXT_ENTRY (Entry); - } - } - - // - // Concatenate with the previous message. - // - Status = AsciiStrCatS ( - mCurrentBuffer, - sizeof (mCurrentBuffer) - 1, - Message - ); - if (EFI_ERROR(Status)) { - Length = AsciiStrLen (mCurrentBuffer); - - if (Length > 0) { - // - // Flush the previous message. - // - if (mCurrentBuffer[Length - 1] != '\n') { - // - // Ensure it is terminated with a newline. - // - mCurrentBuffer[Length] = '\n'; - mCurrentBuffer[Length+1] = '\0'; - } - AppleDebugLogPrintToOcLog ( - OcLog, - "AAPL: %a", - Message - ); - mCurrentBuffer[0] = '\0'; - - // - // Append the new message again. - // - Status = AsciiStrCpyS ( - mCurrentBuffer, - sizeof (mCurrentBuffer) - 1, - Message - ); - } - - // - // New message does not fit, send it directly. - // - if (EFI_ERROR(Status)) { - return AppleDebugLogPrintToOcLog ( - OcLog, - "AAPL: %a", - Message - ); - } - } - - // - // New message is in the buffer, send it line-by-line. - // - while (TRUE) { - NewLinePos = AsciiStrStr (mCurrentBuffer, "\n"); - if (NewLinePos == NULL) { - break; - } - - AppleDebugLogPrintToOcLog ( - OcLog, - "AAPL: %.*a", - (UINTN) (NewLinePos - mCurrentBuffer + 1), - mCurrentBuffer - ); - - Length = AsciiStrLen (NewLinePos + 1); - - if (Length > 0) { - CopyMem (mCurrentBuffer, NewLinePos + 1, Length + 1); - } else { - mCurrentBuffer[0] = '\0'; - } - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AppleDebugLogExtractBuffer ( - IN OUT UINT32 *Position, - IN OUT UINTN *BufferSize, - OUT CHAR8 *Buffer OPTIONAL, - OUT UINT32 *LostCharacters OPTIONAL - ) -{ - // - // Do nothing for now. - // - return EFI_END_OF_FILE; -} - -STATIC -EFI_STATUS -EFIAPI -AppleDebugLogWriteFiles ( - VOID - ) -{ - // - // Do nothing for now. - // - return EFI_SUCCESS; -} - -STATIC -VOID -EFIAPI -AppleDebugLogSetupFiles ( - VOID - ) -{ - // - // Do nothing for now. - // -} - -STATIC -APPLE_DEBUG_LOG_PROTOCOL -mAppleDebugLogProtocol = { - .Revision = APPLE_DEBUG_LOG_PROTOCOL_REVISION, - .Print = AppleDebugLogPrint, - .ExtractBuffer = AppleDebugLogExtractBuffer, - .WriteFiles = AppleDebugLogWriteFiles, - .SetupFiles = AppleDebugLogSetupFiles -}; - -APPLE_DEBUG_LOG_PROTOCOL * -OcAppleDebugLogInstallProtocol ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - - APPLE_DEBUG_LOG_PROTOCOL *Protocol; - EFI_HANDLE Handle; - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gAppleDebugLogProtocolGuid); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCL: Uninstall failed: %r\n", Status)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gAppleDebugLogProtocolGuid, - NULL, - (VOID *) &Protocol - ); - - if (!EFI_ERROR(Status)) { - return Protocol; - } - } - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gAppleDebugLogProtocolGuid, - (VOID **) &mAppleDebugLogProtocol, - NULL - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - return &mAppleDebugLogProtocol; -} - -VOID -OcAppleDebugLogConfigure ( - IN BOOLEAN Enable - ) -{ - mAppleDebugLogEnable = Enable; -} - -VOID -OcAppleDebugLogPerfAllocated ( - IN OUT VOID *PerfBuffer, - IN UINTN PerfBufferSize - ) -{ - DEBUG ((DEBUG_INFO, "OCL: EFI Boot performance buffer %p (%u)\n", PerfBuffer, (UINT32) PerfBufferSize)); - if (mAppleDebugLogEnable) { - ZeroMem (PerfBuffer, PerfBufferSize); - - mApplePerfBuffer = PerfBuffer; - mApplePerfBufferSize = PerfBufferSize; - mApplePerfDumped = 0; - } -} - diff --git a/Library/OcDebugLogLib/OcDebugLogLib.c b/Library/OcDebugLogLib/OcDebugLogLib.c deleted file mode 100755 index be1a38835..000000000 --- a/Library/OcDebugLogLib/OcDebugLogLib.c +++ /dev/null @@ -1,287 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "OcLogInternal.h" - -/** - Prints a debug message to the debug output device if the specified error level is enabled. - - If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function - GetDebugPrintErrorLevel (), then print the message specified by Format and the - associated variable argument list to the debug output device. - - If Format is NULL, then ASSERT(). - - @param ErrorLevel The error level of the debug message. - @param Format Format string for the debug message to print. - @param ... A variable argument list whose contents are accessed - based on the format string specified by Format. -**/ -VOID -EFIAPI -DebugPrint ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Format, - ... - ) -{ - VA_LIST Marker; - CHAR16 Buffer[256]; - OC_LOG_PROTOCOL *OcLog; - - ASSERT (Format != NULL); - - OcLog = InternalGetOcLog (); - - VA_START (Marker, Format); - - if (OcLog != NULL) { - OcLog->AddEntry (OcLog, ErrorLevel, Format, Marker); - } else if ((ErrorLevel & GetDebugPrintErrorLevel ()) != 0) { - UnicodeVSPrintAsciiFormat (Buffer, sizeof (Buffer), Format, Marker); - gST->ConOut->OutputString (gST->ConOut, Buffer); - } - - VA_END (Marker); -} - - -/** - Prints an assert message containing a filename, line number, and description. - This may be followed by a breakpoint or a dead loop. - - Print a message of the form "ASSERT (): \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 - 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 - processing another DebugAssert(), then DebugAssert() must return immediately. - - If FileName is NULL, then a string of "(NULL) Filename" is printed. - If Description is NULL, then a string of "(NULL) Description" is printed. - - @param FileName The pointer to the name of the source file that generated - the assert condition. - @param LineNumber The line number in the source file that generated the - assert condition - @param Description The pointer to the description of the assert condition. - -**/ -VOID -EFIAPI -DebugAssert ( - IN CONST CHAR8 *FileName, - IN UINTN LineNumber, - IN CONST CHAR8 *Description - ) -{ - // - // Generate the ASSERT() message and log it - // - DebugPrint ( - DEBUG_ERROR, - "ASSERT [%a] %a(%d): %a\n", - gEfiCallerBaseName, - FileName, - LineNumber, - Description - ); - - // - // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings - // - if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { - CpuBreakpoint (); - } else if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { - CpuDeadLoop (); - } -} - - -/** - Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. - - This function fills Length bytes of Buffer with the value specified by - PcdDebugClearMemoryValue, and returns Buffer. - - If Buffer is NULL, then ASSERT(). - If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. - @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. - - @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. -**/ -VOID * -EFIAPI -DebugClearMemory ( - OUT VOID *Buffer, - IN UINTN Length - ) -{ - // - // If Buffer is NULL, then ASSERT(). - // - ASSERT (Buffer != NULL); - - // - // SetMem() checks for the the ASSERT() condition on Length and returns Buffer - // - return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue)); -} - - -/** - 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. - - @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. - -**/ -BOOLEAN -EFIAPI -DebugAssertEnabled ( - VOID - ) -{ - return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); -} - - -/** - 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. - - @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. - -**/ -BOOLEAN -EFIAPI -DebugPrintEnabled ( - VOID - ) -{ - return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); -} - - -/** - 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. - - @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. - -**/ -BOOLEAN -EFIAPI -DebugCodeEnabled ( - VOID - ) -{ - return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); -} - - -/** - 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. - - @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. - -**/ -BOOLEAN -EFIAPI -DebugClearMemoryEnabled ( - VOID - ) -{ - return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); -} - - -/** - Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. - - This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. - - @retval TRUE Current ErrorLevel is supported. - @retval FALSE Current ErrorLevel is not supported. - -**/ -BOOLEAN -EFIAPI -DebugPrintLevelEnabled ( - IN CONST UINTN ErrorLevel - ) -{ - return (BOOLEAN) ((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0); -} - -/** - Prints via gST->ConOut without any pool allocations. - Otherwise equivalent to Print. - Note: EFIAPI must be present for VA_ARGS forwarding (causes bugs with gcc). - - @param[in] Format Formatted string. -**/ -VOID -EFIAPI -OcPrintScreen ( - IN CONST CHAR16 *Format, - ... - ) -{ - CHAR16 Buffer[1024]; - VA_LIST Marker; - - VA_START (Marker, Format); - UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker); - VA_END (Marker); - - // - // It is safe to call gST->ConOut->OutputString, because in crtitical areas - // AptioMemoryFix is responsible for overriding gBS->AllocatePool with its own - // implementation that uses a custom allocator. - // - if (gST->ConOut) { - gST->ConOut->OutputString (gST->ConOut, Buffer); - } -} diff --git a/Library/OcDebugLogLib/OcDebugLogLib.inf b/Library/OcDebugLogLib/OcDebugLogLib.inf deleted file mode 100755 index 159188008..000000000 --- a/Library/OcDebugLogLib/OcDebugLogLib.inf +++ /dev/null @@ -1,68 +0,0 @@ -## @file -# -# Component description file for Debug Library using the OcLog protocol. -# -# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcDebugLogLib - FILE_GUID = 85E15002-397B-441B-AC5C-BF952B0E7331 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = DebugLib - -# VALID_ARCHITECTURES = IA32 X64 IPF EBC - -[Packages] - CloverPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - - -[Guids] - gEfiMiscSubClassGuid - gOcVendorVariableGuid - gApplePlatformProducerNameGuid - -[Protocols] - gOcLogProtocolGuid - gAppleDebugLogProtocolGuid - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugPrintErrorLevelLib - DevicePathLib - MemoryAllocationLib - OcCpuLib - OcDataHubLib - SerialPortLib - UefiRuntimeServicesTableLib - -[Pcd] - gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask - gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel - -[Sources] - OcAppleLog.c - OcDebugLogLib.c - OcLog.c - OcLogInternal.h - DebugPrint.c - DebugHelp.c diff --git a/Library/OcDebugLogLib/OcLog.c b/Library/OcDebugLogLib/OcLog.c deleted file mode 100755 index 717cebfb6..000000000 --- a/Library/OcDebugLogLib/OcLog.c +++ /dev/null @@ -1,559 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OcLogInternal.h" - -STATIC -CHAR8 * -GetTiming ( - IN OC_LOG_PROTOCOL *This - ) -{ - OC_LOG_PRIVATE_DATA *Private = NULL; - - UINT64 dTStartSec = 0; - UINT64 dTStartMs = 0; - UINT64 dTLastSec = 0; - UINT64 dTLastMs = 0; - UINT64 CurrentTsc = 0; - - if (This == NULL) { - return NULL; - } - - Private = OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (This); - - // - // Calibrate TSC for timings. - // - - if (Private->TscFrequency == 0) { - Private->TscFrequency = OcGetTSCFrequency (); - - if (Private->TscFrequency != 0) { - CurrentTsc = AsmReadTsc (); - - Private->TscStart = CurrentTsc; - Private->TscLast = CurrentTsc; - } - } - - if (Private->TscFrequency > 0) { - CurrentTsc = AsmReadTsc (); - - dTStartMs = DivU64x64Remainder (MultU64x32 (CurrentTsc - Private->TscStart, 1000), Private->TscFrequency, NULL); - dTStartSec = DivU64x64Remainder (dTStartMs, 1000, &dTStartMs); - dTLastMs = DivU64x64Remainder (MultU64x32 (CurrentTsc - Private->TscLast, 1000), Private->TscFrequency, NULL); - dTLastSec = DivU64x64Remainder (dTLastMs, 1000, &dTLastMs); - - Private->TscLast = CurrentTsc; - } - - AsciiSPrint ( - Private->TimingTxt, - OC_LOG_TIMING_BUFFER_SIZE, - "%02d:%03d %02d:%03d ", - dTStartSec, - dTStartMs, - dTLastSec, - dTLastMs - ); - - return Private->TimingTxt; -} - -STATIC -CHAR16 * -GetLogPath ( - IN CONST CHAR16 *LogPrefixPath - ) -{ - EFI_STATUS Status; - EFI_TIME Date; - CHAR16 *LogPath; - UINTN Size; - - if (LogPrefixPath == NULL) { - return NULL; - } - - Status = gRT->GetTime (&Date, NULL); - if (EFI_ERROR(Status)) { - ZeroMem (&Date, sizeof (Date)); - } - - Size = StrSize (LogPrefixPath) + L_STR_SIZE (L"-0000-00-00-000000.txt"); - - LogPath = AllocatePool (Size); - if (LogPath == NULL) { - return NULL; - } - - UnicodeSPrint ( - LogPath, - Size, - L"%s-%04u-%02u-%02u-%02u%02u%02u.txt", - LogPrefixPath, - (UINT32) Date.Year, - (UINT32) Date.Month, - (UINT32) Date.Day, - (UINT32) Date.Hour, - (UINT32) Date.Minute, - (UINT32) Date.Second - ); - - return LogPath; -} - -EFI_STATUS -EFIAPI -OcLogAddEntry ( - IN OC_LOG_PROTOCOL *OcLog, - IN UINTN ErrorLevel, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ) -{ - EFI_STATUS Status; - - OC_LOG_PRIVATE_DATA *Private; - UINT32 Attributes; - UINT32 TimingLength; - UINT32 LineLength; - APPLE_PLATFORM_DATA_RECORD *Entry; - UINT32 KeySize; - UINT32 DataSize; - UINT32 TotalSize; - - Private = OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog); - - if ((OcLog->Options & OC_LOG_ENABLE) == 0) { - // - // Silently ignore when disabled. - // - return EFI_SUCCESS; - } - - AsciiVSPrint ( - Private->LineBuffer, - sizeof (Private->LineBuffer), - FormatString, - Marker - ); - - // - // Add Entry. - // - - Status = EFI_SUCCESS; - - if (*Private->LineBuffer != '\0') { - GetTiming (OcLog); - - // - // Send the string to the console output device. - // - if ((OcLog->Options & OC_LOG_CONSOLE) != 0 && (OcLog->DisplayLevel & ErrorLevel) != 0) { - UnicodeSPrint ( - Private->UnicodeLineBuffer, - sizeof (Private->UnicodeLineBuffer), - L"%a", - Private->LineBuffer - ); - gST->ConOut->OutputString (gST->ConOut, Private->UnicodeLineBuffer); - - if (OcLog->DisplayDelay > 0) { - gBS->Stall (OcLog->DisplayDelay); - } - } - - TimingLength = (UINT32) AsciiStrLen (Private->TimingTxt); - LineLength = (UINT32) AsciiStrLen (Private->LineBuffer); - - // - // Write to serial port. - // - if ((OcLog->Options & OC_LOG_SERIAL) != 0) { - Status = SerialPortWrite ((UINT8 *) Private->TimingTxt, TimingLength); - if (Status == EFI_NO_MAPPING) { - // - // Disable serial port option. - // - OcLog->Options &= ~OC_LOG_SERIAL; - } - SerialPortWrite ((UINT8 *) Private->LineBuffer, LineLength); - } - - // - // Write to DataHub. - // - if ((OcLog->Options & OC_LOG_DATA_HUB) != 0) { - if (Private->DataHub == NULL) { - gBS->LocateProtocol ( - &gEfiDataHubProtocolGuid, - NULL, - (VOID **) &Private->DataHub - ); - } - - if (Private->DataHub != NULL) { - KeySize = (L_STR_LEN (OC_LOG_VARIABLE_NAME) + 6) * sizeof (CHAR16); - DataSize = TimingLength + LineLength + 1; - TotalSize = KeySize + DataSize + sizeof (*Entry); - - Entry = AllocatePool (TotalSize); - - if (Entry != NULL) { - ZeroMem (Entry, sizeof (*Entry)); - Entry->KeySize = KeySize; - Entry->ValueSize = DataSize; - - UnicodeSPrint ( - (CHAR16 *) &Entry->Data[0], - Entry->KeySize, - L"%s%05u", - OC_LOG_VARIABLE_NAME, - Private->LogCounter++ - ); - - CopyMem ( - &Entry->Data[Entry->KeySize], - Private->TimingTxt, - TimingLength - ); - - CopyMem ( - &Entry->Data[Entry->KeySize + TimingLength], - Private->LineBuffer, - LineLength + 1 - ); - - Private->DataHub->LogData ( - Private->DataHub, - &gEfiMiscSubClassGuid, - &gApplePlatformProducerNameGuid, - EFI_DATA_RECORD_CLASS_DATA, - Entry, - TotalSize - ); - - FreePool (Entry); - } - } - } - - // - // Write to internal buffer. - // - - Status = AsciiStrCatS (Private->AsciiBuffer, Private->AsciiBufferSize, Private->TimingTxt); - if (!EFI_ERROR(Status)) { - Status = AsciiStrCatS (Private->AsciiBuffer, Private->AsciiBufferSize, Private->LineBuffer); - } - - // - // Write to a file. - // Always overwriting file completely is most reliable. - // I know it is slow, but fixed size write is more reliable with broken FAT32 driver. - // - if ((OcLog->Options & OC_LOG_FILE) != 0 && OcLog->FileSystem != NULL) { - if (EfiGetCurrentTpl () <= TPL_CALLBACK) { - SetFileData ( - OcLog->FileSystem, - OcLog->FilePath, - Private->AsciiBuffer, - (UINT32) Private->AsciiBufferSize - ); - } - } - - // - // Write to a variable. - // - if (ErrorLevel != DEBUG_BULK_INFO && (OcLog->Options & (OC_LOG_VARIABLE | OC_LOG_NONVOLATILE)) != 0) { - // - // Do not log timing information to NVRAM, it is already large. - // This check is here, because Microsoft is retarded and asserts. - // - if (Private->NvramBufferSize - AsciiStrSize (Private->NvramBuffer) >= AsciiStrLen (Private->LineBuffer)) { - Status = AsciiStrCatS (Private->NvramBuffer, Private->NvramBufferSize, Private->LineBuffer); - } else { - Status = EFI_BUFFER_TOO_SMALL; - } - if (!EFI_ERROR(Status)) { - Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - if ((OcLog->Options & OC_LOG_NONVOLATILE) != 0) { - Attributes |= EFI_VARIABLE_NON_VOLATILE; - } - - Status = gRT->SetVariable ( - OC_LOG_VARIABLE_NAME, - &gOcVendorVariableGuid, - Attributes, - AsciiStrLen (Private->NvramBuffer), - Private->NvramBuffer - ); - - if (EFI_ERROR(Status)) { - // - // On APTIO V this may not even get printed. Regardless of volatile or not - // it will firstly start discarding NVRAM data silently, and then will borks - // NVRAM support completely till reboot. Let's stop on first error at least. - // - gST->ConOut->OutputString (gST->ConOut, L"NVRAM is full, cannot log!\r\n"); - gBS->Stall (SECONDS_TO_MICROSECONDS (1)); - OcLog->Options &= ~(OC_LOG_VARIABLE | OC_LOG_NONVOLATILE); - } - } else { - gST->ConOut->OutputString (gST->ConOut, L"NVRAM log size exceeded, cannot log!\r\n"); - gBS->Stall (SECONDS_TO_MICROSECONDS (1)); - OcLog->Options &= ~(OC_LOG_VARIABLE | OC_LOG_NONVOLATILE); - } - } - } - - if ((ErrorLevel & OcLog->HaltLevel) != 0 - && AsciiStrnCmp (FormatString, "\nASSERT_RETURN_ERROR", L_STR_LEN ("\nASSERT_RETURN_ERROR")) != 0 - && AsciiStrnCmp (FormatString, "\nASSERT_EFI_ERROR", L_STR_LEN ("\nASSERT_EFI_ERROR")) != 0) { - gST->ConOut->OutputString (gST->ConOut, L"Halting on critical error\r\n"); - gBS->Stall (SECONDS_TO_MICROSECONDS (1)); - CpuDeadLoop (); - } - - return Status; -} - -EFI_STATUS -EFIAPI -OcLogGetLog ( - IN OC_LOG_PROTOCOL *This, - OUT CHAR8 **OcLogBuffer - ) -{ - EFI_STATUS Status; - - OC_LOG_PRIVATE_DATA *Private; - - Status = EFI_INVALID_PARAMETER; - - if (OcLogBuffer != NULL) { - Private = OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (This); - *OcLogBuffer = Private->AsciiBuffer; - - Status = EFI_SUCCESS; - } - - return Status; -} - -EFI_STATUS -EFIAPI -OcLogSaveLog ( - IN OC_LOG_PROTOCOL *This, - IN UINT32 NonVolatile OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ) -{ - return EFI_NOT_FOUND; -} - -EFI_STATUS -EFIAPI -OcLogResetTimers ( - IN OC_LOG_PROTOCOL *This - ) -{ - return EFI_SUCCESS; -} - -OC_LOG_PROTOCOL * -InternalGetOcLog ( - VOID - ) -{ - EFI_STATUS Status; - - STATIC OC_LOG_PROTOCOL *mInternalOcLog = NULL; - - if (mInternalOcLog == NULL) { - Status = gBS->LocateProtocol ( - &gOcLogProtocolGuid, - NULL, - (VOID **) &mInternalOcLog - ); - - if (EFI_ERROR(Status) || mInternalOcLog->Revision != OC_LOG_REVISION) { - mInternalOcLog = NULL; - } - } - - return mInternalOcLog; -} - -EFI_STATUS -OcConfigureLogProtocol ( - IN OC_LOG_OPTIONS Options, - IN UINT32 DisplayDelay, - IN UINTN DisplayLevel, - IN UINTN HaltLevel, - IN CONST CHAR16 *LogPrefixPath OPTIONAL, - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *LogFileSystem OPTIONAL - ) -{ - EFI_STATUS Status; - - OC_LOG_PROTOCOL *OcLog; - OC_LOG_PRIVATE_DATA *Private; - EFI_HANDLE Handle; - EFI_FILE_PROTOCOL *LogRoot; - CHAR16 *LogPath; - - if ((Options & (OC_LOG_FILE | OC_LOG_ENABLE)) == (OC_LOG_FILE | OC_LOG_ENABLE)) { - LogRoot = NULL; - LogPath = GetLogPath (LogPrefixPath); - - if (LogPath != NULL) { - if (LogFileSystem != NULL) { - Status = LogFileSystem->OpenVolume (LogFileSystem, &LogRoot); - if (EFI_ERROR(Status)) { - LogRoot = NULL; - } - } - - if (LogRoot == NULL) { - Status = FindWritableFileSystem (&LogRoot); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCL: There is no place to write log file to - %r\n", Status)); - LogRoot = NULL; - } - } - - if (LogRoot == NULL) { - FreePool (LogPath); - LogPath = NULL; - } - } - } else { - LogRoot = NULL; - LogPath = NULL; - } - - // - // Check if protocol already exists. - // - - OcLog = InternalGetOcLog (); - - if (OcLog != NULL) { - // - // Set desired options in existing protocol. - // - - if (OcLog->FileSystem != NULL) { - OcLog->FileSystem->Close (OcLog->FileSystem); - } - if (OcLog->FilePath != NULL) { - FreePool (OcLog->FilePath); - } - - OcLog->Options = Options; - OcLog->DisplayDelay = DisplayDelay; - OcLog->DisplayLevel = DisplayLevel; - OcLog->HaltLevel = HaltLevel; - OcLog->FileSystem = LogRoot; - OcLog->FilePath = LogPath; - - Status = EFI_SUCCESS; - } else { - Private = AllocateZeroPool (sizeof (*Private)); - Status = EFI_OUT_OF_RESOURCES; - - if (Private != NULL) { - Private->Signature = OC_LOG_PRIVATE_DATA_SIGNATURE; - Private->AsciiBufferSize = OC_LOG_BUFFER_SIZE; - Private->NvramBufferSize = OC_LOG_NVRAM_BUFFER_SIZE; - Private->OcLog.Revision = OC_LOG_REVISION; - Private->OcLog.AddEntry = OcLogAddEntry; - Private->OcLog.GetLog = OcLogGetLog; - Private->OcLog.SaveLog = OcLogSaveLog; - Private->OcLog.ResetTimers = OcLogResetTimers; - Private->OcLog.Options = Options; - Private->OcLog.DisplayDelay = DisplayDelay; - Private->OcLog.DisplayLevel = DisplayLevel; - Private->OcLog.HaltLevel = HaltLevel; - Private->OcLog.FileSystem = LogRoot; - Private->OcLog.FilePath = LogPath; - - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gOcLogProtocolGuid, - EFI_NATIVE_INTERFACE, - &Private->OcLog - ); - - if (!EFI_ERROR(Status)) { - OcLog = &Private->OcLog; - } else { - FreePool (Private); - } - } - } - - if (!EFI_ERROR(Status) - && (Options & (OC_LOG_SERIAL | OC_LOG_ENABLE)) == (OC_LOG_SERIAL | OC_LOG_ENABLE)) { - SerialPortInitialize (); - } - - if (LogRoot != NULL) { - if (!EFI_ERROR(Status)) { - if (OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBufferSize > 0) { - SetFileData ( - LogRoot, - LogPath, - OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBuffer, - (UINT32) OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS (OcLog)->AsciiBufferSize - ); - } - } else { - LogRoot->Close (LogRoot); - FreePool (LogPath); - } - } - - return Status; -} diff --git a/Library/OcDebugLogLib/OcLogInternal.h b/Library/OcDebugLogLib/OcLogInternal.h deleted file mode 100755 index 7d870759d..000000000 --- a/Library/OcDebugLogLib/OcLogInternal.h +++ /dev/null @@ -1,55 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_LOG_INTERNAL_H -#define OC_LOG_INTERNAL_H - -#include -#include - -#define OC_LOG_BUFFER_SIZE BASE_256KB -#define OC_LOG_LINE_BUFFER_SIZE BASE_1KB -#define OC_LOG_NVRAM_BUFFER_SIZE BASE_32KB -#define OC_LOG_FILE_PATH_BUFFER_SIZE 256 -#define OC_LOG_TIMING_BUFFER_SIZE 64 - -#define OC_LOG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('O', 'C', 'L', 'G') - -#define OC_LOG_PRIVATE_DATA_FROM_OC_LOG_THIS(a) \ - (CR (a, OC_LOG_PRIVATE_DATA, OcLog, OC_LOG_PRIVATE_DATA_SIGNATURE)) - -typedef struct { - UINT64 Signature; - UINT64 TscFrequency; - UINT64 TscStart; - UINT64 TscLast; - CHAR8 TimingTxt[OC_LOG_TIMING_BUFFER_SIZE]; - CHAR8 LineBuffer[OC_LOG_LINE_BUFFER_SIZE]; - CHAR16 UnicodeLineBuffer[OC_LOG_LINE_BUFFER_SIZE]; - CHAR8 AsciiBuffer[OC_LOG_BUFFER_SIZE]; - UINTN AsciiBufferSize; - CHAR8 NvramBuffer[OC_LOG_NVRAM_BUFFER_SIZE]; - UINTN NvramBufferSize; - UINT32 LogCounter; - CHAR16 *LogFilePathName; - EFI_DATA_HUB_PROTOCOL *DataHub; - OC_LOG_PROTOCOL OcLog; -} OC_LOG_PRIVATE_DATA; - -OC_LOG_PROTOCOL * -InternalGetOcLog ( - VOID - ); - -#endif // OC_LOG_INTERNAL_H diff --git a/Library/OcDevicePathLib/ExpandDevicePath.c b/Library/OcDevicePathLib/ExpandDevicePath.c deleted file mode 100644 index d34f75a62..000000000 --- a/Library/OcDevicePathLib/ExpandDevicePath.c +++ /dev/null @@ -1,902 +0,0 @@ -/** @file - Library functions which relates with booting. - -Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
-(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// CHANGE: Track InternalConnectAll() execution status. -STATIC BOOLEAN mConnectAllExecuted = FALSE; - -// CHANGE: Added from UefiBootManagerLib -/** - Connect all the drivers to all the controllers. - - This function makes sure all the current system drivers manage the correspoinding - controllers if have. And at the same time, makes sure all the system controllers - have driver to manage it if have. -**/ -VOID -InternalConnectAll ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - // CHANGE: Report execution status. - mConnectAllExecuted = TRUE; - - // - // Connect All EFI 1.10 drivers following EFI 1.10 algorithm - // CHANGE: Only connect device handles. Do not call gDS->Dispatch(). - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiDevicePathProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (!EFI_ERROR(Status)) { - for (Index = 0; Index < HandleCount; Index++) { - gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - } - - FreePool (HandleBuffer); - } -} - -/** - Check whether a USB device match the specified USB Class device path. This - function follows "Load Option Processing" behavior in UEFI specification. - - @param UsbIo USB I/O protocol associated with the USB device. - @param UsbClass The USB Class device path to match. - - @retval TRUE The USB device match the USB Class device path. - @retval FALSE The USB device does not match the USB Class device path. - -**/ -STATIC -BOOLEAN -BmMatchUsbClass ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN USB_CLASS_DEVICE_PATH *UsbClass - ) -{ - EFI_STATUS Status; - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - EFI_USB_INTERFACE_DESCRIPTOR IfDesc; - UINT8 DeviceClass; - UINT8 DeviceSubClass; - UINT8 DeviceProtocol; - - if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) || - (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP)){ - return FALSE; - } - - // - // Check Vendor Id and Product Id. - // - Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); - if (EFI_ERROR(Status)) { - return FALSE; - } - - if ((UsbClass->VendorId != 0xffff) && - (UsbClass->VendorId != DevDesc.IdVendor)) { - return FALSE; - } - - if ((UsbClass->ProductId != 0xffff) && - (UsbClass->ProductId != DevDesc.IdProduct)) { - return FALSE; - } - - DeviceClass = DevDesc.DeviceClass; - DeviceSubClass = DevDesc.DeviceSubClass; - DeviceProtocol = DevDesc.DeviceProtocol; - if (DeviceClass == 0) { - // - // If Class in Device Descriptor is set to 0, use the Class, SubClass and - // Protocol in Interface Descriptor instead. - // - Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); - if (EFI_ERROR(Status)) { - return FALSE; - } - - DeviceClass = IfDesc.InterfaceClass; - DeviceSubClass = IfDesc.InterfaceSubClass; - DeviceProtocol = IfDesc.InterfaceProtocol; - } - - // - // Check Class, SubClass and Protocol. - // - if ((UsbClass->DeviceClass != 0xff) && - (UsbClass->DeviceClass != DeviceClass)) { - return FALSE; - } - - if ((UsbClass->DeviceSubClass != 0xff) && - (UsbClass->DeviceSubClass != DeviceSubClass)) { - return FALSE; - } - - if ((UsbClass->DeviceProtocol != 0xff) && - (UsbClass->DeviceProtocol != DeviceProtocol)) { - return FALSE; - } - - return TRUE; -} - -/** - Check whether a USB device match the specified USB WWID device path. This - function follows "Load Option Processing" behavior in UEFI specification. - - @param UsbIo USB I/O protocol associated with the USB device. - @param UsbWwid The USB WWID device path to match. - - @retval TRUE The USB device match the USB WWID device path. - @retval FALSE The USB device does not match the USB WWID device path. - -**/ -STATIC -BOOLEAN -BmMatchUsbWwid ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN USB_WWID_DEVICE_PATH *UsbWwid - ) -{ - EFI_STATUS Status; - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - EFI_USB_INTERFACE_DESCRIPTOR IfDesc; - UINT16 *LangIdTable; - UINT16 TableSize; - UINT16 Index; - CHAR16 *CompareStr; - UINTN CompareLen; - CHAR16 *SerialNumberStr; - UINTN Length; - - if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) || - (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP)) { - return FALSE; - } - - // - // Check Vendor Id and Product Id. - // - Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); - if (EFI_ERROR(Status)) { - return FALSE; - } - if ((DevDesc.IdVendor != UsbWwid->VendorId) || - (DevDesc.IdProduct != UsbWwid->ProductId)) { - return FALSE; - } - - // - // Check Interface Number. - // - Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); - if (EFI_ERROR(Status)) { - return FALSE; - } - if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) { - return FALSE; - } - - // - // Check Serial Number. - // - if (DevDesc.StrSerialNumber == 0) { - return FALSE; - } - - // - // Get all supported languages. - // - TableSize = 0; - LangIdTable = NULL; - Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize); - if (EFI_ERROR(Status) || (TableSize == 0) || (LangIdTable == NULL)) { - return FALSE; - } - - // - // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters. - // - CompareStr = (CHAR16 *) (UINTN) (UsbWwid + 1); - CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16); - if (CompareStr[CompareLen - 1] == L'\0') { - CompareLen--; - } - - // - // Compare serial number in each supported language. - // - for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) { - SerialNumberStr = NULL; - Status = UsbIo->UsbGetStringDescriptor ( - UsbIo, - LangIdTable[Index], - DevDesc.StrSerialNumber, - &SerialNumberStr - ); - if (EFI_ERROR(Status) || (SerialNumberStr == NULL)) { - continue; - } - - Length = StrLen (SerialNumberStr); - if ((Length >= CompareLen) && - (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) { - FreePool (SerialNumberStr); - return TRUE; - } - - FreePool (SerialNumberStr); - } - - return FALSE; -} - -/** - Find a USB device which match the specified short-form device path start with - USB Class or USB WWID device path. If ParentDevicePath is NULL, this function - will search in all USB devices of the platform. If ParentDevicePath is not NULL, - this function will only search in its child devices. - - @param DevicePath The device path that contains USB Class or USB WWID device path. - @param ParentDevicePathSize The length of the device path before the USB Class or - USB WWID device path. - @param UsbIoHandleCount A pointer to the count of the returned USB IO handles. - - @retval NULL The matched USB IO handles cannot be found. - @retval other The matched USB IO handles. - -**/ -STATIC -EFI_HANDLE * -BmFindUsbDevice ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINTN ParentDevicePathSize, - OUT UINTN *UsbIoHandleCount - ) -{ - EFI_STATUS Status; - EFI_HANDLE *UsbIoHandles; - EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath; - EFI_USB_IO_PROTOCOL *UsbIo; - UINTN Index; - BOOLEAN Matched; - - ASSERT (UsbIoHandleCount != NULL); - - // - // Get all UsbIo Handles. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiUsbIoProtocolGuid, - NULL, - UsbIoHandleCount, - &UsbIoHandles - ); - if (EFI_ERROR(Status)) { - *UsbIoHandleCount = 0; - UsbIoHandles = NULL; - } - - for (Index = 0; Index < *UsbIoHandleCount; ) { - // - // Get the Usb IO interface. - // - Status = gBS->HandleProtocol( - UsbIoHandles[Index], - &gEfiUsbIoProtocolGuid, - (VOID **) &UsbIo - ); - UsbIoDevicePath = DevicePathFromHandle (UsbIoHandles[Index]); - Matched = FALSE; - if (!EFI_ERROR(Status) && (UsbIoDevicePath != NULL)) { - - // - // Compare starting part of UsbIoHandle's device path with ParentDevicePath. - // - if (CompareMem (UsbIoDevicePath, DevicePath, ParentDevicePathSize) == 0) { - if (BmMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ((UINTN) DevicePath + ParentDevicePathSize)) || - BmMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ((UINTN) DevicePath + ParentDevicePathSize))) { - Matched = TRUE; - } - } - } - - if (!Matched) { - (*UsbIoHandleCount) --; - CopyMem (&UsbIoHandles[Index], &UsbIoHandles[Index + 1], (*UsbIoHandleCount - Index) * sizeof (EFI_HANDLE)); - } else { - Index++; - } - } - - return UsbIoHandles; -} - -/** - Expand USB Class or USB WWID device path node to be full device path of a USB - device in platform. - - This function support following 4 cases: - 1) Boot Option device path starts with a USB Class or USB WWID device path, - and there is no Media FilePath device path in the end. - In this case, it will follow Removable Media Boot Behavior. - 2) Boot Option device path starts with a USB Class or USB WWID device path, - and ended with Media FilePath device path. - 3) Boot Option device path starts with a full device path to a USB Host Controller, - contains a USB Class or USB WWID device path node, while not ended with Media - FilePath device path. In this case, it will follow Removable Media Boot Behavior. - 4) Boot Option device path starts with a full device path to a USB Host Controller, - contains a USB Class or USB WWID device path node, and ended with Media - FilePath device path. - - @param FilePath The device path pointing to a load option. - It could be a short-form device path. - @param FullPath The full path returned by the routine in last call. - Set to NULL in first call. - @param ShortformNode Pointer to the USB short-form device path node in the FilePath buffer. - - @return The next possible full path pointing to the load option. - Caller is responsible to free the memory. -**/ -STATIC -EFI_DEVICE_PATH_PROTOCOL * -BmExpandUsbDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN EFI_DEVICE_PATH_PROTOCOL *FullPath, - IN EFI_DEVICE_PATH_PROTOCOL *ShortformNode - ) -{ - UINTN ParentDevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_DEVICE_PATH_PROTOCOL *NextFullPath; - EFI_HANDLE *Handles; - UINTN HandleCount; - UINTN Index; - BOOLEAN GetNext; - - NextFullPath = NULL; - GetNext = (BOOLEAN)(FullPath == NULL); - ParentDevicePathSize = (UINTN) ShortformNode - (UINTN) FilePath; - RemainingDevicePath = NextDevicePathNode (ShortformNode); - Handles = BmFindUsbDevice (FilePath, ParentDevicePathSize, &HandleCount); - - for (Index = 0; Index < HandleCount; Index++) { - FilePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), RemainingDevicePath); - if (FilePath == NULL) { - // - // Out of memory. - // - continue; - } - NextFullPath = OcGetNextLoadOptionDevicePath (FilePath, NULL); - FreePool (FilePath); - if (NextFullPath == NULL) { - // - // No BlockIo or SimpleFileSystem under FilePath. - // - continue; - } - if (GetNext) { - break; - } else { - GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0); - FreePool (NextFullPath); - NextFullPath = NULL; - } - } - - if (Handles != NULL) { - FreePool (Handles); - } - - return NextFullPath; -} - -/** - Expand the media device path which points to a BlockIo or SimpleFileSystem instance. - - @param DevicePath The media device path pointing to a BlockIo or SimpleFileSystem instance. - @param FullPath The full path returned by the routine in last call. - Set to NULL in first call. - - @return The next possible full path pointing to the load option. - Caller is responsible to free the memory. -**/ -STATIC -EFI_DEVICE_PATH_PROTOCOL * -BmExpandMediaDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *FullPath, - IN EFI_HANDLE Handle - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - VOID *Buffer; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *NextFullPath; - UINTN Size; - UINTN TempSize; - EFI_HANDLE *SimpleFileSystemHandles; - UINTN NumberSimpleFileSystemHandles; - UINTN Index; - BOOLEAN GetNext; - - GetNext = (BOOLEAN)(FullPath == NULL); - // - // Check whether the device is connected - // CHANGE: This branch has been removed as it has been covered by a caller change - // - - // CHANGE: Get Handle via parameter as the function is called by the caller too - - // - // For device boot option only pointing to the removable device handle, - // should make sure all its children handles (its child partion or media handles) - // are created and connected. - // - gBS->ConnectController (Handle, NULL, NULL, TRUE); - - // - // Issue a dummy read to the device to check for media change. - // When the removable media is changed, any Block IO read/write will - // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is - // returned. After the Block IO protocol is reinstalled, subsequent - // Block IO read/write will success. - // - Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); - // CHANGE: Do not ASSERT. - if (EFI_ERROR(Status)) { - return NULL; - } - Buffer = AllocatePool (BlockIo->Media->BlockSize); - if (Buffer != NULL) { - BlockIo->ReadBlocks ( - BlockIo, - BlockIo->Media->MediaId, - 0, - BlockIo->Media->BlockSize, - Buffer - ); - FreePool (Buffer); - } - - // - // Detect the the default boot file from removable Media - // - NextFullPath = NULL; - Size = GetDevicePathSize (DevicePath) - END_DEVICE_PATH_LENGTH; - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumberSimpleFileSystemHandles, - &SimpleFileSystemHandles - ); - for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) { - // - // Get the device path size of SimpleFileSystem handle - // - TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]); - TempSize = GetDevicePathSize (TempDevicePath) - END_DEVICE_PATH_LENGTH; - // - // Check whether the device path of boot option is part of the SimpleFileSystem handle's device path - // - if ((Size <= TempSize) && (CompareMem (TempDevicePath, DevicePath, Size) == 0)) { - // CHANGE: Do not append EFI boot file. - NextFullPath = DuplicateDevicePath (TempDevicePath); - if (GetNext) { - break; - } else { - GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0); - FreePool (NextFullPath); - NextFullPath = NULL; - } - } - } - - if (SimpleFileSystemHandles != NULL) { - FreePool (SimpleFileSystemHandles); - } - - return NextFullPath; -} - -/** - Check whether there is a instance in BlockIoDevicePath, which contain multi device path - instances, has the same partition node with HardDriveDevicePath device path - - @param Handle The partition's device handle - @param BlockIoDevicePath Multi device path instances which need to check - @param HardDriveDevicePath A device path which starts with a hard drive media - device path. - @param LocateEsp Use ESP- instead of PartitionNumber-matching. - - @retval TRUE There is a matched device path instance. - @retval FALSE There is no matched device path instance. - -**/ -STATIC -BOOLEAN -BmMatchPartitionDevicePathNode ( - IN EFI_HANDLE Handle, - IN EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath, - IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath, - IN BOOLEAN LocateEsp - ) -{ - HARDDRIVE_DEVICE_PATH *Node; - CONST EFI_PARTITION_ENTRY *PartEntry; - - if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) { - return FALSE; - } - - // CHANGE: Abort early if partition cannot be an ESP while it was requested. - if (LocateEsp - && (HardDriveDevicePath->MBRType != MBR_TYPE_EFI_PARTITION_TABLE_HEADER - || HardDriveDevicePath->SignatureType != SIGNATURE_TYPE_GUID)) { - return FALSE; - } - - // - // Match all the partition device path nodes including the nested partition nodes - // - while (!IsDevicePathEnd (BlockIoDevicePath)) { - if ((DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) && - (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP) - ) { - // - // See if the harddrive device path in blockio matches the orig Hard Drive Node - // - Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath; - - // - // Match Signature and PartitionNumber. - // Unused bytes in Signature are initiaized with zeros. - // - if ((Node->MBRType == HardDriveDevicePath->MBRType) && - (Node->SignatureType == HardDriveDevicePath->SignatureType) && - (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)) { - // CHANGE: Allow ESP location when PartitionNumber mismatches. - if (!LocateEsp) { - if (Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) { - return TRUE; - } - } else { - PartEntry = OcGetGptPartitionEntry (Handle); - if (PartEntry != NULL - && CompareGuid (&PartEntry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) { - return TRUE; - } - } - } - } - - BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath); - } - - return FALSE; -} - -/** - Expand a device path that starts with a hard drive media device path node to be a - full device path that includes the full hardware path to the device. We need - to do this so it can be booted. As an optimization the front match (the part point - to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a variable - so a connect all is not required on every boot. All successful history device path - which point to partition node (the front part) will be saved. - - @param FilePath The device path pointing to a load option. - It could be a short-form device path. - - @return The full device path pointing to the load option. -**/ -STATIC -EFI_DEVICE_PATH_PROTOCOL * -BmExpandPartitionDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath - ) -{ - EFI_STATUS Status; - UINTN BlockIoHandleCount; - EFI_HANDLE *BlockIoBuffer; - EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath; - UINTN Index; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *FullPath; - BOOLEAN LocateEsp; - - // CHANGE: Remove HDDP variable code. - - FullPath = NULL; - // - // If we get here we fail to find or 'HDDP' not exist, and now we need - // to search all devices in the system for a matched partition - // - // CHANGE: Only connect all on failure. - // - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer); - if (EFI_ERROR(Status)) { - BlockIoHandleCount = 0; - BlockIoBuffer = NULL; - } - // - // Loop through all the device handles that support the BLOCK_IO Protocol - // CHANGE: Locate ESP when failing to find an exact match - // - LocateEsp = FALSE; - do { - for (Index = 0; Index < BlockIoHandleCount; Index++) { - BlockIoDevicePath = DevicePathFromHandle (BlockIoBuffer[Index]); - if (BlockIoDevicePath == NULL) { - continue; - } - - if (BmMatchPartitionDevicePathNode (BlockIoBuffer[Index], BlockIoDevicePath, (HARDDRIVE_DEVICE_PATH *) FilePath, LocateEsp)) { - // - // Find the matched partition device path - // - TempDevicePath = AppendDevicePath (BlockIoDevicePath, NextDevicePathNode (FilePath)); - FullPath = OcGetNextLoadOptionDevicePath (TempDevicePath, NULL); - FreePool (TempDevicePath); - - if (FullPath != NULL) { - break; - } - } - } - - if (FullPath != NULL) { - break; - } - - if (!mConnectAllExecuted) { - InternalConnectAll (); - FullPath = BmExpandPartitionDevicePath (FilePath); - break; - } - - if (LocateEsp) { - break; - } - LocateEsp = TRUE; - } while (TRUE); - - if (BlockIoBuffer != NULL) { - FreePool (BlockIoBuffer); - } - - return FullPath; -} - -/** - Connect the specific Usb device which match the short form device path, - and whose bus is determined by Host Controller (Uhci or Ehci). - - @param DevicePath A short-form device path that starts with the first - element being a USB WWID or a USB Class device - path - - @return EFI_INVALID_PARAMETER DevicePath is NULL pointer. - DevicePath is not a USB device path. - - @return EFI_SUCCESS Success to connect USB device - @return EFI_NOT_FOUND Fail to find handle for USB controller to connect. - -**/ -STATIC -EFI_STATUS -BmConnectUsbShortFormDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE *Handles; - UINTN HandleCount; - UINTN Index; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Class[3]; - BOOLEAN AtLeastOneConnected; - - // - // Check the passed in parameters - // - if (DevicePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) || - ((DevicePathSubType (DevicePath) != MSG_USB_CLASS_DP) && (DevicePathSubType (DevicePath) != MSG_USB_WWID_DP)) - ) { - return EFI_INVALID_PARAMETER; - } - - // - // Find the usb host controller firstly, then connect with the remaining device path - // - AtLeastOneConnected = FALSE; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &Handles - ); - if (!EFI_ERROR(Status)) { - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - Handles[Index], - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo - ); - if (!EFI_ERROR(Status)) { - // - // Check whether the Pci device is the wanted usb host controller - // - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class); - if (!EFI_ERROR(Status) && - ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1])) - ) { - Status = gBS->ConnectController ( - Handles[Index], - NULL, - DevicePath, - FALSE - ); - if (!EFI_ERROR(Status)) { - AtLeastOneConnected = TRUE; - } - } - } - } - - if (Handles != NULL) { - FreePool (Handles); - } - } - - return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND; -} - -EFI_DEVICE_PATH_PROTOCOL * -OcGetNextLoadOptionDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN EFI_DEVICE_PATH_PROTOCOL *FullPath - ) -{ - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *Node; - EFI_STATUS Status; - - ASSERT (FilePath != NULL); - - // - // CHANGE: If SimpleFileSystem is located, the device path is already expanded. - // - Node = FilePath; - Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &Node, &Handle); - if (!EFI_ERROR(Status)) { - if (FullPath != NULL) { - return NULL; - } - - return DuplicateDevicePath (FilePath); - } - - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &Node, &Handle); - if (!EFI_ERROR(Status) && IsDevicePathEnd (Node)) { - return BmExpandMediaDevicePath (FilePath, FullPath, Handle); - } - - // CHANGE: File Path node support removed. - - // - // Expand the short-form device path to full device path - // - if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) && - (DevicePathSubType (FilePath) == MEDIA_HARDDRIVE_DP)) { - // - // Expand the Harddrive device path - // - if (FullPath == NULL) { - return BmExpandPartitionDevicePath (FilePath); - } else { - return NULL; - } - } else if ((DevicePathType (FilePath) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (FilePath) == MSG_URI_DP)) { - // - // CHANGE: Removed expansion of the URI device path - // - return NULL; - } else { - Node = FilePath; - Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &Node, &Handle); - if (EFI_ERROR(Status)) { - // - // Only expand the USB WWID/Class device path - // when FilePath doesn't point to a physical UsbIo controller. - // Otherwise, infinite recursion will happen. - // - for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) { - if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && - ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) || (DevicePathSubType (Node) == MSG_USB_WWID_DP))) { - break; - } - } - - // - // Expand the USB WWID/Class device path - // - if (!IsDevicePathEnd (Node)) { - if (FilePath == Node) { - // - // Boot Option device path starts with USB Class or USB WWID device path. - // For Boot Option device path which doesn't begin with the USB Class or - // USB WWID device path, it's not needed to connect again here. - // - BmConnectUsbShortFormDevicePath (FilePath); - } - return BmExpandUsbDevicePath (FilePath, FullPath, Node); - } - } - } - - // - // For the below cases, FilePath only expands to one Full path. - // So just handle the case when FullPath == NULL. - // - if (FullPath != NULL) { - return NULL; - } - - // CHANGE: SimleFileSystem case has been covered at the beginning of the function - - // CHANGE: Removed FV support. - - // - // CHANGE: Remove LoadFile support (e.g. PXE network boot). - // - return NULL; -} diff --git a/Library/OcDevicePathLib/OcDevicePathLib.c b/Library/OcDevicePathLib/OcDevicePathLib.c deleted file mode 100755 index aa0dbafcb..000000000 --- a/Library/OcDevicePathLib/OcDevicePathLib.c +++ /dev/null @@ -1,998 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_DEVICE_PATH_PROTOCOL * -AppendFileNameDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CHAR16 *FileName - ) -{ - EFI_DEVICE_PATH_PROTOCOL *AppendedDevicePath; - - FILEPATH_DEVICE_PATH *FilePathNode; - EFI_DEVICE_PATH_PROTOCOL *DevicePathEndNode; - UINTN FileNameSize; - UINTN FileDevicePathNodeSize; - - AppendedDevicePath = NULL; - - if (DevicePath != NULL && FileName != NULL) { - FileNameSize = StrSize (FileName); - FileDevicePathNodeSize = (FileNameSize + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH); - FilePathNode = AllocateZeroPool (FileDevicePathNodeSize); - - if (FilePathNode != NULL) { - FilePathNode->Header.Type = MEDIA_DEVICE_PATH; - FilePathNode->Header.SubType = MEDIA_FILEPATH_DP; - - SetDevicePathNodeLength (&FilePathNode->Header, FileNameSize + SIZE_OF_FILEPATH_DEVICE_PATH); - - CopyMem (FilePathNode->PathName, FileName, FileNameSize); - - DevicePathEndNode = NextDevicePathNode (&FilePathNode->Header); - - SetDevicePathEndNode (DevicePathEndNode); - - AppendedDevicePath = AppendDevicePath (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)FilePathNode); - - FreePool (FilePathNode); - } - } - - return AppendedDevicePath; -} - -EFI_DEVICE_PATH_PROTOCOL * -FindDevicePathNodeWithType ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT8 Type, - IN UINT8 SubType OPTIONAL - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; - - DevicePathNode = NULL; - - while (!IsDevicePathEnd (DevicePath)) { - if ((DevicePathType (DevicePath) == Type) - && ((SubType == 0) || (DevicePathSubType (DevicePath) == SubType))) { - DevicePathNode = DevicePath; - - break; - } - - DevicePath = NextDevicePathNode (DevicePath); - } - - return DevicePathNode; -} - -EFI_DEVICE_PATH_PROTOCOL * -AbsoluteDevicePath ( - IN EFI_HANDLE Handle, - IN EFI_DEVICE_PATH_PROTOCOL *RelativePath OPTIONAL - ) -{ - EFI_DEVICE_PATH_PROTOCOL *HandlePath; - EFI_DEVICE_PATH_PROTOCOL *NewPath; - - HandlePath = DevicePathFromHandle (Handle); - if (HandlePath == NULL) { - return NULL; - } - - if (RelativePath == NULL) { - return DuplicateDevicePath (HandlePath); - } - - NewPath = AppendDevicePath (HandlePath, RelativePath); - - if (NewPath == NULL) { - return DuplicateDevicePath (HandlePath); - } - - return NewPath; -} - -EFI_DEVICE_PATH_PROTOCOL * -TrailedBooterDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - FILEPATH_DEVICE_PATH *FilePath; - FILEPATH_DEVICE_PATH *NewFilePath; - UINTN Length; - UINTN Size; - - DevicePathWalker = DevicePath; - - while (!IsDevicePathEnd (DevicePathWalker)) { - if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) - && (DevicePathSubType (DevicePathWalker) == MEDIA_FILEPATH_DP) - && IsDevicePathEnd (NextDevicePathNode (DevicePathWalker))) { - FilePath = (FILEPATH_DEVICE_PATH *) DevicePathWalker; - Length = OcFileDevicePathNameLen (FilePath); - if (Length > 0) { - if (FilePath->PathName[Length - 1] == L'\\') { - // - // Already appended, good. It should never be true with Apple entries though. - // - return NULL; - } else if (Length > 4 && (FilePath->PathName[Length - 4] != '.' - || (FilePath->PathName[Length - 3] != 'e' && FilePath->PathName[Length - 3] != 'E') - || (FilePath->PathName[Length - 2] != 'f' && FilePath->PathName[Length - 2] != 'F') - || (FilePath->PathName[Length - 1] != 'i' && FilePath->PathName[Length - 1] != 'I'))) { - // - // Found! We should have gotten something like: - // PciRoot(0x0)/Pci(...)/Pci(...)/Sata(...)/HD(...)/\com.apple.recovery.boot - // - - Size = GetDevicePathSize (DevicePath); - NewDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (Size + sizeof (CHAR16)); - if (NewDevicePath == NULL) { - // - // Allocation failure, just ignore. - // - return NULL; - } - // - // Strip the string termination and DP end node, which will get re-set - // - CopyMem (NewDevicePath, DevicePath, Size - sizeof (CHAR16) - END_DEVICE_PATH_LENGTH); - NewFilePath = (FILEPATH_DEVICE_PATH *) ((UINT8 *)DevicePathWalker - (UINT8 *)DevicePath + (UINT8 *)NewDevicePath); - Size = DevicePathNodeLength (DevicePathWalker) + sizeof (CHAR16); - SetDevicePathNodeLength (NewFilePath, Size); - NewFilePath->PathName[Length] = L'\\'; - NewFilePath->PathName[Length+1] = L'\0'; - SetDevicePathEndNode ((UINT8 *) NewFilePath + Size); - return NewDevicePath; - } - } - } - - DevicePathWalker = NextDevicePathNode (DevicePathWalker); - } - - // - // Has .efi suffix or unsupported format. - // - return NULL; -} - -VOID -OcFixAppleBootDevicePathNodeRestore ( - IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, - IN CONST APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext - ) -{ - EFI_DEV_PATH_PTR Node; - UINT8 NodeType; - UINT8 NodeSubType; - - // - // ATTENTION: This function must be carefully sync'd with changes to - // OcFixAppleBootDevicePathNode(). - // - - Node.DevPath = DevicePathNode; - - NodeType = DevicePathType (Node.DevPath); - NodeSubType = DevicePathSubType (Node.DevPath); - - if (NodeType == MESSAGING_DEVICE_PATH) { - switch (NodeSubType) { - case MSG_SATA_DP: - Node.Sata->PortMultiplierPortNumber = RestoreContext->Sata.PortMultiplierPortNumber; - break; - - // - // The related patches in OcFixAppleBootDevicePathNode() are performed - // from MSG_SASEX_DP and MSG_NVME_NAMESPACE_DP but change the SubType. - // Please refer to the destination rather than the source SubType when - // matching the logic. - // - case MSG_NVME_NAMESPACE_DP: - case 0x22: - Node.NvmeNamespace->Header.SubType = RestoreContext->SasExNvme.SubType; - break; - - default: - break; - } - } else if (NodeType == ACPI_DEVICE_PATH) { - switch (NodeSubType) { - case ACPI_DP: - Node.Acpi->HID = RestoreContext->Acpi.HID; - Node.Acpi->UID = RestoreContext->Acpi.UID; - break; - - case ACPI_EXTENDED_DP: - Node.ExtendedAcpi->HID = RestoreContext->ExtendedAcpi.HID; - Node.ExtendedAcpi->CID = RestoreContext->ExtendedAcpi.CID; - break; - - default: - break; - } - } -} - -INTN -OcFixAppleBootDevicePathNode ( - IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, - OUT APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext OPTIONAL - ) -{ - EFI_DEV_PATH_PTR Node; - UINT8 NodeType; - UINT8 NodeSubType; - UINTN NodeSize; - - ASSERT (DevicePathNode != NULL); - - // - // ATTENTION: Changes to this function must be carefully sync'd with - // OcFixAppleBootDevicePathNodeRestore(). - // - - Node.DevPath = DevicePathNode; - - NodeType = DevicePathType (Node.DevPath); - NodeSubType = DevicePathSubType (Node.DevPath); - - if (NodeType == MESSAGING_DEVICE_PATH) { - switch (NodeSubType) { - case MSG_SATA_DP: - if (RestoreContext != NULL) { - RestoreContext->Sata.PortMultiplierPortNumber = Node.Sata->PortMultiplierPortNumber; - } - - if (Node.Sata->PortMultiplierPortNumber != 0xFFFF) { - // - // Must be set to 0xFFFF if the device is directly connected to the - // HBA. This rule has been established by UEFI 2.5 via an Erratum - // and has not been followed by Apple thus far. - // Reference: AppleACPIPlatform.kext, - // appendSATADevicePathNodeForIOMedia - // - Node.Sata->PortMultiplierPortNumber = 0xFFFF; - return 1; - } - - return -1; - - case MSG_SASEX_DP: - // - // Apple uses SubType 0x16 (SasEx) for NVMe, while the UEFI - // Specification defines it as SubType 0x17. The structures are - // identical. - // Reference: AppleACPIPlatform.kext, - // appendNVMeDevicePathNodeForIOMedia - // - if (RestoreContext != NULL) { - RestoreContext->SasExNvme.SubType = Node.DevPath->SubType; - } -/* - STATIC_ASSERT ( - sizeof (SASEX_DEVICE_PATH) != sizeof (NVME_NAMESPACE_DEVICE_PATH), - "SasEx and NVMe DPs must differ in size for fixing to be accurate." - ); -*/ - NodeSize = DevicePathNodeLength (Node.DevPath); - if (NodeSize == sizeof (NVME_NAMESPACE_DEVICE_PATH)) { - Node.SasEx->Header.SubType = MSG_NVME_NAMESPACE_DP; - return 1; - } - - return -1; - - case MSG_NVME_NAMESPACE_DP: - // - // Apple MacPro5,1 includes NVMe driver, however, it contains a typo in MSG_SASEX_DP. - // Instead of 0x16 aka 22 (SasEx) it uses 0x22 aka 34 (Unspecified). - // Here we replace it with the "right" value. - // Reference: https://forums.macrumors.com/posts/28169441. - // - if (RestoreContext != NULL) { - RestoreContext->SasExNvme.SubType = Node.DevPath->SubType; - } - - Node.NvmeNamespace->Header.SubType = 0x22; - return 1; - - default: - break; - } - } else if (NodeType == ACPI_DEVICE_PATH) { - switch (NodeSubType) { - case ACPI_DP: - if (RestoreContext != NULL) { - RestoreContext->Acpi.HID = Node.Acpi->HID; - RestoreContext->Acpi.UID = Node.Acpi->UID; - } - - if (EISA_ID_TO_NUM (Node.Acpi->HID) == 0x0A03) { - // - // In some firmwares UIDs for PciRoot do not match between ACPI tables and UEFI - // UEFI Device Paths. The former contain 0x00, 0x40, 0x80, 0xC0 values, while - // the latter have ascending numbers. - // Reference: https://github.com/acidanthera/bugtracker/issues/664. - // On other boards it is be even more erratic, refer to: - // https://github.com/acidanthera/bugtracker/issues/664#issuecomment-647526506 - // - switch (Node.Acpi->UID) { - case 0x10: - case 0x40: - Node.Acpi->UID = 1; - return 1; - - case 0x20: - case 0x80: - Node.Acpi->UID = 2; - return 1; - - case 0x28: - case 0xC0: - Node.Acpi->UID = 3; - return 1; - - case 0x30: - Node.Acpi->UID = 4; - return 1; - - case 0x38: - Node.Acpi->UID = 5; - return 1; - - default: - break; - } - // - // Apple uses PciRoot (EISA 0x0A03) nodes while some firmwares might use - // PcieRoot (EISA 0x0A08). - // - Node.Acpi->HID = BitFieldWrite32 ( - Node.Acpi->HID, - 16, - 31, - 0x0A08 - ); - return 1; - } - - return -1; - - case ACPI_EXTENDED_DP: - if (RestoreContext != NULL) { - RestoreContext->ExtendedAcpi.HID = Node.ExtendedAcpi->HID; - RestoreContext->ExtendedAcpi.CID = Node.ExtendedAcpi->CID; - } - // - // Apple uses PciRoot (EISA 0x0A03) nodes while some firmwares might use - // PcieRoot (EISA 0x0A08). - // - if (EISA_ID_TO_NUM (Node.ExtendedAcpi->HID) == 0x0A03) { - Node.ExtendedAcpi->HID = BitFieldWrite32 ( - Node.ExtendedAcpi->HID, - 16, - 31, - 0x0A08 - ); - return 1; - } - - if (EISA_ID_TO_NUM (Node.ExtendedAcpi->CID) == 0x0A03 - && EISA_ID_TO_NUM (Node.ExtendedAcpi->HID) != 0x0A08) { - Node.ExtendedAcpi->CID = BitFieldWrite32 ( - Node.ExtendedAcpi->CID, - 16, - 31, - 0x0A08 - ); - return 1; - } - - return -1; - - default: - break; - } - } - - return 0; -} - -INTN -OcFixAppleBootDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ) -{ - INTN Result; - INTN NodePatched; - - EFI_DEVICE_PATH_PROTOCOL *OriginalDevPath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - - APPLE_BOOT_DP_PATCH_CONTEXT FirstNodeRestoreContext; - APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContextPtr; - - EFI_HANDLE Device; - - ASSERT (DevicePath != NULL); - ASSERT (*DevicePath != NULL); - ASSERT (IsDevicePathValid (*DevicePath, 0)); - - OriginalDevPath = *DevicePath; - // - // Restoring is only required for the first Device Path node. Please refer - // to the loop for an explanation. - // - RestoreContextPtr = &FirstNodeRestoreContext; - NodePatched = 0; - do { - // - // Retrieve the first Device Path node that cannot be located. - // - RemainingDevicePath = OriginalDevPath; - gBS->LocateDevicePath ( - &gEfiDevicePathProtocolGuid, - &RemainingDevicePath, - &Device - ); - // - // Patch the potentially invalid node. - // - Result = OcFixAppleBootDevicePathNode ( - RemainingDevicePath, - RestoreContextPtr - ); - // - // Save a restore context only for the first processing of the first node. - // The reason for this is when the first node cannot be located with any - // patch applied, the Device Path may be of a prefix short-form and may - // possibly be expanded successfully unmodified. - // - RestoreContextPtr = NULL; - // - // Continue as long as nodes are being patched. Remember patch status. - // - NodePatched |= Result > 0; - } while (Result > 0); - - *DevicePath = RemainingDevicePath; - - if (Result < 0) { - // - // If the path could not be fixed, restore the first node if it's the one - // failing to be located. Please refer to the loop for an explanation. - // If advancing by at least one node happened, the Device Path cannot - // be of a prefix short-form and hence restoring is not beneficial (and most - // especially would require tracking every node individually). - // - if (NodePatched != 0 && RemainingDevicePath == OriginalDevPath) { - OcFixAppleBootDevicePathNodeRestore ( - OriginalDevPath, - &FirstNodeRestoreContext - ); - } - - return -1; - } - - return NodePatched; -} - -STATIC -BOOLEAN -InternalFileDevicePathsEqualClipBottom ( - IN CONST FILEPATH_DEVICE_PATH *FilePath, - IN OUT UINTN *FilePathLength, - IN OUT UINTN *ClipIndex - ) -{ - UINTN Index; - - ASSERT (FilePathLength != NULL); - ASSERT (*FilePathLength != 0); - ASSERT (FilePath != NULL); - ASSERT (ClipIndex != NULL); - - Index = *ClipIndex; - if (FilePath->PathName[Index] == L'\\') { - *ClipIndex = Index + 1; - --(*FilePathLength); - return TRUE; - } - - return FALSE; -} - -STATIC -UINTN -InternalFileDevicePathsEqualClipNode ( - IN FILEPATH_DEVICE_PATH **FilePath, - OUT UINTN *ClipIndex - ) -{ - EFI_DEV_PATH_PTR DevPath; - UINTN Index; - - UINTN Length; - EFI_DEVICE_PATH_PROTOCOL *NextNode; - - ASSERT (FilePath != NULL); - ASSERT (ClipIndex != NULL); - // - // It is unlikely to be encountered, but empty nodes are not forbidden. - // - for ( - Length = 0, NextNode = &(*FilePath)->Header; - Length == 0; - NextNode = NextDevicePathNode (DevPath.DevPath) - ) { - DevPath.DevPath = NextNode; - - if ((DevicePathType (DevPath.DevPath) != MEDIA_DEVICE_PATH) - || (DevicePathSubType (DevPath.DevPath) != MEDIA_FILEPATH_DP)) { - return 0; - } - - Length = OcFileDevicePathNameLen (DevPath.FilePath); - if (Length > 0) { - Index = 0; - InternalFileDevicePathsEqualClipBottom (DevPath.FilePath, &Length, &Index); - if ((Length > 0) - && DevPath.FilePath->PathName[Index + Length - 1] == L'\\') { - --Length; - } - - *ClipIndex = Index; - } - } - - *FilePath = DevPath.FilePath; - return Length; -} - -STATIC -UINTN -InternalFileDevicePathsEqualClipNextNode ( - IN FILEPATH_DEVICE_PATH **FilePath, - OUT UINTN *ClipIndex - ) -{ - ASSERT (FilePath != NULL); - ASSERT (ClipIndex != NULL); - - *FilePath = (FILEPATH_DEVICE_PATH *)NextDevicePathNode (*FilePath); - return InternalFileDevicePathsEqualClipNode (FilePath, ClipIndex); -} - -BOOLEAN -InternalFileDevicePathsEqualWorker ( - IN FILEPATH_DEVICE_PATH **FilePath1, - IN FILEPATH_DEVICE_PATH **FilePath2 - ) -{ - UINTN Clip1Index; - UINTN Clip2Index; - UINTN Len1; - UINTN Len2; - UINTN CurrentLen; - UINTN Index; - CHAR16 Char1; - CHAR16 Char2; - BOOLEAN Result; - - ASSERT (FilePath1 != NULL); - ASSERT (*FilePath1 != NULL); - ASSERT (FilePath2 != NULL); - ASSERT (*FilePath2 != NULL); - - ASSERT (IsDevicePathValid (&(*FilePath1)->Header, 0)); - ASSERT (IsDevicePathValid (&(*FilePath2)->Header, 0)); - - Len1 = InternalFileDevicePathsEqualClipNode (FilePath1, &Clip1Index); - Len2 = InternalFileDevicePathsEqualClipNode (FilePath2, &Clip2Index); - - do { - if ((Len1 == 0) && (Len2 == 0)) { - return TRUE; - } - - CurrentLen = MIN (Len1, Len2); - if (CurrentLen == 0) { - return FALSE; - } - // - // FIXME: Discuss case sensitivity. For UEFI FAT, case insensitivity is - // guaranteed. - // - for (Index = 0; Index < CurrentLen; ++Index) { - Char1 = CharToUpper ((*FilePath1)->PathName[Clip1Index + Index]); - Char2 = CharToUpper ((*FilePath2)->PathName[Clip2Index + Index]); - if (Char1 != Char2) { - return FALSE; - } - } - - if (Len1 == Len2) { - Len1 = InternalFileDevicePathsEqualClipNextNode (FilePath1, &Clip1Index); - Len2 = InternalFileDevicePathsEqualClipNextNode (FilePath2, &Clip2Index); - } else if (Len1 < Len2) { - Len1 = InternalFileDevicePathsEqualClipNextNode (FilePath1, &Clip1Index); - if (Len1 == 0) { - return FALSE; - } - - Len2 -= CurrentLen; - Clip2Index += CurrentLen; - // - // Switching to the next node for the other Device Path implies a path - // separator. Verify we hit such in the currently walked path too. - // - Result = InternalFileDevicePathsEqualClipBottom (*FilePath2, &Len2, &Clip2Index); - if (!Result) { - return FALSE; - } - } else { - Len2 = InternalFileDevicePathsEqualClipNextNode (FilePath2, &Clip2Index); - if (Len2 == 0) { - return FALSE; - } - - Len1 -= CurrentLen; - Clip1Index += CurrentLen; - // - // Switching to the next node for the other Device Path implies a path - // separator. Verify we hit such in the currently walked path too. - // - Result = InternalFileDevicePathsEqualClipBottom (*FilePath1, &Len1, &Clip1Index); - if (!Result) { - return FALSE; - } - } - } while (TRUE); -} - -/** - Check whether File Device Paths are equal. - - @param[in] FilePath1 The first device path protocol to compare. - @param[in] FilePath2 The second device path protocol to compare. - - @retval TRUE The device paths matched - @retval FALSE The device paths were different -**/ -BOOLEAN -FileDevicePathsEqual ( - IN FILEPATH_DEVICE_PATH *FilePath1, - IN FILEPATH_DEVICE_PATH *FilePath2 - ) -{ - ASSERT (FilePath1 != NULL); - ASSERT (FilePath2 != NULL); - - return InternalFileDevicePathsEqualWorker (&FilePath1, &FilePath2); -} - -STATIC -BOOLEAN -InternalDevicePathCmpWorker ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentPath, - IN EFI_DEVICE_PATH_PROTOCOL *ChildPath, - IN BOOLEAN CheckChild - ) -{ - BOOLEAN Result; - INTN CmpResult; - - EFI_DEV_PATH_PTR ChildPathPtr; - EFI_DEV_PATH_PTR ParentPathPtr; - - UINT8 NodeType; - UINT8 NodeSubType; - UINTN NodeSize; - - ASSERT (ParentPath != NULL); - ASSERT (IsDevicePathValid (ParentPath, 0)); - ASSERT (ChildPath != NULL); - ASSERT (IsDevicePathValid (ChildPath, 0)); - - ParentPathPtr.DevPath = ParentPath; - ChildPathPtr.DevPath = ChildPath; - - while (TRUE) { - NodeType = DevicePathType (ChildPathPtr.DevPath); - NodeSubType = DevicePathSubType (ChildPathPtr.DevPath); - - if (NodeType == END_DEVICE_PATH_TYPE) { - // - // We only support single-instance Device Paths. - // - ASSERT (NodeSubType == END_ENTIRE_DEVICE_PATH_SUBTYPE); - return (CheckChild - || (DevicePathType (ParentPathPtr.DevPath) == END_DEVICE_PATH_TYPE)); - } - - if ((DevicePathType (ParentPathPtr.DevPath) != NodeType) - || (DevicePathSubType (ParentPathPtr.DevPath) != NodeSubType)) { - return FALSE; - } - - if ((NodeType == MEDIA_DEVICE_PATH) - && (NodeSubType == MEDIA_FILEPATH_DP)) { - // - // File Paths need special consideration for prepended and appended - // terminators, as well as multiple nodes. - // - Result = InternalFileDevicePathsEqualWorker ( - &ParentPathPtr.FilePath, - &ChildPathPtr.FilePath - ); - if (!Result) { - return FALSE; - } - // - // InternalFileDevicePathsEqualWorker advances the nodes. - // - } else { - NodeSize = DevicePathNodeLength (ChildPathPtr.DevPath); - if (DevicePathNodeLength (ParentPathPtr.DevPath) != NodeSize) { - return FALSE; - } -/* - STATIC_ASSERT ( - (sizeof (*ChildPathPtr.DevPath) == 4), - "The Device Path comparison logic depends on the entire header being checked" - ); -*/ - CmpResult = CompareMem ( - (ChildPathPtr.DevPath + 1), - (ParentPathPtr.DevPath + 1), - (NodeSize - sizeof (*ChildPathPtr.DevPath)) - ); - if (CmpResult != 0) { - return FALSE; - } - - ParentPathPtr.DevPath = NextDevicePathNode (ParentPathPtr.DevPath); - ChildPathPtr.DevPath = NextDevicePathNode (ChildPathPtr.DevPath); - } - } -} - -BOOLEAN -EFIAPI -IsDevicePathEqual ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ) -{ - return InternalDevicePathCmpWorker (DevicePath1, DevicePath2, FALSE); -} - -BOOLEAN -EFIAPI -IsDevicePathChild ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentPath, - IN EFI_DEVICE_PATH_PROTOCOL *ChildPath - ) -{ - return InternalDevicePathCmpWorker (ParentPath, ChildPath, TRUE); -} - -UINTN -OcFileDevicePathNameSize ( - IN CONST FILEPATH_DEVICE_PATH *FilePath - ) -{ - ASSERT (FilePath != NULL); - ASSERT (IsDevicePathValid (&FilePath->Header, 0)); - return (OcFileDevicePathNameLen (FilePath) + 1) * sizeof (*FilePath->PathName); -} - -UINTN -OcFileDevicePathNameLen ( - IN CONST FILEPATH_DEVICE_PATH *FilePath - ) -{ - UINTN Size; - UINTN Len; - - ASSERT (FilePath != NULL); - ASSERT (IsDevicePathValid (&FilePath->Header, 0)); - - Size = DevicePathNodeLength (FilePath) - SIZE_OF_FILEPATH_DEVICE_PATH; - // - // Account for more than one termination character. - // - Len = (Size / sizeof (*FilePath->PathName)) - 1; - while (Len > 0 && FilePath->PathName[Len - 1] == L'\0') { - --Len; - } - - return Len; -} - -/** - Retrieve the size of the full file path described by DevicePath. - - @param[in] DevicePath The Device Path to inspect. - - @returns The size of the full file path. - @retval 0 DevicePath does not start with a File Path node or contains - non-terminating nodes that are not File Path nodes. - -**/ -UINTN -OcFileDevicePathFullNameSize ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - UINTN PathSize; - CONST FILEPATH_DEVICE_PATH *FilePath; - - ASSERT (DevicePath != NULL); - ASSERT (IsDevicePathValid (DevicePath, 0)); - - PathSize = 1; - do { - // - // On the first iteration, this ensures the path is not immediately - // terminated. - // - if (DevicePath->Type != MEDIA_DEVICE_PATH - || DevicePath->SubType != MEDIA_FILEPATH_DP) { - return 0; - } - - FilePath = (FILEPATH_DEVICE_PATH *)DevicePath; - PathSize += OcFileDevicePathNameLen (FilePath); - - DevicePath = NextDevicePathNode (DevicePath); - } while (!IsDevicePathEnd (DevicePath)); - return PathSize * sizeof (*FilePath->PathName); -} - -/** - Retrieve the full file path described by FilePath. - The caller is expected to call OcFileDevicePathFullNameSize() or ensure its - guarantees are met. - - @param[out] PathName On output, the full file path of FilePath. - @param[in] FilePath The File Device Path to inspect. - @param[in] PathNameSize The size, in bytes, of PathnName. Must equal the - actual fill file path size. - -**/ -VOID -OcFileDevicePathFullName ( - OUT CHAR16 *PathName, - IN CONST FILEPATH_DEVICE_PATH *FilePath, - IN UINTN PathNameSize - ) -{ - UINTN PathLen; - - ASSERT (PathName != NULL); - ASSERT (FilePath != NULL); - ASSERT (IsDevicePathValid (&FilePath->Header, 0)); - ASSERT (PathNameSize == OcFileDevicePathFullNameSize (&FilePath->Header)); - - // - // FIXME: Insert separators between nodes if not present already. - // - - do { - PathLen = OcFileDevicePathNameLen (FilePath); - CopyMem ( - PathName, - FilePath->PathName, - PathLen * sizeof (*FilePath->PathName) - ); - PathName += PathLen; - - FilePath = (CONST FILEPATH_DEVICE_PATH *)NextDevicePathNode (FilePath); - } while (!IsDevicePathEnd (FilePath)); - *PathName = CHAR_NULL; -} - -EFI_DEVICE_PATH_PROTOCOL * -OcAppendDevicePathInstanceDedupe ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ) -{ - INTN CmpResult; - - EFI_DEVICE_PATH_PROTOCOL *DevPathWalker; - EFI_DEVICE_PATH_PROTOCOL *CurrentInstance; - - UINTN AppendInstanceSize; - UINTN CurrentInstanceSize; - - ASSERT (DevicePathInstance != NULL); - - if (DevicePath != NULL) { - AppendInstanceSize = GetDevicePathSize (DevicePathInstance); - DevPathWalker = DevicePath; - - while (TRUE) { - CurrentInstance = GetNextDevicePathInstance ( - &DevPathWalker, - &CurrentInstanceSize - ); - if (CurrentInstance == NULL) { - break; - } - - if (CurrentInstanceSize != AppendInstanceSize) { - FreePool (CurrentInstance); - continue; - } - - CmpResult = CompareMem ( - CurrentInstance, - DevicePathInstance, - CurrentInstanceSize - ); - - FreePool (CurrentInstance); - - if (CmpResult == 0) { - return DuplicateDevicePath (DevicePath); - } - } - } - - return AppendDevicePathInstance (DevicePath, DevicePathInstance); -} - -UINTN -OcGetNumDevicePathInstances ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - UINTN NumInstances; - - NumInstances = 1; - - while (!IsDevicePathEnd (DevicePath)) { - if (IsDevicePathEndInstance (DevicePath)) { - ++NumInstances; - } - - DevicePath = NextDevicePathNode (DevicePath); - } - - return NumInstances; -} diff --git a/Library/OcDevicePathLib/OcDevicePathLib.inf b/Library/OcDevicePathLib/OcDevicePathLib.inf deleted file mode 100755 index 029d590c9..000000000 --- a/Library/OcDevicePathLib/OcDevicePathLib.inf +++ /dev/null @@ -1,60 +0,0 @@ -## @file -# -# Component description file for OcDevicePathLibrary. -# -# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcDevicePathLib - FILE_GUID = BDEBB36A-9261-4908-9E42-FE59E0B43B82 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcDevicePathLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - OcDevicePathLib.c - ExpandDevicePath.c - ../../Include/Library/OcDevicePathLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - MemoryAllocationLib - OcFileLib - UefiBootServicesTableLib - -[Guids] - gEfiPartTypeSystemPartGuid - -[Protocols] - gEfiDevicePathToTextProtocolGuid - gEfiSimpleFileSystemProtocolGuid - gEfiBlockIoProtocolGuid - gEfiUsbIoProtocolGuid - gEfiLoadFileProtocolGuid diff --git a/Library/OcFileLib/FileProtocol.c b/Library/OcFileLib/FileProtocol.c deleted file mode 100644 index ca06a5e34..000000000 --- a/Library/OcFileLib/FileProtocol.c +++ /dev/null @@ -1,267 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -EFI_STATUS -GetFileData ( - IN EFI_FILE_PROTOCOL *File, - IN UINT32 Position, - IN UINT32 Size, - OUT UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN ReadSize; - - Status = File->SetPosition (File, Position); - if (EFI_ERROR(Status)) { - return Status; - } - - ReadSize = Size; - Status = File->Read (File, &ReadSize, Buffer); - File->SetPosition (File, 0); - if (EFI_ERROR(Status)) { - return Status; - } - - if (ReadSize != Size) { - return EFI_BAD_BUFFER_SIZE; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetFileSize ( - IN EFI_FILE_PROTOCOL *File, - OUT UINT32 *Size - ) -{ - EFI_STATUS Status; - UINT64 Position; - - Status = File->SetPosition (File, 0xFFFFFFFFFFFFFFFFULL); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = File->GetPosition (File, &Position); - File->SetPosition (File, 0); - if (EFI_ERROR(Status)) { - return Status; - } - - if ((UINT32) Position != Position) { - return EFI_OUT_OF_RESOURCES; - } - - *Size = (UINT32) Position; - - return EFI_SUCCESS; -} - -EFI_STATUS -GetFileModifcationTime ( - IN EFI_FILE_PROTOCOL *File, - OUT EFI_TIME *Time - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - EFI_FILE_INFO *FileInfo; - - BufferSize = 0; - Status = File->GetInfo (File, &gEfiFileInfoGuid, &BufferSize, NULL); - - if (Status != EFI_BUFFER_TOO_SMALL) { - return Status; - } - - if (BufferSize < sizeof (EFI_FILE_INFO)) { - return EFI_INVALID_PARAMETER; - } - - FileInfo = (EFI_FILE_INFO *) AllocatePool (BufferSize); - if (FileInfo == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = File->GetInfo (File, &gEfiFileInfoGuid, &BufferSize, FileInfo); - if (EFI_ERROR(Status)) { - FreePool (FileInfo); - return Status; - } - - CopyMem (Time, &FileInfo->ModificationTime, sizeof (*Time)); - FreePool (FileInfo); - - return EFI_SUCCESS; -} - -EFI_STATUS -FindWritableFileSystem ( - IN OUT EFI_FILE_PROTOCOL **WritableFs - ) -{ - EFI_HANDLE *HandleBuffer; - UINTN HandleCount; - UINTN Index; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; - EFI_FILE_PROTOCOL *Fs; - EFI_FILE_PROTOCOL *File; - - // - // Locate all the simple file system devices in the system. - // - EFI_STATUS Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR(Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; ++Index) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &SimpleFs - ); - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_VERBOSE, - "OCFS: FindWritableFileSystem gBS->HandleProtocol[%u] returned %r\n", - (UINT32) Index, - Status - )); - continue; - } - - Status = SimpleFs->OpenVolume (SimpleFs, &Fs); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_VERBOSE, - "OCFS: FindWritableFileSystem SimpleFs->OpenVolume[%u] returned %r\n", - (UINT32) Index, - Status - )); - continue; - } - - // - // We cannot test if the file system is writeable without attempting to create some file. - // - Status = SafeFileOpen ( - Fs, - &File, - L"octest.fil", - EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, - 0 - ); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_VERBOSE, - "OCFS: FindWritableFileSystem Fs->Open[%u] returned %r\n", - (UINT32) Index, - Status - )); - continue; - } - - // - // Delete the temporary file and report the found file system. - // - Fs->Delete (File); - *WritableFs = Fs; - break; - } - - gBS->FreePool (HandleBuffer); - - return Status; -} - -EFI_STATUS -SetFileData ( - IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL, - IN CONST CHAR16 *FileName, - IN CONST VOID *Buffer, - IN UINT32 Size - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL *Fs; - EFI_FILE_PROTOCOL *File; - UINTN WrittenSize; - - if (WritableFs == NULL) { - Status = FindWritableFileSystem (&Fs); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData can't find writable FS\n")); - return Status; - } - } else { - Fs = WritableFs; - } - - Status = SafeFileOpen ( - Fs, - &File, - (CHAR16 *) FileName, - EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, - 0 - ); - - if (!EFI_ERROR(Status)) { - WrittenSize = Size; - Status = File->Write (File, &WrittenSize, (VOID *) Buffer); - Fs->Close (File); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData file->Write returned %r\n", Status)); - } else if (WrittenSize != Size) { - DEBUG (( - DEBUG_VERBOSE, - "WriteFileData: File->Write truncated %u to %u\n", - Status, - Size, - (UINT32) WrittenSize - )); - Status = EFI_BAD_BUFFER_SIZE; - } - } else { - DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData Fs->Open of %s returned %r\n", FileName, Status)); - } - - if (WritableFs == NULL) { - Fs->Close (Fs); - } - - return Status; -} diff --git a/Library/OcFileLib/FirmwareFile.c b/Library/OcFileLib/FirmwareFile.c deleted file mode 100644 index b53c60ede..000000000 --- a/Library/OcFileLib/FirmwareFile.c +++ /dev/null @@ -1,113 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC -EFI_HANDLE -GetFvFileVolume ( - IN EFI_GUID *FvNameGuid - ) -{ - UINTN Index; - EFI_STATUS Status; - UINT32 AuthenticationStatus; - EFI_FIRMWARE_VOLUME_PROTOCOL *FirmwareVolumeInterface; - UINTN NumOfHandles; - EFI_HANDLE *HandleBuffer; - EFI_FV_FILETYPE Type; - UINTN Size; - EFI_FV_FILE_ATTRIBUTES Attributes; - EFI_HANDLE CurrentVolume; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolumeProtocolGuid, - NULL, - &NumOfHandles, - &HandleBuffer - ); - - // - // TODO: Support FirmwareVolume2? - // - if (EFI_ERROR(Status)) { - return NULL; - } - - for (Index = 0; Index < NumOfHandles; ++Index) { - CurrentVolume = HandleBuffer[Index]; - - Status = gBS->HandleProtocol ( - CurrentVolume, - &gEfiFirmwareVolumeProtocolGuid, - (VOID **) &FirmwareVolumeInterface - ); - - if (EFI_ERROR(Status)) { - continue; - } - - Status = FirmwareVolumeInterface->ReadFile ( - FirmwareVolumeInterface, - FvNameGuid, - NULL, - &Size, - &Type, - &Attributes, - &AuthenticationStatus - ); - - if (!EFI_ERROR(Status)) { - gBS->FreePool (HandleBuffer); - return CurrentVolume; - } - } - - gBS->FreePool (HandleBuffer); - return NULL; -} - -EFI_DEVICE_PATH_PROTOCOL * -CreateFvFileDevicePath ( - IN EFI_GUID *FileGuid - ) -{ - EFI_HANDLE VolumeHandle; - EFI_DEVICE_PATH_PROTOCOL *VolumeDevicePath; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode; - - VolumeHandle = GetFvFileVolume (FileGuid); - if (VolumeHandle == NULL) { - return NULL; - } - - VolumeDevicePath = DevicePathFromHandle (VolumeHandle); - if (VolumeDevicePath == NULL) { - return NULL; - } - - EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid); - return AppendDevicePathNode (VolumeDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode); -} diff --git a/Library/OcFileLib/FsConnectQuirk.c b/Library/OcFileLib/FsConnectQuirk.c deleted file mode 100644 index caf8a7516..000000000 --- a/Library/OcFileLib/FsConnectQuirk.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - Copyright (C) 2019, Download-Fritz. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#include - -#include -#include - -#include -#include -#include - -/** - Unblocks all partition handles without a File System protocol attached from - driver connection, if applicable. - -**/ -VOID -OcUnblockUnmountedPartitions ( - VOID - ) -{ - EFI_STATUS Status; - - UINTN NumHandles; - EFI_HANDLE *Handles; - UINTN HandleIndex; - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - - UINTN NumBlockIoInfo; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *BlockIoInfos; - UINTN BlockIoInfoIndex; - // - // For all Block I/O handles, check whether it is a partition. If it is and - // does not have a File System protocol attached, ensure it does not have a - // blocking driver attached which prevents the connection of a FS driver. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiBlockIoProtocolGuid, - NULL, - &NumHandles, - &Handles - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCFSQ: Could not locate DiskIo handles\n")); - return; - } - - for (HandleIndex = 0; HandleIndex < NumHandles; ++HandleIndex) { - // - // Skip the current handle if a File System driver is already attached. - // - Status = gBS->HandleProtocol ( - Handles[HandleIndex], - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - if (!EFI_ERROR(Status)) { - continue; - } - // - // Ensure the current handle describes a partition. - // - Status = gBS->HandleProtocol ( - Handles[HandleIndex], - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo - ); - if (EFI_ERROR(Status) || !BlockIo->Media->LogicalPartition) { - continue; - } - // - // Disconnect any blocking drivers if applicable. - // - Status = gBS->OpenProtocolInformation ( - Handles[HandleIndex], - &gEfiBlockIoProtocolGuid, - &BlockIoInfos, - &NumBlockIoInfo - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCFSQ: Attached drivers could not been retrieved\n")); - continue; - } - - for (BlockIoInfoIndex = 0; BlockIoInfoIndex < NumBlockIoInfo; ++BlockIoInfoIndex) { - if ((BlockIoInfos[BlockIoInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - Status = gBS->DisconnectController ( - Handles[HandleIndex], - BlockIoInfos[BlockIoInfoIndex].AgentHandle, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCFSQ: Failed to unblock handle %p - %r\n", - Handles[HandleIndex], - Status - )); - } - } - } - - FreePool (BlockIoInfos); - } - - FreePool (Handles); -} diff --git a/Library/OcFileLib/GetFileInfo.c b/Library/OcFileLib/GetFileInfo.c deleted file mode 100755 index 9cdddd7a7..000000000 --- a/Library/OcFileLib/GetFileInfo.c +++ /dev/null @@ -1,78 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -VOID * -GetFileInfo ( - IN EFI_FILE_PROTOCOL *File, - IN EFI_GUID *InformationType, - IN UINTN MinFileInfoSize, - OUT UINTN *RealFileInfoSize OPTIONAL - ) -{ - VOID *FileInfoBuffer; - - UINTN FileInfoSize; - EFI_STATUS Status; - - FileInfoSize = 0; - FileInfoBuffer = NULL; - - Status = File->GetInfo ( - File, - InformationType, - &FileInfoSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL && FileInfoSize >= MinFileInfoSize) { - FileInfoBuffer = AllocateZeroPool (FileInfoSize); - - if (FileInfoBuffer != NULL) { - Status = File->GetInfo ( - File, - InformationType, - &FileInfoSize, - FileInfoBuffer - ); - - if (!EFI_ERROR(Status)) { - if (RealFileInfoSize != NULL) { - *RealFileInfoSize = FileInfoSize; - } - } else { - FreePool (FileInfoBuffer); - - FileInfoBuffer = NULL; - } - } - } - - return FileInfoBuffer; -} diff --git a/Library/OcFileLib/GetVolumeLabel.c b/Library/OcFileLib/GetVolumeLabel.c deleted file mode 100755 index 6992e9ce7..000000000 --- a/Library/OcFileLib/GetVolumeLabel.c +++ /dev/null @@ -1,94 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CHAR16 * -GetVolumeLabel ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem - ) -{ - EFI_STATUS Status; - - EFI_FILE_HANDLE Volume; - EFI_FILE_SYSTEM_VOLUME_LABEL *VolumeInfo; - UINTN VolumeLabelSize; - - ASSERT (FileSystem != NULL); - - Volume = NULL; - Status = FileSystem->OpenVolume ( - FileSystem, - &Volume - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - VolumeInfo = GetFileInfo ( - Volume, - &gEfiFileSystemVolumeLabelInfoIdGuid, - sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL), - &VolumeLabelSize - ); - - Volume->Close (Volume); -/* - STATIC_ASSERT ( - OFFSET_OF(EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel) == 0, - "Expected EFI_FILE_SYSTEM_VOLUME_LABEL to represent CHAR16 string!" - ); -*/ - if (VolumeInfo != NULL) { - if (VolumeLabelSize >= sizeof (CHAR16) && VolumeInfo->VolumeLabel[0] != L'\0') { - // - // The spec requires disk label to be NULL-terminated, but it - // was unclear whether the size should contain terminator or not. - // Some old HFS Plus drivers provide volume label size without - // terminating \0 (though they do append it). These drivers must - // not be used, but we try not to die when debugging is off. - // - if (VolumeInfo->VolumeLabel[VolumeLabelSize / sizeof (CHAR16) - 1] != '\0' - || VolumeLabelSize > OC_MAX_VOLUME_LABEL_SIZE * sizeof (CHAR16)) { - DEBUG ((DEBUG_ERROR, "OCFS: Found unterminated or too long volume label!")); - FreePool (VolumeInfo); - return AllocateCopyPool (sizeof (L"INVALID"), L"INVALID"); - } else { - UnicodeFilterString (VolumeInfo->VolumeLabel, TRUE); - return VolumeInfo->VolumeLabel; - } - } - FreePool (VolumeInfo); - } - - return AllocateCopyPool (sizeof (L"NO NAME"), L"NO NAME"); -} diff --git a/Library/OcFileLib/GptPartitionEntry.c b/Library/OcFileLib/GptPartitionEntry.c deleted file mode 100644 index a4a4493a8..000000000 --- a/Library/OcFileLib/GptPartitionEntry.c +++ /dev/null @@ -1,633 +0,0 @@ -/** @file - Copyright (C) 2019, Download-Fritz. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC EFI_GUID mInternalDiskPartitionEntriesProtocolGuid = { - 0x1A81704, 0x3442, 0x4A7D, { 0x87, 0x40, 0xF4, 0xEC, 0x5B, 0xBE, 0x59, 0x77 } -}; - -STATIC EFI_GUID mInternalPartitionEntryProtocolGuid = { - 0x9FC6B19, 0xB8A1, 0x4A01, { 0x8D, 0xB1, 0x87, 0x94, 0xE7, 0x63, 0x4C, 0xA5 } -}; - -EFI_STATUS -OcDiskInitializeContext ( - OUT OC_DISK_CONTEXT *Context, - IN EFI_HANDLE DiskHandle, - IN BOOLEAN UseBlockIo2 - ) -{ - EFI_STATUS Status; - - // - // Retrieve the Block I/O protocol. - // - if (UseBlockIo2) { - Status = gBS->HandleProtocol ( - DiskHandle, - &gEfiBlockIo2ProtocolGuid, - (VOID **) &Context->BlockIo2 - ); - } else { - Context->BlockIo2 = NULL; - Status = EFI_ABORTED; - } - - if (EFI_ERROR(Status)) { - Status = gBS->HandleProtocol ( - DiskHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &Context->BlockIo - ); - } else { - Context->BlockIo = NULL; - } - - if (EFI_ERROR(Status)) { - DEBUG (( - DEBUG_INFO, - "OCPI: Block I/O (%d/%d) protocols (%d) are not present on %p - %r\n", - Context->BlockIo != NULL, - Context->BlockIo2 != NULL, - UseBlockIo2, - DiskHandle, - Status - )); - return Status; - } - - if (Context->BlockIo2 != NULL && Context->BlockIo2->Media != NULL) { - Context->BlockSize = Context->BlockIo2->Media->BlockSize; - Context->MediaId = Context->BlockIo2->Media->MediaId; - } else if (Context->BlockIo != NULL && Context->BlockIo->Media != NULL) { - Context->BlockSize = Context->BlockIo->Media->BlockSize; - Context->MediaId = Context->BlockIo->Media->MediaId; - } else { - return EFI_UNSUPPORTED; - } - - // - // Check that BlockSize is POT. - // - if (Context->BlockSize == 0 || (Context->BlockSize & (Context->BlockSize - 1)) != 0) { - DEBUG ((DEBUG_INFO, "OCPI: Block I/O has invalid block size %u\n", Context->BlockSize)); - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -OcDiskRead ( - IN OC_DISK_CONTEXT *Context, - IN UINT64 Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - - ASSERT (Context->BlockIo != NULL || Context->BlockIo2 != NULL); - ASSERT ((BufferSize & (Context->BlockSize - 1)) == 0); - - if (Context->BlockIo2 != NULL) { - Status = Context->BlockIo2->ReadBlocksEx ( - Context->BlockIo2, - Context->MediaId, - Lba, - NULL, - BufferSize, - Buffer - ); - } else { - Status = Context->BlockIo->ReadBlocks ( - Context->BlockIo, - Context->MediaId, - Lba, - BufferSize, - Buffer - ); - } - - return Status; -} - -STATIC -VOID -InternalDebugPrintPartitionEntry ( - IN UINTN ErrorLevel, - IN CONST CHAR8 *Message, - IN CONST EFI_PARTITION_ENTRY *PartitionEntry - ) -{ - ASSERT (PartitionEntry != NULL); - - DEBUG (( - ErrorLevel, - "%a:\n" - "- PartitionTypeGUID: %g\n" - "- UniquePartitionGUID: %g\n" - "- StartingLBA: %lx\n" - "- EndingLBA: %lx\n" - "- Attributes: %lx\n" - "- PartitionName: %s\n", - Message, - PartitionEntry->PartitionTypeGUID, - PartitionEntry->UniquePartitionGUID, - PartitionEntry->StartingLBA, - PartitionEntry->EndingLBA, - PartitionEntry->Attributes, - PartitionEntry->PartitionName - )); -} - -STATIC -EFI_HANDLE -InternalPartitionGetDiskHandle ( - IN EFI_DEVICE_PATH_PROTOCOL *HdDevicePath, - IN UINTN HdNodeOffset, - OUT BOOLEAN *HasBlockIo2 - ) -{ - EFI_HANDLE DiskHandle; - - EFI_STATUS Status; - - EFI_DEVICE_PATH_PROTOCOL *PrefixPath; - EFI_DEVICE_PATH_PROTOCOL *TempPath; - - ASSERT (HdDevicePath != NULL); - ASSERT (HdNodeOffset < GetDevicePathSize (HdDevicePath)); - ASSERT (HasBlockIo2 != NULL); - - PrefixPath = DuplicateDevicePath (HdDevicePath); - if (PrefixPath == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: DP allocation error\n")); - return NULL; - } - // - // Strip the HD node in order to retrieve the last node supporting Block I/O - // before it, which is going to be its disk. - // - TempPath = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)PrefixPath + HdNodeOffset); - SetDevicePathEndNode (TempPath); - - TempPath = PrefixPath; - Status = gBS->LocateDevicePath ( - &gEfiBlockIo2ProtocolGuid, - &TempPath, - &DiskHandle - ); - *HasBlockIo2 = !EFI_ERROR(Status); - - if (EFI_ERROR(Status)) { - TempPath = PrefixPath; - Status = gBS->LocateDevicePath ( - &gEfiBlockIoProtocolGuid, - &TempPath, - &DiskHandle - ); - } - - if (EFI_ERROR(Status)) { - DebugPrintDevicePath ( - DEBUG_INFO, - "OCPI: Failed to locate disk", - PrefixPath - ); - - DiskHandle = NULL; - } - - FreePool (PrefixPath); - - return DiskHandle; -} - -/** - Retrieve the disk's device handle from a partition's Device Path. - - @param[in] HdDevicePath The Device Path of the partition. - -**/ -EFI_HANDLE -OcPartitionGetDiskHandle ( - IN EFI_DEVICE_PATH_PROTOCOL *HdDevicePath - ) -{ - CONST HARDDRIVE_DEVICE_PATH *HdNode; - BOOLEAN Dummy; - - ASSERT (HdDevicePath != NULL); - - HdNode = (HARDDRIVE_DEVICE_PATH *)( - FindDevicePathNodeWithType ( - HdDevicePath, - MEDIA_DEVICE_PATH, - MEDIA_HARDDRIVE_DP - ) - ); - if (HdNode == NULL) { - return NULL; - } - - return InternalPartitionGetDiskHandle ( - HdDevicePath, - (UINTN)HdNode - (UINTN)HdDevicePath, - &Dummy - ); -} - -EFI_DEVICE_PATH_PROTOCOL * -OcDiskFindSystemPartitionPath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DiskDevicePath, - OUT UINTN *EspDevicePathSize, - OUT EFI_HANDLE *EspDeviceHandle - ) -{ - EFI_DEVICE_PATH_PROTOCOL *EspDevicePath; - - EFI_STATUS Status; - BOOLEAN Result; - INTN CmpResult; - - UINTN Index; - UINTN NumHandles; - EFI_HANDLE *Handles; - EFI_HANDLE Handle; - - UINTN DiskDpSize; - UINTN DiskDpCmpSize; - EFI_DEVICE_PATH_PROTOCOL *HdDevicePath; - UINTN HdDpSize; - - CONST EFI_PARTITION_ENTRY *PartEntry; - - ASSERT (DiskDevicePath != NULL); - ASSERT (EspDevicePathSize != NULL); - ASSERT (EspDeviceHandle != NULL); - - DebugPrintDevicePath ( - DEBUG_INFO, - "OCPI: Locating disk's ESP", - (EFI_DEVICE_PATH_PROTOCOL *)DiskDevicePath - ); - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumHandles, - &Handles - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCPI: Failed to locate FS handles\n")); - return NULL; - } - - EspDevicePath = NULL; - - DiskDpSize = GetDevicePathSize (DiskDevicePath); - // - // The partition's Device Path must be at least as big as the disk's (prefix) - // plus an additional HardDrive node. - // - Result = OcOverflowAddUN ( - DiskDpSize, - sizeof (HARDDRIVE_DEVICE_PATH), - &DiskDpCmpSize - ); - if (Result) { - DEBUG ((DEBUG_INFO, "OCPI: HD node would overflow DP\n")); - return NULL; - } - - for (Index = 0; Index < NumHandles; ++Index) { - Handle = Handles[Index]; - - HdDevicePath = DevicePathFromHandle (Handle); - if (HdDevicePath == NULL) { - continue; - } - - HdDpSize = GetDevicePathSize (HdDevicePath); - if (HdDpSize < DiskDpCmpSize) { - continue; - } - // - // Verify the partition's Device Path has the disk's prefixed. - // - CmpResult = CompareMem ( - HdDevicePath, - DiskDevicePath, - DiskDpSize - END_DEVICE_PATH_LENGTH - ); - if (CmpResult != 0) { - continue; - } - - DebugPrintDevicePath (DEBUG_INFO, "OCPI: Discovered HD DP", HdDevicePath); - - PartEntry = OcGetGptPartitionEntry (Handle); - if (PartEntry == NULL) { - continue; - } - - InternalDebugPrintPartitionEntry ( - DEBUG_INFO, - "OCPI: Discovered PartEntry", - PartEntry - ); - - if (CompareGuid (&PartEntry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) { - EspDevicePath = HdDevicePath; - *EspDevicePathSize = HdDpSize; - *EspDeviceHandle = Handle; - break; - } - } - - FreePool (Handles); - - return EspDevicePath; -} - -CONST OC_PARTITION_ENTRIES * -OcGetDiskPartitions ( - IN EFI_HANDLE DiskHandle, - IN BOOLEAN UseBlockIo2 - ) -{ - OC_PARTITION_ENTRIES *PartEntries; - - EFI_STATUS Status; - BOOLEAN Result; - - OC_DISK_CONTEXT DiskContext; - - EFI_LBA PartEntryLBA; - UINT32 NumPartitions; - UINT32 PartEntrySize; - UINTN PartEntriesSize; - UINTN PartEntriesStructSize; - UINTN BufferSize; - EFI_PARTITION_TABLE_HEADER *GptHeader; - - ASSERT (DiskHandle != NULL); - - Status = gBS->HandleProtocol ( - DiskHandle, - &mInternalDiskPartitionEntriesProtocolGuid, - (VOID **) &PartEntries - ); - if (!EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCPI: Located cached partition entries\n")); - return PartEntries; - } - - Status = OcDiskInitializeContext (&DiskContext, DiskHandle, UseBlockIo2); - if (EFI_ERROR(Status)) { - return NULL; - } - - // - // Retrieve the GPT header. - // - BufferSize = ALIGN_VALUE (sizeof (*GptHeader), DiskContext.BlockSize); - GptHeader = AllocatePool (BufferSize); - if (GptHeader == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: GPT header allocation error\n")); - return NULL; - } - - Status = OcDiskRead ( - &DiskContext, - PRIMARY_PART_HEADER_LBA, - BufferSize, - GptHeader - ); - if (EFI_ERROR(Status)) { - FreePool (GptHeader); - DEBUG (( - DEBUG_INFO, - "OCPI: ReadDisk1 (block: %u, io1: %d, io2: %d, size: %u) %r\n", - DiskContext.BlockSize, - DiskContext.BlockIo != NULL, - DiskContext.BlockIo2 != NULL, - (UINT32) BufferSize, - Status - )); - return NULL; - } - - if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID) { - FreePool (GptHeader); - DEBUG ((DEBUG_INFO, "OCPI: Partition table not supported\n")); - return NULL; - } - - PartEntrySize = GptHeader->SizeOfPartitionEntry; - if (PartEntrySize < sizeof (EFI_PARTITION_ENTRY)) { - FreePool (GptHeader); - DEBUG ((DEBUG_INFO, "OCPI: GPT header is malformed\n")); - return NULL; - } - - NumPartitions = GptHeader->NumberOfPartitionEntries; - PartEntryLBA = GptHeader->PartitionEntryLBA; - - FreePool (GptHeader); - - Result = OcOverflowMulUN (NumPartitions, PartEntrySize, &PartEntriesSize); - if (Result || MAX_UINTN - DiskContext.BlockSize < PartEntriesSize) { - DEBUG ((DEBUG_INFO, "OCPI: Partition entries size overflows\n")); - return NULL; - } - - PartEntriesSize = ALIGN_VALUE (PartEntriesSize, DiskContext.BlockSize); - - Result = OcOverflowAddUN ( - sizeof (PartEntries), - PartEntriesSize, - &PartEntriesStructSize - ); - if (Result) { - DEBUG ((DEBUG_INFO, "OCPI: Partition entries struct size overflows\n")); - return NULL; - } - // - // Retrieve the GPT partition entries. - // - PartEntries = AllocatePool (PartEntriesStructSize); - if (PartEntries == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: Partition entries allocation error\n")); - return NULL; - } - - Status = OcDiskRead ( - &DiskContext, - PartEntryLBA, - PartEntriesSize, - PartEntries->FirstEntry - ); - if (EFI_ERROR(Status)) { - FreePool (PartEntries); - DEBUG (( - DEBUG_INFO, - "OCPI: ReadDisk2 (block: %u, io1: %d, io2: %d, size: %u) %r\n", - DiskContext.BlockSize, - DiskContext.BlockIo != NULL, - DiskContext.BlockIo2 != NULL, - (UINT32) PartEntriesSize, - Status - )); - return NULL; - } - - PartEntries->NumPartitions = NumPartitions; - PartEntries->PartitionEntrySize = PartEntrySize; - // - // FIXME: This causes the handle to be dangling if the device is detached. - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &DiskHandle, - &mInternalDiskPartitionEntriesProtocolGuid, - PartEntries, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCPI: Failed to cache partition entries\n")); - FreePool (PartEntries); - return NULL; - } - - return PartEntries; -} - -/** - Retrieve the partition's GPT information, if applicable - - @param[in] FsHandle The device handle of the partition to retrieve info of. - -**/ -CONST EFI_PARTITION_ENTRY * -OcGetGptPartitionEntry ( - IN EFI_HANDLE FsHandle - ) -{ - CONST EFI_PARTITION_ENTRY *PartEntry; - CONST OC_PARTITION_ENTRIES *Partitions; - - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *FsDevicePath; - CONST HARDDRIVE_DEVICE_PATH *HdNode; - EFI_HANDLE DiskHandle; - BOOLEAN HasBlockIo2; - UINTN Offset; - - ASSERT (FsHandle != NULL); - - Status = gBS->HandleProtocol ( - FsHandle, - &mInternalPartitionEntryProtocolGuid, - (VOID **)&PartEntry - ); - if (!EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCPI: Located cached partition entry\n")); - return PartEntry; - } - // - // Retrieve the partition Device Path information. - // - FsDevicePath = DevicePathFromHandle (FsHandle); - if (FsDevicePath == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: Failed to retrieve Device Path\n")); - return NULL; - } - - HdNode = (HARDDRIVE_DEVICE_PATH *)( - FindDevicePathNodeWithType ( - FsDevicePath, - MEDIA_DEVICE_PATH, - MEDIA_HARDDRIVE_DP - ) - ); - if (HdNode == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: Device Path does not describe a partition\n")); - return NULL; - } - - DiskHandle = InternalPartitionGetDiskHandle ( - FsDevicePath, - (UINTN)HdNode - (UINTN)FsDevicePath, - &HasBlockIo2 - ); - if (DiskHandle == NULL) { - DebugPrintDevicePath ( - DEBUG_INFO, - "OCPI: Could not locate partition's disk", - FsDevicePath - ); - return NULL; - } - // - // Get the disk's GPT partition entries. - // - Partitions = OcGetDiskPartitions (DiskHandle, HasBlockIo2); - if (Partitions == NULL) { - DEBUG ((DEBUG_INFO, "OCPI: Failed to retrieve disk info\n")); - return NULL; - } - - if (HdNode->PartitionNumber > Partitions->NumPartitions) { - DEBUG ((DEBUG_INFO, "OCPI: Partition is OOB\n")); - return NULL; - } - - ASSERT (HdNode->PartitionNumber > 0); - Offset = ((UINTN)(HdNode->PartitionNumber - 1) * Partitions->PartitionEntrySize); - PartEntry = (EFI_PARTITION_ENTRY *)((UINTN)Partitions->FirstEntry + Offset); - // - // FIXME: This causes the handle to be dangling if the device is detached. - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &FsHandle, - &mInternalPartitionEntryProtocolGuid, - PartEntry, - NULL - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCPI: Failed to cache partition entry\n")); - return NULL; - } - - return PartEntry; -} diff --git a/Library/OcFileLib/LocateFileSystem.c b/Library/OcFileLib/LocateFileSystem.c deleted file mode 100644 index 2348d5d21..000000000 --- a/Library/OcFileLib/LocateFileSystem.c +++ /dev/null @@ -1,175 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * -LocateFileSystem ( - IN EFI_HANDLE DeviceHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - CHAR16 *UnicodeFilePath; - - DEBUG_CODE_BEGIN (); - DEBUG ((DEBUG_INFO, "OCFS: Trying to locate filesystem on %p %p\n", DeviceHandle, FilePath)); - if (FilePath != NULL) { - UnicodeFilePath = ConvertDevicePathToText (FilePath, FALSE, FALSE); - if (UnicodeFilePath != NULL) { - DEBUG ((DEBUG_INFO, "OCFS: Filesystem DP is %s\n", UnicodeFilePath)); - FreePool (UnicodeFilePath); - } - } - DEBUG_CODE_END (); - - if (DeviceHandle == NULL) { - // - // Locate DeviceHandle if we have none (idea by dmazar). - // - if (FilePath == NULL) { - DEBUG ((DEBUG_WARN, "OCFS: No device handle or path to proceed\n")); - return NULL; - } - - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - &FilePath, - &DeviceHandle - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_WARN, "OCFS: Failed to locate device handle over path - %r\n", Status)); - return NULL; - } - } - - Status = gBS->HandleProtocol ( - DeviceHandle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **) &FileSystem - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCFS: No filesystem on device handle %p\n", DeviceHandle)); - return NULL; - } - - return FileSystem; -} - -EFI_FILE_PROTOCOL * -LocateRootVolume ( - IN EFI_HANDLE DeviceHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *RootVolume; - - FileSystem = LocateFileSystem (DeviceHandle, FilePath); - if (FileSystem == NULL) { - return NULL; - } - - Status = FileSystem->OpenVolume (FileSystem, &RootVolume); - if (EFI_ERROR(Status)) { - return NULL; - } - - return RootVolume; -} - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * -LocateFileSystemByGuid ( - IN CONST GUID *Guid - ) -{ - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; - - EFI_STATUS Status; - - UINTN NumHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - CONST HARDDRIVE_DEVICE_PATH *HardDrive; - - ASSERT (Guid != NULL); - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumHandles, - &HandleBuffer - ); - if (EFI_ERROR(Status)) { - return NULL; - } - - SimpleFs = NULL; - - for (Index = 0; Index < NumHandles; ++Index) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - (VOID **)&DevicePath - ); - if (EFI_ERROR(Status)) { - continue; - } - - HardDrive = (HARDDRIVE_DEVICE_PATH *)( - FindDevicePathNodeWithType ( - DevicePath, - MEDIA_DEVICE_PATH, - MEDIA_HARDDRIVE_DP - ) - ); - if ((HardDrive == NULL) || (HardDrive->SignatureType != 0x02)) { - continue; - } - - if (CompareGuid (Guid, (GUID *)HardDrive->Signature)) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiSimpleFileSystemProtocolGuid, - (VOID **)&SimpleFs - ); - if (EFI_ERROR(Status)) { - SimpleFs = NULL; - } - - break; - } - } - - FreePool (HandleBuffer); - return SimpleFs; -} diff --git a/Library/OcFileLib/OcFileLib.inf b/Library/OcFileLib/OcFileLib.inf deleted file mode 100755 index 7821de1f7..000000000 --- a/Library/OcFileLib/OcFileLib.inf +++ /dev/null @@ -1,65 +0,0 @@ -## @file -# -# Component description file for OcFileLibrary. -# -# Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcFileLib - FILE_GUID = E7FF8BF4-1641-44AF-BFCE-EF3CF0EF21BE - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcFileLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# VALID_ARCHITECTURES = IA32 X64 - -[Sources] - FileProtocol.c - GetFileInfo.c - GetVolumeLabel.c - LocateFileSystem.c - OpenFile.c - ReadFile.c - GptPartitionEntry.c - FirmwareFile.c - FsConnectQuirk.c - ../../Include/Library/OcFileLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - -[LibraryClasses] - BaseLib - DevicePathLib - OcDevicePathLib - OcGuardLib - MemoryAllocationLib - -[Guids] - gEfiFileInfoGuid ## CONSUMES - gEfiFileSystemInfoGuid ## CONSUMES - gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES - gEfiPartTypeSystemPartGuid ## CONSUMES - -[Protocols] - gEfiFirmwareVolumeProtocolGuid - gEfiFirmwareVolume2ProtocolGuid - gEfiDevicePathProtocolGuid - gEfiBlockIo2ProtocolGuid - gEfiBlockIoProtocolGuid diff --git a/Library/OcFileLib/OpenFile.c b/Library/OcFileLib/OpenFile.c deleted file mode 100644 index 0ab7e570c..000000000 --- a/Library/OcFileLib/OpenFile.c +++ /dev/null @@ -1,215 +0,0 @@ -/** @file - The UEFI Library provides functions and macros that simplify the development of - UEFI Drivers and UEFI Applications. These functions and macros help manage EFI - events, build simple locks utilizing EFI Task Priority Levels (TPLs), install - EFI Driver Model related protocols, manage Unicode string tables for UEFI Drivers, - and print messages on the console output and standard error devices. - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -EFI_STATUS -SafeFileOpen ( - IN EFI_FILE_PROTOCOL *Protocol, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CONST CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - UINTN Length; - - DEBUG_CODE_BEGIN (); - ASSERT (FileName != NULL); - Length = StrLen (FileName); - if (Length > 0 && FileName[Length - 1] == L'\\') { - DEBUG ((DEBUG_INFO, "OCFS: Filename %s has trailing slash\n", FileName)); - } - DEBUG_CODE_END (); - - Status = Protocol->Open ( - Protocol, - NewHandle, - (CHAR16 *) FileName, - OpenMode, - Attributes - ); - - return Status; -} - -EFI_STATUS -EFIAPI -OcOpenFileByRemainingDevicePath ( - IN EFI_HANDLE FileSystemHandle, - IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT EFI_FILE_PROTOCOL **File, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - EFI_FILE_PROTOCOL *LastFile; - CONST EFI_DEVICE_PATH_PROTOCOL *FilePathNode; - CHAR16 *AlignedPathName; - CHAR16 *PathName; - UINTN PathLength; - EFI_FILE_PROTOCOL *NextFile; - - ASSERT (FileSystemHandle != NULL); - ASSERT (RemainingDevicePath != NULL); - ASSERT (File != NULL); - - Status = gBS->OpenProtocol ( - FileSystemHandle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **)&FileSystem, - gImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Open the root directory of the filesystem. After this operation succeeds, - // we have to release LastFile on error. - // - Status = FileSystem->OpenVolume (FileSystem, &LastFile); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Traverse the device path nodes relative to the filesystem. - // - FilePathNode = RemainingDevicePath; - while (!IsDevicePathEnd (FilePathNode)) { - if (DevicePathType (FilePathNode) != MEDIA_DEVICE_PATH || - DevicePathSubType (FilePathNode) != MEDIA_FILEPATH_DP) { - Status = EFI_INVALID_PARAMETER; - goto CloseLastFile; - } - - // - // FilePathNode->PathName may be unaligned, and the UEFI specification - // requires pointers that are passed to protocol member functions to be - // aligned. Create an aligned copy of the pathname to match that - // and to apply the hack below. - // - AlignedPathName = AllocateCopyPool ( - (DevicePathNodeLength (FilePathNode) - - SIZE_OF_FILEPATH_DEVICE_PATH), - ((CONST FILEPATH_DEVICE_PATH *) FilePathNode)->PathName - ); - if (AlignedPathName == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto CloseLastFile; - } - - // - // This is a compatibility hack for firmwares not supporting - // opening filepaths (directories) with a trailing slash in the end. - // More details in a852f85986c1fe23fc3a429605e3c560ea800c54 OpenCorePkg commit. - // - PathLength = StrLen (AlignedPathName); - if (PathLength > 0 && AlignedPathName[PathLength - 1] == '\\') { - AlignedPathName[PathLength - 1] = '\0'; - } - - PathName = AlignedPathName; - - // - // Open or create the file corresponding to the next pathname fragment. - // - Status = SafeFileOpen ( - LastFile, - &NextFile, - PathName, - OpenMode, - Attributes - ); - - FreePool (AlignedPathName); - - if (EFI_ERROR(Status)) { - goto CloseLastFile; - } - - // - // Advance to the next device path node. - // - LastFile->Close (LastFile); - LastFile = NextFile; - FilePathNode = NextDevicePathNode (FilePathNode); - } - - *File = LastFile; - return EFI_SUCCESS; - -CloseLastFile: - LastFile->Close (LastFile); - - // - // We are on the error path; we must have set an error Status for returning - // to the caller. - // - ASSERT (EFI_ERROR(Status)); - return Status; -} - -EFI_STATUS -EFIAPI -OcOpenFileByDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, - OUT EFI_FILE_PROTOCOL **File, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - EFI_HANDLE FileSystemHandle; - - ASSERT (File != NULL); - ASSERT (FilePath != NULL); - - // - // Look up the filesystem. - // - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - FilePath, - &FileSystemHandle - ); - if (EFI_ERROR(Status)) { - return Status; - } - - return OcOpenFileByRemainingDevicePath ( - FileSystemHandle, - *FilePath, - File, - OpenMode, - Attributes - ); -} diff --git a/Library/OcFileLib/ReadFile.c b/Library/OcFileLib/ReadFile.c deleted file mode 100755 index e9d355c78..000000000 --- a/Library/OcFileLib/ReadFile.c +++ /dev/null @@ -1,151 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -VOID * -ReadFile ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *FilePath, - OUT UINT32 *FileSize OPTIONAL, - IN UINT32 MaxFileSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_FILE_HANDLE Volume; - EFI_FILE_HANDLE FileHandle; - UINT8 *FileBuffer; - UINT32 FileBufferSize; - UINT32 FileReadSize; - - ASSERT (FileSystem != NULL); - ASSERT (FilePath != NULL); - - Status = FileSystem->OpenVolume ( - FileSystem, - &Volume - ); - if (EFI_ERROR(Status)) { - return NULL; - } - - Status = SafeFileOpen ( - Volume, - &FileHandle, - (CHAR16 *) FilePath, - EFI_FILE_MODE_READ, - 0 - ); - - Volume->Close (Volume); - - if (EFI_ERROR(Status)) { - return NULL; - } - - Status = GetFileSize ( - FileHandle, - &FileReadSize - ); - if (EFI_ERROR(Status) - || OcOverflowAddU32 (FileReadSize, sizeof (CHAR16), &FileBufferSize) - || (MaxFileSize > 0 && FileReadSize > MaxFileSize)) { - FileHandle->Close (FileHandle); - return NULL; - } - - FileBuffer = AllocatePool (FileBufferSize); - if (FileBuffer != NULL) { - Status = GetFileData ( - FileHandle, - 0, - FileReadSize, - FileBuffer - ); - - if (!EFI_ERROR(Status)) { - FileBuffer[FileReadSize] = 0; - FileBuffer[FileReadSize + 1] = 0; - if (FileSize != NULL) { - *FileSize = FileReadSize; - } - } else { - FreePool (FileBuffer); - FileBuffer = NULL; - } - } - - FileHandle->Close (FileHandle); - return FileBuffer; -} - -EFI_STATUS -ReadFileSize ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *FilePath, - OUT UINT32 *Size - ) -{ - EFI_STATUS Status; - EFI_FILE_HANDLE Volume; - EFI_FILE_HANDLE FileHandle; - - ASSERT (FileSystem != NULL); - ASSERT (FilePath != NULL); - ASSERT (Size != NULL); - - Status = FileSystem->OpenVolume ( - FileSystem, - &Volume - ); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = SafeFileOpen ( - Volume, - &FileHandle, - (CHAR16 *) FilePath, - EFI_FILE_MODE_READ, - 0 - ); - - Volume->Close (Volume); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = GetFileSize ( - FileHandle, - Size - ); - - return Status; -} diff --git a/Library/OcGuardLib/BitOverflow.c b/Library/OcGuardLib/BitOverflow.c deleted file mode 100644 index 6eb9d2bb6..000000000 --- a/Library/OcGuardLib/BitOverflow.c +++ /dev/null @@ -1,289 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -// -// The implementations provided try not to be obviously slow, but primarily -// target C99 compliance rather than performance. -// - -BOOLEAN -(OcOverflowAddU32) ( - UINT32 A, - UINT32 B, - UINT32 *Result - ) -{ - UINT64 Temp; - - // - // I believe casting will be faster on X86 at least. - // - Temp = (UINT64) A + B; - *Result = (UINT32) Temp; - if (Temp <= MAX_UINT32) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowSubU32) ( - UINT32 A, - UINT32 B, - UINT32 *Result - ) -{ - *Result = A - B; - if (B <= A) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowMulU32) ( - UINT32 A, - UINT32 B, - UINT32 *Result - ) -{ - UINT64 Temp; - - Temp = (UINT64) A * B; - *Result = (UINT32) Temp; - if (Temp <= MAX_UINT32) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowAddS32) ( - INT32 A, - INT32 B, - INT32 *Result - ) -{ - INT64 Temp; - - Temp = (INT64) A + B; - *Result = (INT32) Temp; - if (Temp >= MIN_INT32 && Temp <= MAX_INT32) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowSubS32) ( - INT32 A, - INT32 B, - INT32 *Result - ) -{ - INT64 Temp; - - Temp = (INT64) A - B; - *Result = (INT32) Temp; - if (Temp >= MIN_INT32 && Temp <= MAX_INT32) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowMulS32) ( - INT32 A, - INT32 B, - INT32 *Result - ) -{ - INT64 Temp; - - Temp = (INT64) A * B; - *Result = (INT32) Temp; - if (Temp >= MIN_INT32 && Temp <= MAX_INT32) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowAddU64) ( - UINT64 A, - UINT64 B, - UINT64 *Result - ) -{ - *Result = A + B; - if (MAX_UINT64 - A >= B) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowSubU64) ( - UINT64 A, - UINT64 B, - UINT64 *Result - ) -{ - *Result = A - B; - if (B <= A) { - return FALSE; - } - - return TRUE; -} - -BOOLEAN -(OcOverflowMulU64) ( - UINT64 A, - UINT64 B, - UINT64 *Result - ) -{ - UINT64 AHi; - UINT64 ALo; - UINT64 BHi; - UINT64 BLo; - UINT64 LoBits; - UINT64 HiBits1; - UINT64 HiBits2; - BOOLEAN Overflow; - - // - // Based on the 2nd option written by Charphacy, believed to be the fastest portable on x86. - // See: https://stackoverflow.com/a/26320664 - // Implements overflow checking by a series of up to 3 multiplications. - // - - AHi = A >> 32ULL; - ALo = A & MAX_UINT32; - BHi = B >> 32ULL; - BLo = B & MAX_UINT32; - - LoBits = ALo * BLo; - if (AHi == 0 && BHi == 0) { - *Result = LoBits; - return FALSE; - } - - Overflow = AHi > 0 && BHi > 0; - HiBits1 = ALo * BHi; - HiBits2 = AHi * BLo; - - *Result = LoBits + ((HiBits1 + HiBits2) << 32ULL); - return Overflow || *Result < LoBits || (HiBits1 >> 32ULL) != 0 || (HiBits2 >> 32ULL) != 0; -} - -BOOLEAN -(OcOverflowAddS64) ( - INT64 A, - INT64 B, - INT64 *Result - ) -{ - if ((B <= 0 || A <= MAX_INT64 - B) && (B >= 0 || A >= MIN_INT64 - B)) { - *Result = A + B; - return FALSE; - } - - // - // Assign some defined value to *Result. - // - *Result = 0; - return TRUE; -} - -BOOLEAN -(OcOverflowSubS64) ( - INT64 A, - INT64 B, - INT64 *Result - ) -{ - if ((B >= 0 || A <= MAX_INT64 + B) && (B <= 0 || A >= MIN_INT64 + B)) { - *Result = A - B; - return FALSE; - } - - // - // Assign some defined value to *Result. - // - *Result = 0; - return TRUE; -} - -BOOLEAN -(OcOverflowMulS64) ( - INT64 A, - INT64 B, - INT64 *Result - ) -{ - UINT64 AU; - UINT64 BU; - UINT64 ResultU; - - // - // It hurts to implement it without unsigned multiplication, maybe rewrite it one day. - // The idea taken from BaseSafeIntLib. - // - -#define OC_ABS_64(X) (((X) < 0) ? (((UINT64) (-((X) + 1))) + 1) : (UINT64) (X)) - - AU = OC_ABS_64 (A); - BU = OC_ABS_64 (B); - - if (OcOverflowMulU64 (AU, BU, &ResultU)) { - *Result = 0; - return TRUE; - } - - // - // Split into positive and negative results and check just one range. - // - if ((A < 0) == (B < 0)) { - if (ResultU <= MAX_INT64) { - *Result = (INT64) ResultU; - return FALSE; - } - } else { - if (ResultU < OC_ABS_64 (MIN_INT64)) { - *Result = -((INT64) ResultU); - return FALSE; - } else if (ResultU == OC_ABS_64 (MIN_INT64)) { - *Result = MIN_INT64; - return FALSE; - } - } - - *Result = 0; - return TRUE; -} diff --git a/Library/OcGuardLib/Canary.c b/Library/OcGuardLib/Canary.c deleted file mode 100644 index 103466f29..000000000 --- a/Library/OcGuardLib/Canary.c +++ /dev/null @@ -1,39 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -// -// TODO: For the cookie to work for security needs, the value is to be runtime -// generated, e.g. with rdrand. For now this code is only written to help debugging -// stack corruptions. -// -UINT64 __security_cookie = 0x9C7D6B4580C0BC9ULL; - -VOID -__security_check_cookie ( - IN UINTN Value - ) -{ - volatile UINTN Index; - - if (Value != (UINTN) __security_cookie) { - Index = 0; - while (Index == 0) - { - } - } -} diff --git a/Library/OcGuardLib/NativeOverflow.c b/Library/OcGuardLib/NativeOverflow.c deleted file mode 100644 index 9aeb1355a..000000000 --- a/Library/OcGuardLib/NativeOverflow.c +++ /dev/null @@ -1,115 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -// -// Currently no architectures provide UINTN and INTN different from 32-bit or 64-bit -// integers. For this reason they are the only variants supported and are enforced here. -// The lib must be C99-compliant, thus no _Static_assert. -// - -typedef BOOLEAN SignedIntnMustBe32or64[sizeof (INTN) == sizeof (INT64) - || sizeof (INTN) == sizeof (INT32) ? 1 : -1]; - -typedef BOOLEAN UnsignedIntnMustBe32or64[sizeof (UINTN) == sizeof (UINT64) - || sizeof (UINTN) == sizeof (UINT32) ? 1 : -1]; - -BOOLEAN -(OcOverflowAddUN) ( - UINTN A, - UINTN B, - UINTN *Result - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return OcOverflowAddU64 (A, B, Result); - } - - return OcOverflowAddU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); -} - -BOOLEAN -(OcOverflowSubUN) ( - UINTN A, - UINTN B, - UINTN *Result - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return OcOverflowSubU64 (A, B, Result); - } - - return OcOverflowSubU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); -} - -BOOLEAN -(OcOverflowMulUN) ( - UINTN A, - UINTN B, - UINTN *Result - ) -{ - if (sizeof (UINTN) == sizeof (UINT64)) { - return OcOverflowMulU64 (A, B, Result); - } - - return OcOverflowMulU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); -} - -BOOLEAN -(OcOverflowAddSN) ( - INTN A, - INTN B, - INTN *Result - ) -{ - if (sizeof (INTN) == sizeof (INT64)) { - return OcOverflowAddS64 (A, B, Result); - } - - return OcOverflowAddS32 ((INT32)A, (INT32)B, (INT32 *)Result); -} - -BOOLEAN -(OcOverflowSubSN) ( - INTN A, - INTN B, - INTN *Result - ) -{ - if (sizeof (INTN) == sizeof (INT64)) { - return OcOverflowSubS64 (A, B, Result); - } - - return OcOverflowSubS32 ((INT32)A, (INT32)B, (INT32 *)Result); -} - -BOOLEAN -(OcOverflowMulSN) ( - INTN A, - INTN B, - INTN *Result - ) -{ - if (sizeof (INTN) == sizeof (INT64)) { - return OcOverflowMulS64 (A, B, Result); - } - - return OcOverflowMulS32 ((INT32)A, (INT32)B, (INT32 *)Result); -} diff --git a/Library/OcGuardLib/OcGuardLib.inf b/Library/OcGuardLib/OcGuardLib.inf deleted file mode 100644 index cb3aadd54..000000000 --- a/Library/OcGuardLib/OcGuardLib.inf +++ /dev/null @@ -1,51 +0,0 @@ -## @file -# OcGuardLib -# -# Copyright (c) 2018, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcGuardLib - FILE_GUID = 4709B3D7-BE0A-4FCE-9DDA-C5823E48BE3C - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcGuardLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - BitOverflow.c - Canary.c - NativeOverflow.c - TripleOverflow.c - UbsanPrintf.c - Ubsan.c - Ubsan.h - -[Packages] - MdePkg/MdePkg.dec - CloverPkg.dec -# OcSupportPkg/OcSupportPkg.dec - -[LibraryClasses] - BaseLib - -[BuildOptions] - XCODE:DEBUG_*_*_CC_FLAGS = -fno-stack-protector - XCODE:NOOPT_*_*_CC_FLAGS = -fno-stack-protector - XCODE:RELEASE_*_*_CC_FLAGS = -fno-stack-protector diff --git a/Library/OcGuardLib/TripleOverflow.c b/Library/OcGuardLib/TripleOverflow.c deleted file mode 100644 index d6155c46c..000000000 --- a/Library/OcGuardLib/TripleOverflow.c +++ /dev/null @@ -1,429 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -BOOLEAN -(OcOverflowTriAddU32) ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ) -{ - UINT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddU32(A, B, &OcTmp); - OcSecond = OcOverflowAddU32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulU32) ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ) -{ - UINT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulU32(A, B, &OcTmp); - OcSecond = OcOverflowMulU32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulU32) ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ) -{ - UINT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddU32(A, B, &OcTmp); - OcSecond = OcOverflowMulU32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddU32) ( - UINT32 A, - UINT32 B, - UINT32 C, - UINT32 *Result - ) -{ - UINT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulU32(A, B, &OcTmp); - OcSecond = OcOverflowAddU32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriAddS32) ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ) -{ - INT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddS32(A, B, &OcTmp); - OcSecond = OcOverflowAddS32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulS32) ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ) -{ - INT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulS32(A, B, &OcTmp); - OcSecond = OcOverflowMulS32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulS32) ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ) -{ - INT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddS32(A, B, &OcTmp); - OcSecond = OcOverflowMulS32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddS32) ( - INT32 A, - INT32 B, - INT32 C, - INT32 *Result - ) -{ - INT32 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulS32(A, B, &OcTmp); - OcSecond = OcOverflowAddS32(OcTmp, C, Result); - return OcFirst | OcSecond; -} - - -BOOLEAN -(OcOverflowTriAddU64) ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ) -{ - UINT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddU64(A, B, &OcTmp); - OcSecond = OcOverflowAddU64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulU64) ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ) -{ - UINT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulU64(A, B, &OcTmp); - OcSecond = OcOverflowMulU64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulU64) ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ) -{ - UINT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddU64(A, B, &OcTmp); - OcSecond = OcOverflowMulU64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddU64) ( - UINT64 A, - UINT64 B, - UINT64 C, - UINT64 *Result - ) -{ - UINT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulU64(A, B, &OcTmp); - OcSecond = OcOverflowAddU64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriAddS64) ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ) -{ - INT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddS64(A, B, &OcTmp); - OcSecond = OcOverflowAddS64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulS64) ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ) -{ - INT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulS64(A, B, &OcTmp); - OcSecond = OcOverflowMulS64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulS64) ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ) -{ - INT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddS64(A, B, &OcTmp); - OcSecond = OcOverflowMulS64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddS64) ( - INT64 A, - INT64 B, - INT64 C, - INT64 *Result - ) -{ - INT64 OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulS64(A, B, &OcTmp); - OcSecond = OcOverflowAddS64(OcTmp, C, Result); - return OcFirst | OcSecond; -} - - -BOOLEAN -(OcOverflowTriAddUN) ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ) -{ - UINTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddUN(A, B, &OcTmp); - OcSecond = OcOverflowAddUN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulUN) ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ) -{ - UINTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulUN(A, B, &OcTmp); - OcSecond = OcOverflowMulUN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulUN) ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ) -{ - UINTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddUN(A, B, &OcTmp); - OcSecond = OcOverflowMulUN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddUN) ( - UINTN A, - UINTN B, - UINTN C, - UINTN *Result - ) -{ - UINTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulUN(A, B, &OcTmp); - OcSecond = OcOverflowAddUN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriAddSN) ( - INTN A, - INTN B, - INTN C, - INTN *Result - ) -{ - INTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddSN(A, B, &OcTmp); - OcSecond = OcOverflowAddSN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowTriMulSN) ( - INTN A, - INTN B, - INTN C, - INTN *Result - ) -{ - INTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulSN(A, B, &OcTmp); - OcSecond = OcOverflowMulSN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowAddMulSN) ( - INTN A, - INTN B, - INTN C, - INTN *Result - ) -{ - INTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowAddSN(A, B, &OcTmp); - OcSecond = OcOverflowMulSN(OcTmp, C, Result); - return OcFirst | OcSecond; -} - -BOOLEAN -(OcOverflowMulAddSN) ( - INTN A, - INTN B, - INTN C, - INTN *Result - ) -{ - INTN OcTmp; - BOOLEAN OcFirst; - BOOLEAN OcSecond; - - OcFirst = OcOverflowMulSN(A, B, &OcTmp); - OcSecond = OcOverflowAddSN(OcTmp, C, Result); - return OcFirst | OcSecond; -} diff --git a/Library/OcGuardLib/Ubsan.c b/Library/OcGuardLib/Ubsan.c deleted file mode 100644 index 0e7682436..000000000 --- a/Library/OcGuardLib/Ubsan.c +++ /dev/null @@ -1,1741 +0,0 @@ -/* $NetBSD: ubsan.c,v 1.6 2019/06/17 18:55:37 kamil Exp $ */ - -/*- - * Copyright (c) 2018 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -/* - * The micro UBSan implementation for the userland (uUBSan) and kernel (kUBSan). - * The uBSSan versions is suitable for inclusion into libc or used standalone - * with ATF tests. - * - * This file due to long symbol names generated by a compiler during the - * instrumentation process does not follow the KNF style with 80-column limit. - */ - -#include "Ubsan.h" - -#ifdef HAVE_UBSAN_SUPPORT - -// OC change: unsupported in EDK2 -// #include -#if defined(_KERNEL) -__KERNEL_RCSID(0, "$NetBSD: ubsan.c,v 1.6 2019/06/17 18:55:37 kamil Exp $"); -#else -__RCSID("$NetBSD: ubsan.c,v 1.6 2019/06/17 18:55:37 kamil Exp $"); -#endif - -#if defined(_KERNEL) -// OC change: unsupported in EDK2 -// #include -// #include -// #include -#define ASSERT(x) KASSERT(x) -#else -#if defined(_LIBC) -#include "namespace.h" -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(_LIBC) -#include "extern.h" -#define ubsan_vsyslog vsyslog_ss -#define ASSERT(x) _DIAGASSERT(x) -#else -#define ubsan_vsyslog vsyslog_r -#define ASSERT(x) assert(x) -#endif -/* These macros are available in _KERNEL only */ -#define SET(t, f) ((t) |= (f)) -#define ISSET(t, f) ((t) & (f)) -#define CLR(t, f) ((t) &= ~(f)) -#endif - -#ifdef UBSAN_ALWAYS_FATAL -static const bool alwaysFatal = true; -#else -static const bool alwaysFatal = false; -#endif - -#define REINTERPRET_CAST(__dt, __st) ((__dt)(__st)) -#define STATIC_CAST(__dt, __st) ((__dt)(__st)) - -#define ACK_REPORTED __BIT(31) - -#define MUL_STRING "*" -#define PLUS_STRING "+" -#define MINUS_STRING "-" -#define DIVREM_STRING "divrem" - -#define CFI_VCALL 0 -#define CFI_NVCALL 1 -#define CFI_DERIVEDCAST 2 -#define CFI_UNRELATEDCAST 3 -#define CFI_ICALL 4 -#define CFI_NVMFCALL 5 -#define CFI_VMFCALL 6 - -#define NUMBER_MAXLEN 128 -#define LOCATION_MAXLEN (PATH_MAX + 32 /* ':LINE:COLUMN' */) - -#define WIDTH_8 8 -#define WIDTH_16 16 -#define WIDTH_32 32 -#define WIDTH_64 64 -#define WIDTH_80 80 -#define WIDTH_96 96 -#define WIDTH_128 128 - -#define NUMBER_SIGNED_BIT 1U - -#ifdef __SIZEOF_INT128__ -typedef __int128 longest; -typedef unsigned __int128 ulongest; -#else -typedef int64_t longest; -typedef uint64_t ulongest; -#endif - -#ifndef _KERNEL -static int ubsan_flags = -1; -#define UBSAN_ABORT __BIT(0) -#define UBSAN_STDOUT __BIT(1) -#define UBSAN_STDERR __BIT(2) -#define UBSAN_SYSLOG __BIT(3) -#endif - -/* Undefined Behavior specific defines and structures */ - -#define KIND_INTEGER 0 -#define KIND_FLOAT 1 -#define KIND_UNKNOWN UINT16_MAX - -struct CSourceLocation { - char *mFilename; - uint32_t mLine; - uint32_t mColumn; -}; - -struct CTypeDescriptor { - uint16_t mTypeKind; - uint16_t mTypeInfo; - uint8_t mTypeName[1]; -}; - -struct COverflowData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; -}; - -struct CUnreachableData { - struct CSourceLocation mLocation; -}; - -struct CCFICheckFailData { - uint8_t mCheckKind; - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; -}; - -struct CDynamicTypeCacheMissData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; - void *mTypeInfo; - uint8_t mTypeCheckKind; -}; - -struct CFunctionTypeMismatchData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; -}; - -struct CImplicitConversionData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mFromType; - struct CTypeDescriptor *mToType; - uint8_t mKind; -}; - -struct CInvalidBuiltinData { - struct CSourceLocation mLocation; - uint8_t mKind; -}; - -struct CInvalidValueData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; -}; - -struct CNonNullArgData { - struct CSourceLocation mLocation; - struct CSourceLocation mAttributeLocation; - int mArgIndex; -}; - -struct CNonNullReturnData { - struct CSourceLocation mAttributeLocation; -}; - -struct COutOfBoundsData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mArrayType; - struct CTypeDescriptor *mIndexType; -}; - -struct CPointerOverflowData { - struct CSourceLocation mLocation; -}; - -struct CShiftOutOfBoundsData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mLHSType; - struct CTypeDescriptor *mRHSType; -}; - -struct CTypeMismatchData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; - unsigned long mLogAlignment; - uint8_t mTypeCheckKind; -}; - -struct CTypeMismatchData_v1 { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; - uint8_t mLogAlignment; - uint8_t mTypeCheckKind; -}; - -struct CVLABoundData { - struct CSourceLocation mLocation; - struct CTypeDescriptor *mType; -}; - -struct CFloatCastOverflowData { - struct CSourceLocation mLocation; /* This field exists in this struct since 2015 August 11th */ - struct CTypeDescriptor *mFromType; - struct CTypeDescriptor *mToType; -}; - -/* Local utility functions */ -// OC change: EFIAPI is required by EDK2 -static void EFIAPI Report(bool isFatal, const char *pFormat, ...) __printflike(2, 3); -static bool isAlreadyReported(struct CSourceLocation *pLocation); -static size_t zDeserializeTypeWidth(struct CTypeDescriptor *pType); -static void DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation); -#ifdef __SIZEOF_INT128__ -static void DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128); -#endif -static void DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L); -static void DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L); -#ifndef _KERNEL -static void DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber); -static void DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber); -#endif -static longest llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber); -static ulongest llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber); -#ifndef _KERNEL -static void DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber); -#endif -static void DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber); -static const char *DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind); -static const char *DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind); -static const char *DeserializeCFICheckKind(uint8_t hhuCFICheckKind); -static const char *DeserializeImplicitConversionCheckKind(uint8_t hhuImplicitConversionCheckKind); -static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber); -static bool isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth); - -/* Unused in this implementation, emitted by the C++ check dynamic type cast. */ -intptr_t __ubsan_vptr_type_cache[128]; - -/* Public symbols used in the instrumentation of the code generation part */ -void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_builtin_unreachable(struct CUnreachableData *pData); -void __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer); -void __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable); -void __ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable); -void __ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash); -void __ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash); -void __ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom); -void __ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom); -void __ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction); -void __ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction); -void __ubsan_handle_implicit_conversion(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo); -void __ubsan_handle_implicit_conversion_abort(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo); -void __ubsan_handle_invalid_builtin(struct CInvalidBuiltinData *pData); -void __ubsan_handle_invalid_builtin_abort(struct CInvalidBuiltinData *pData); -void __ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulVal); -void __ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulVal); -void __ubsan_handle_missing_return(struct CUnreachableData *pData); -void __ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldVal); -void __ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldVal); -void __ubsan_handle_nonnull_arg(struct CNonNullArgData *pData); -void __ubsan_handle_nonnull_arg_abort(struct CNonNullArgData *pData); -void __ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer); -void __ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer); -void __ubsan_handle_nullability_arg(struct CNonNullArgData *pData); -void __ubsan_handle_nullability_arg_abort(struct CNonNullArgData *pData); -void __ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer); -void __ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer); -void __ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex); -void __ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex); -void __ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult); -void __ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult); -void __ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS); -void __ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer); -void __ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer); -void __ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer); -void __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer); -void __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound); -void __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound); -void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr); - -static void HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation); -static void HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue); -static void HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData); -static void HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer); -static void HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound); -static void HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex); -static void HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS); -static void HandleImplicitConversion(bool isFatal, struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo); -static void HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue); -static void HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData); -static void HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction); -static void HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer); -static void HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash); -static void HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom); -static void HandleMissingReturn(bool isFatal, struct CUnreachableData *pData); -static void HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData); -static void HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer); -static void HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult); - -static void -HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation) -{ - char szLocation[LOCATION_MAXLEN]; - char szLHS[NUMBER_MAXLEN]; - char szRHS[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mType, ulLHS); - DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mType, ulRHS); - - Report(isFatal, "UBSan: Undefined Behavior in %s, %s integer overflow: %s %s %s cannot be represented in type %s\n", - szLocation, ISSET(pData->mType->mTypeInfo, NUMBER_SIGNED_BIT) ? "signed" : "unsigned", szLHS, szOperation, szRHS, pData->mType->mTypeName); -} - -static void -HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue) -{ - char szLocation[LOCATION_MAXLEN]; - char szOldValue[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szOldValue, NUMBER_MAXLEN, pData->mType, ulOldValue); - - Report(isFatal, "UBSan: Undefined Behavior in %s, negation of %s cannot be represented in type %s\n", - szLocation, szOldValue, pData->mType->mTypeName); -} - -static void -HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData) -{ - char szLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, calling __builtin_unreachable()\n", - szLocation); -} - -static void -HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer) -{ - char szLocation[LOCATION_MAXLEN]; - - ASSERT(mLocation); - ASSERT(mType); - - if (isAlreadyReported(mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, mLocation); - - if (ulPointer == 0) { - Report(isFatal, "UBSan: Undefined Behavior in %s, %s null pointer of type %s\n", - szLocation, DeserializeTypeCheckKind(mTypeCheckKind), mType->mTypeName); - } else if ((mLogAlignment - 1) & ulPointer) { - Report(isFatal, "UBSan: Undefined Behavior in %s, %s misaligned address %p for type %s which requires %ld byte alignment\n", - szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName, mLogAlignment); - } else { - Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %p with insufficient space for an object of type %s\n", - szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName); - } -} - -static void -HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound) -{ - char szLocation[LOCATION_MAXLEN]; - char szBound[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szBound, NUMBER_MAXLEN, pData->mType, ulBound); - - Report(isFatal, "UBSan: Undefined Behavior in %s, variable length array bound value %s <= 0\n", - szLocation, szBound); -} - -static void -HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex) -{ - char szLocation[LOCATION_MAXLEN]; - char szIndex[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szIndex, NUMBER_MAXLEN, pData->mIndexType, ulIndex); - - Report(isFatal, "UBSan: Undefined Behavior in %s, index %s is out of range for type %s\n", - szLocation, szIndex, pData->mArrayType->mTypeName); -} - -static void -HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - char szLocation[LOCATION_MAXLEN]; - char szLHS[NUMBER_MAXLEN]; - char szRHS[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mLHSType, ulLHS); - DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mRHSType, ulRHS); - - if (isNegativeNumber(szLocation, pData->mRHSType, ulRHS)) - Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is negative\n", - szLocation, szRHS); - else if (isShiftExponentTooLarge(szLocation, pData->mRHSType, ulRHS, zDeserializeTypeWidth(pData->mLHSType))) - Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is too large for %zu-bit type %s\n", - szLocation, szRHS, zDeserializeTypeWidth(pData->mLHSType), pData->mLHSType->mTypeName); - else if (isNegativeNumber(szLocation, pData->mLHSType, ulLHS)) - Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of negative value %s\n", - szLocation, szLHS); - else - Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of %s by %s places cannot be represented in type %s\n", - szLocation, szLHS, szRHS, pData->mLHSType->mTypeName); -} - -static void -HandleImplicitConversion(bool isFatal, struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) -{ - char szLocation[LOCATION_MAXLEN]; - char szFrom[NUMBER_MAXLEN]; - char szTo[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szFrom, NUMBER_MAXLEN, pData->mFromType, ulFrom); - DeserializeNumber(szLocation, szTo, NUMBER_MAXLEN, pData->mToType, ulTo); - - Report(isFatal, "UBSAN: Undefined Behavior in %s, %s from %s to %s\n", - szLocation, DeserializeImplicitConversionCheckKind(pData->mKind), pData->mFromType->mTypeName, pData->mToType->mTypeName); -} - -static void -HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue) -{ - char szLocation[LOCATION_MAXLEN]; - char szValue[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szValue, NUMBER_MAXLEN, pData->mType, ulValue); - - Report(isFatal, "UBSan: Undefined Behavior in %s, load of value %s is not a valid value for type %s\n", - szLocation, szValue, pData->mType->mTypeName); -} - -static void -HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData) -{ - char szLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, passing zero to %s, which is not a valid argument\n", - szLocation, DeserializeBuiltinCheckKind(pData->mKind)); -} - -static void -HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction) -{ - char szLocation[LOCATION_MAXLEN]; - - /* - * There is no a portable C solution to translate an address of a - * function to its name. On the cost of getting this routine simple - * and portable without ifdefs between the userland and the kernel - * just print the address of the function as-is. - * - * For better diagnostic messages in the userland, users shall use - * the full upstream version shipped along with the compiler toolchain. - */ - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, call to function %#lx through pointer to incorrect function type %s\n", - szLocation, ulFunction, pData->mType->mTypeName); -} - -static void -HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer) -{ - char szLocation[LOCATION_MAXLEN]; - - /* - * This is a minimal implementation without diving into C++ - * specifics and (Itanium) ABI deserialization. - */ - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - if (pData->mCheckKind == CFI_ICALL || pData->mCheckKind == CFI_VMFCALL) { - Report(isFatal, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx)\n", - szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable); - } else { - Report(isFatal || FromUnrecoverableHandler, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx; %s vtable; from %s handler; Program Counter %#lx; Frame Pointer %#lx)\n", - szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable, *bValidVtable ? "valid" : "invalid", *FromUnrecoverableHandler ? "unrecoverable" : "recoverable", *ProgramCounter, *FramePointer); - } -} - -static void -HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash) -{ -#if 0 - char szLocation[LOCATION_MAXLEN]; - - /* - * Unimplemented. - * - * This UBSan handler is special as the check has to be impelemented - * in an implementation. In order to handle it there is need to - * introspect into C++ ABI internals (RTTI) and use low-level - * C++ runtime interfaces. - */ - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %#lx which might not point to an object of type %s\n" - szLocation, DeserializeTypeCheckKind(pData->mTypeCheckKind), ulPointer, pData->mType); -#endif -} - -static void -HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom) -{ - char szLocation[LOCATION_MAXLEN]; - char szFrom[NUMBER_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - DeserializeNumber(szLocation, szFrom, NUMBER_MAXLEN, pData->mFromType, ulFrom); - - Report(isFatal, "UBSan: Undefined Behavior in %s, %s (of type %s) is outside the range of representable values of type %s\n", - szLocation, szFrom, pData->mFromType->mTypeName, pData->mToType->mTypeName); -} - -static void -HandleMissingReturn(bool isFatal, struct CUnreachableData *pData) -{ - char szLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, execution reached the end of a value-returning function without returning a value\n", - szLocation); -} - -static void -HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData) -{ - char szLocation[LOCATION_MAXLEN]; - char szAttributeLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - if (pData->mAttributeLocation.mFilename) - DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation); - else - szAttributeLocation[0] = '\0'; - - Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer passed as argument %d, which is declared to never be null%s%s\n", - szLocation, pData->mArgIndex, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation); -} - -static void -HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer) -{ - char szLocation[LOCATION_MAXLEN]; - char szAttributeLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - ASSERT(pLocationPointer); - - if (isAlreadyReported(pLocationPointer)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, pLocationPointer); - if (pData->mAttributeLocation.mFilename) - DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation); - else - szAttributeLocation[0] = '\0'; - - Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer returned from function declared to never return null%s%s\n", - szLocation, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation); -} - -static void -HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult) -{ - char szLocation[LOCATION_MAXLEN]; - - ASSERT(pData); - - if (isAlreadyReported(&pData->mLocation)) - return; - - DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation); - - Report(isFatal, "UBSan: Undefined Behavior in %s, pointer expression with base %#lx overflowed to %#lx\n", - szLocation, ulBase, ulResult); -} - -/* Definions of public symbols emitted by the instrumentation code */ -void -__ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(false, pData, ulLHS, ulRHS, PLUS_STRING); -} - -void -__ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(true, pData, ulLHS, ulRHS, PLUS_STRING); -} - -void -__ubsan_handle_builtin_unreachable(struct CUnreachableData *pData) -{ - - ASSERT(pData); - - HandleBuiltinUnreachable(true, pData); -} - -void -__ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer) -{ - - ASSERT(pData); - - HandleCFIBadType(false, pData, ulVtable, &bValidVtable, &FromUnrecoverableHandler, &ProgramCounter, &FramePointer); -} - -void -__ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable) -{ - - ASSERT(pData); - - HandleCFIBadType(false, pData, ulValue, 0, 0, 0, 0); -} - -void -__ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable) -{ - - ASSERT(pData); - - HandleCFIBadType(true, pData, ulValue, 0, 0, 0, 0); -} - -void -__ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(false, pData, ulLHS, ulRHS, DIVREM_STRING); -} - -void -__ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(true, pData, ulLHS, ulRHS, DIVREM_STRING); -} - -void -__ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash) -{ - - ASSERT(pData); - - HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash); -} - -void -__ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash) -{ - - ASSERT(pData); - - HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash); -} - -void -__ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom) -{ - - ASSERT(pData); - - HandleFloatCastOverflow(false, pData, ulFrom); -} - -void -__ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom) -{ - - ASSERT(pData); - - HandleFloatCastOverflow(true, pData, ulFrom); -} - -void -__ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction) -{ - - ASSERT(pData); - - HandleFunctionTypeMismatch(false, pData, ulFunction); -} - -void -__ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction) -{ - - ASSERT(pData); - - HandleFunctionTypeMismatch(false, pData, ulFunction); -} - -void -__ubsan_handle_implicit_conversion(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) -{ - ASSERT(pData); - - HandleImplicitConversion(false, pData, ulFrom, ulTo); -} - -void -__ubsan_handle_implicit_conversion_abort(struct CImplicitConversionData *pData, unsigned long ulFrom, unsigned long ulTo) -{ - - ASSERT(pData); - - HandleImplicitConversion(false, pData, ulFrom, ulTo); -} - -void -__ubsan_handle_invalid_builtin(struct CInvalidBuiltinData *pData) -{ - - ASSERT(pData); - - HandleInvalidBuiltin(true, pData); -} - -void -__ubsan_handle_invalid_builtin_abort(struct CInvalidBuiltinData *pData) -{ - - ASSERT(pData); - - HandleInvalidBuiltin(true, pData); -} - -void -__ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulValue) -{ - - ASSERT(pData); - - HandleLoadInvalidValue(false, pData, ulValue); -} - -void -__ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulValue) -{ - - ASSERT(pData); - - HandleLoadInvalidValue(true, pData, ulValue); -} - -void -__ubsan_handle_missing_return(struct CUnreachableData *pData) -{ - - ASSERT(pData); - - HandleMissingReturn(true, pData); -} - -void -__ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(false, pData, ulLHS, ulRHS, MUL_STRING); -} - -void -__ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(true, pData, ulLHS, ulRHS, MUL_STRING); -} - -void -__ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldValue) -{ - - ASSERT(pData); - - HandleNegateOverflow(false, pData, ulOldValue); -} - -void -__ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldValue) -{ - - ASSERT(pData); - - HandleNegateOverflow(true, pData, ulOldValue); -} - -void -__ubsan_handle_nonnull_arg(struct CNonNullArgData *pData) -{ - - ASSERT(pData); - - HandleNonnullArg(false, pData); -} - -void -__ubsan_handle_nonnull_arg_abort(struct CNonNullArgData *pData) -{ - - ASSERT(pData); - - HandleNonnullArg(true, pData); -} - -void -__ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer) -{ - - ASSERT(pData); - ASSERT(pLocationPointer); - - HandleNonnullReturn(false, pData, pLocationPointer); -} - -void -__ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer) -{ - - ASSERT(pData); - ASSERT(pLocationPointer); - - HandleNonnullReturn(true, pData, pLocationPointer); -} - -void -__ubsan_handle_nullability_arg(struct CNonNullArgData *pData) -{ - - ASSERT(pData); - - HandleNonnullArg(false, pData); -} - -void -__ubsan_handle_nullability_arg_abort(struct CNonNullArgData *pData) -{ - - ASSERT(pData); - - HandleNonnullArg(true, pData); -} - -void -__ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer) -{ - - ASSERT(pData); - ASSERT(pLocationPointer); - - HandleNonnullReturn(false, pData, pLocationPointer); -} - -void -__ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer) -{ - - ASSERT(pData); - ASSERT(pLocationPointer); - - HandleNonnullReturn(true, pData, pLocationPointer); -} - -void -__ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex) -{ - - ASSERT(pData); - - HandleOutOfBounds(false, pData, ulIndex); -} - -void -__ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex) -{ - - ASSERT(pData); - - HandleOutOfBounds(true, pData, ulIndex); -} - -void -__ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult) -{ - - ASSERT(pData); - - HandlePointerOverflow(false, pData, ulBase, ulResult); -} - -void -__ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult) -{ - - ASSERT(pData); - - HandlePointerOverflow(true, pData, ulBase, ulResult); -} - -void -__ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleShiftOutOfBounds(false, pData, ulLHS, ulRHS); -} - -void -__ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleShiftOutOfBounds(true, pData, ulLHS, ulRHS); -} - -void -__ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(false, pData, ulLHS, ulRHS, MINUS_STRING); -} - -void -__ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS) -{ - - ASSERT(pData); - - HandleOverflow(true, pData, ulLHS, ulRHS, MINUS_STRING); -} - -void -__ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer) -{ - - ASSERT(pData); - - HandleTypeMismatch(false, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer); -} - -void -__ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer) -{ - - ASSERT(pData); - - HandleTypeMismatch(true, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer); -} - -void -__ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer) -{ - - ASSERT(pData); - - HandleTypeMismatch(false, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer); -} - -void -__ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer) -{ - - ASSERT(pData); - - HandleTypeMismatch(true, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer); -} - -void -__ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound) -{ - - ASSERT(pData); - - HandleVlaBoundNotPositive(false, pData, ulBound); -} - -void -__ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound) -{ - - ASSERT(pData); - - HandleVlaBoundNotPositive(true, pData, ulBound); -} - -void -__ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr) -{ - /* - * Unimplemented. - * - * The __ubsan_on_report() feature is non trivial to implement in a - * shared code between the kernel and userland. It's also opening - * new sets of potential problems as we are not expected to slow down - * execution of certain kernel subsystems (synchronization issues, - * interrupt handling etc). - * - * A proper solution would need probably a lock-free bounded queue built - * with atomic operations with the property of miltiple consumers and - * multiple producers. Maintaining and validating such code is not - * worth the effort. - * - * A legitimate user - besides testing framework - is a debugger plugin - * intercepting reports from the UBSan instrumentation. For such - * scenarios it is better to run the Clang/GCC version. - */ -} - -/* Local utility functions */ - -static void -// OC change: EFIAPI is required by EDK2 -EFIAPI -Report(bool isFatal, const char *pFormat, ...) -{ - va_list ap; - - ASSERT(pFormat); - - va_start(ap, pFormat); -#if defined(_KERNEL) - if (isFatal || alwaysFatal) - vpanic(pFormat, ap); - else - vprintf(pFormat, ap); -#else - if (ubsan_flags == -1) { - char buf[1024]; - char *p; - - ubsan_flags = UBSAN_STDERR; - - if (getenv_r("LIBC_UBSAN", buf, sizeof(buf)) != -1) { - for (p = buf; *p; p++) { - switch (*p) { - case 'a': - SET(ubsan_flags, UBSAN_ABORT); - break; - case 'A': - CLR(ubsan_flags, UBSAN_ABORT); - break; - case 'e': - SET(ubsan_flags, UBSAN_STDERR); - break; - case 'E': - CLR(ubsan_flags, UBSAN_STDERR); - break; - case 'l': - SET(ubsan_flags, UBSAN_SYSLOG); - break; - case 'L': - CLR(ubsan_flags, UBSAN_SYSLOG); - break; - case 'o': - SET(ubsan_flags, UBSAN_STDOUT); - break; - case 'O': - CLR(ubsan_flags, UBSAN_STDOUT); - break; - default: - break; - } - } - } - } - - // The *v*print* functions can flush the va_list argument. - // Create a local copy for each call to prevent invalid read. - if (ISSET(ubsan_flags, UBSAN_STDOUT)) { - va_list tmp; - va_copy(tmp, ap); - vprintf(pFormat, tmp); - va_end(tmp); - fflush(stdout); - } - if (ISSET(ubsan_flags, UBSAN_STDERR)) { - va_list tmp; - va_copy(tmp, ap); - vfprintf(stderr, pFormat, tmp); - va_end(tmp); - fflush(stderr); - } - if (ISSET(ubsan_flags, UBSAN_SYSLOG)) { - va_list tmp; - va_copy(tmp, ap); - struct syslog_data SyslogData = SYSLOG_DATA_INIT; - ubsan_vsyslog(LOG_DEBUG | LOG_USER, &SyslogData, pFormat, tmp); - va_end(tmp); - } - if (isFatal || alwaysFatal || ISSET(ubsan_flags, UBSAN_ABORT)) { - abort(); - __unreachable(); - /* NOTREACHED */ - } -#endif - va_end(ap); -} - -static bool -isAlreadyReported(struct CSourceLocation *pLocation) -{ - /* - * This code is shared between libc, kernel and standalone usage. - * It shall work in early bootstrap phase of both of them. - */ - - uint32_t siOldValue; - volatile uint32_t *pLine; - - ASSERT(pLocation); - - pLine = &pLocation->mLine; - - do { - siOldValue = *pLine; - } while (__sync_val_compare_and_swap(pLine, siOldValue, siOldValue | ACK_REPORTED) != siOldValue); - - return ISSET(siOldValue, ACK_REPORTED); -} - -static size_t -zDeserializeTypeWidth(struct CTypeDescriptor *pType) -{ - size_t zWidth = 0; - - ASSERT(pType); - - switch (pType->mTypeKind) { - case KIND_INTEGER: - zWidth = __BIT(__SHIFTOUT(pType->mTypeInfo, ~NUMBER_SIGNED_BIT)); - break; - case KIND_FLOAT: - zWidth = pType->mTypeInfo; - break; - default: - Report(true, "UBSan: Unknown variable type %#04" PRIx16 "\n", pType->mTypeKind); - __unreachable(); - /* NOTREACHED */ - } - - /* Invalid width will be transformed to 0 */ - ASSERT(zWidth > 0); - - return zWidth; -} - -static void -DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation) -{ - - ASSERT(pLocation); - ASSERT(pLocation->mFilename); - - snprintf(pBuffer, zBUfferLength, "%s:%" PRIu32 ":%" PRIu32, pLocation->mFilename, pLocation->mLine & (uint32_t)~ACK_REPORTED, pLocation->mColumn); -} - -#ifdef __SIZEOF_INT128__ -static void -DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128) -{ - char szBuf[3]; /* 'XX\0' */ - char rgNumber[sizeof(ulongest)]; - ssize_t zI; - - memcpy(rgNumber, &U128, sizeof(U128)); - - strlcpy(pBuffer, "Undecoded-128-bit-Integer-Type (0x", zBUfferLength); -#if BYTE_ORDER == LITTLE_ENDIAN - for (zI = sizeof(ulongest) - 1; zI >= 0; zI--) { -#else - for (zI = 0; zI < (ssize_t)sizeof(ulongest); zI++) { -#endif - snprintf(szBuf, sizeof(szBuf), "%02" PRIx8, rgNumber[zI]); - strlcat(pBuffer, szBuf, zBUfferLength); - } - strlcat(pBuffer, ")", zBUfferLength); -} -#endif - -static void -DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L) -{ - - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - ASSERT(ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)); - - switch (zDeserializeTypeWidth(pType)) { - default: - ASSERT(0 && "Invalid codepath"); - __unreachable(); - /* NOTREACHED */ -#ifdef __SIZEOF_INT128__ - case WIDTH_128: - DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L)); - break; -#endif - case WIDTH_64: - /* FALLTHROUGH */ - case WIDTH_32: - /* FALLTHROUGH */ - case WIDTH_16: - /* FALLTHROUGH */ - case WIDTH_8: - snprintf(pBuffer, zBUfferLength, "%" PRId64, STATIC_CAST(int64_t, L)); - break; - } -} - -static void -DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L) -{ - - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - ASSERT(!ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)); - - switch (zDeserializeTypeWidth(pType)) { - default: - ASSERT(0 && "Invalid codepath"); - __unreachable(); - /* NOTREACHED */ -#ifdef __SIZEOF_INT128__ - case WIDTH_128: - DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L)); - break; -#endif - case WIDTH_64: - /* FALLTHROUGH */ - case WIDTH_32: - /* FALLTHROUGH */ - case WIDTH_16: - /* FALLTHROUGH */ - case WIDTH_8: - snprintf(pBuffer, zBUfferLength, "%" PRIu64, STATIC_CAST(uint64_t, L)); - break; - } -} - -#ifndef _KERNEL -static void -DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber) -{ - double D; -#ifdef __HAVE_LONG_DOUBLE - long double LD; -#endif - - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - ASSERT(pNumber); - /* - * This function handles 64-bit number over a pointer on 32-bit CPUs. - */ - ASSERT((sizeof(*pNumber) * CHAR_BIT < WIDTH_64) || (zDeserializeTypeWidth(pType) >= WIDTH_64)); - ASSERT(sizeof(D) == sizeof(uint64_t)); -#ifdef __HAVE_LONG_DOUBLE - ASSERT(sizeof(LD) > sizeof(uint64_t)); -#endif - - switch (zDeserializeTypeWidth(pType)) { -#ifdef __HAVE_LONG_DOUBLE - case WIDTH_128: - /* FALLTHROUGH */ - case WIDTH_96: - /* FALLTHROUGH */ - case WIDTH_80: - memcpy(&LD, pNumber, sizeof(long double)); - snprintf(pBuffer, zBUfferLength, "%Lg", LD); - break; -#endif - case WIDTH_64: - memcpy(&D, pNumber, sizeof(double)); - snprintf(pBuffer, zBUfferLength, "%g", D); - break; - } -} - -static void -DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - float F; - double D; - uint32_t U32; - - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - ASSERT(sizeof(F) == sizeof(uint32_t)); - ASSERT(sizeof(D) == sizeof(uint64_t)); - - switch (zDeserializeTypeWidth(pType)) { - case WIDTH_64: - memcpy(&D, &ulNumber, sizeof(double)); - snprintf(pBuffer, zBUfferLength, "%g", D); - break; - case WIDTH_32: - /* - * On supported platforms sizeof(float)==sizeof(uint32_t) - * unsigned long is either 32 or 64-bit, cast it to 32-bit - * value in order to call memcpy(3) in an Endian-aware way. - */ - U32 = STATIC_CAST(uint32_t, ulNumber); - memcpy(&F, &U32, sizeof(float)); - snprintf(pBuffer, zBUfferLength, "%g", F); - break; - case WIDTH_16: - snprintf(pBuffer, zBUfferLength, "Undecoded-16-bit-Floating-Type (%#04" PRIx16 ")", STATIC_CAST(uint16_t, ulNumber)); - break; - } -} -#endif - -static longest -llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - size_t zNumberWidth; - longest L = 0; - - ASSERT(szLocation); - ASSERT(pType); - - zNumberWidth = zDeserializeTypeWidth(pType); - switch (zNumberWidth) { - default: - Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation); - __unreachable(); - /* NOTREACHED */ - case WIDTH_128: -#ifdef __SIZEOF_INT128__ - memcpy(&L, REINTERPRET_CAST(longest *, ulNumber), sizeof(longest)); - break; -#else - Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation); - __unreachable(); - /* NOTREACHED */ -#endif - case WIDTH_64: - if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) { - L = *REINTERPRET_CAST(int64_t *, ulNumber); - } else { - L = STATIC_CAST(int64_t, STATIC_CAST(uint64_t, ulNumber)); - } - break; - case WIDTH_32: - L = STATIC_CAST(int32_t, STATIC_CAST(uint32_t, ulNumber)); - break; - case WIDTH_16: - L = STATIC_CAST(int16_t, STATIC_CAST(uint16_t, ulNumber)); - break; - case WIDTH_8: - L = STATIC_CAST(int8_t, STATIC_CAST(uint8_t, ulNumber)); - break; - } - - return L; -} - -static ulongest -llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - size_t zNumberWidth; - ulongest UL = 0; - - ASSERT(pType); - - zNumberWidth = zDeserializeTypeWidth(pType); - switch (zNumberWidth) { - default: - Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation); - __unreachable(); - /* NOTREACHED */ - case WIDTH_128: -#ifdef __SIZEOF_INT128__ - memcpy(&UL, REINTERPRET_CAST(ulongest *, ulNumber), sizeof(ulongest)); - break; -#else - Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation); - __unreachable(); - /* NOTREACHED */ -#endif - case WIDTH_64: - if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) { - UL = *REINTERPRET_CAST(uint64_t *, ulNumber); - break; - } - /* FALLTHROUGH */ - case WIDTH_32: - /* FALLTHROUGH */ - case WIDTH_16: - /* FALLTHROUGH */ - case WIDTH_8: - UL = ulNumber; - break; - } - - return UL; -} - -#ifndef _KERNEL -static void -DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - size_t zNumberWidth; - - ASSERT(szLocation); - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - ASSERT(pType->mTypeKind == KIND_FLOAT); - - zNumberWidth = zDeserializeTypeWidth(pType); - switch (zNumberWidth) { - default: - Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation); - __unreachable(); - /* NOTREACHED */ -#ifdef __HAVE_LONG_DOUBLE - case WIDTH_128: - /* FALLTHROUGH */ - case WIDTH_96: - /* FALLTHROUGH */ - case WIDTH_80: - DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber)); - break; -#endif - case WIDTH_64: - if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) { - DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber)); - break; - } - /* FALLTHROUGH */ - case WIDTH_32: - /* FALLTHROUGH */ - case WIDTH_16: - DeserializeFloatInlined(pBuffer, zBUfferLength, pType, ulNumber); - break; - } -} -#endif - -static void -DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - - ASSERT(szLocation); - ASSERT(pBuffer); - ASSERT(zBUfferLength > 0); - ASSERT(pType); - - switch(pType->mTypeKind) { - case KIND_INTEGER: - if (ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)) { - longest L = llliGetNumber(szLocation, pType, ulNumber); - DeserializeNumberSigned(pBuffer, zBUfferLength, pType, L); - } else { - ulongest UL = llluGetNumber(szLocation, pType, ulNumber); - DeserializeNumberUnsigned(pBuffer, zBUfferLength, pType, UL); - } - break; - case KIND_FLOAT: -#ifdef _KERNEL - Report(true, "UBSan: Unexpected Float Type in %s\n", szLocation); - __unreachable(); - /* NOTREACHED */ -#else - DeserializeNumberFloat(szLocation, pBuffer, zBUfferLength, pType, ulNumber); - break; -#endif - case KIND_UNKNOWN: - Report(true, "UBSan: Unknown Type in %s\n", szLocation); - __unreachable(); - /* NOTREACHED */ - } -} - -static const char * -DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind) -{ - const char *rgczTypeCheckKinds[] = { - "load of", - "store to", - "reference binding to", - "member access within", - "member call on", - "constructor call on", - "downcast of", - "downcast of", - "upcast of", - "cast to virtual base of", - "_Nonnull binding to", - "dynamic operation on" - }; - - ASSERT(__arraycount(rgczTypeCheckKinds) > hhuTypeCheckKind); - - return rgczTypeCheckKinds[hhuTypeCheckKind]; -} - -static const char * -DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind) -{ - const char *rgczBuiltinCheckKinds[] = { - "ctz()", - "clz()" - }; - - ASSERT(__arraycount(rgczBuiltinCheckKinds) > hhuBuiltinCheckKind); - - return rgczBuiltinCheckKinds[hhuBuiltinCheckKind]; -} - -static const char * -DeserializeCFICheckKind(uint8_t hhuCFICheckKind) -{ - const char *rgczCFICheckKinds[] = { - "virtual call", // CFI_VCALL - "non-virtual call", // CFI_NVCALL - "base-to-derived cast", // CFI_DERIVEDCAST - "cast to unrelated type", // CFI_UNRELATEDCAST - "indirect function call", // CFI_ICALL - "non-virtual pointer to member function call", // CFI_NVMFCALL - "virtual pointer to member function call", // CFI_VMFCALL - }; - - ASSERT(__arraycount(rgczCFICheckKinds) > hhuCFICheckKind); - - return rgczCFICheckKinds[hhuCFICheckKind]; -} - -static const char * -DeserializeImplicitConversionCheckKind(uint8_t hhuImplicitConversionCheckKind) -{ - const char *rgczImplicitConversionCheckKind[] = { - "integer truncation", - "unsigned integer truncation", - "signed integer truncation", - "integer sign change", - "signed integer trunctation or sign change", - }; - - ASSERT(__arraycount(rgczImplicitConversionCheckKind) > hhuImplicitConversionCheckKind); - - return rgczImplicitConversionCheckKind[hhuImplicitConversionCheckKind]; -} - -static bool -isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber) -{ - - ASSERT(szLocation); - ASSERT(pType); - ASSERT(pType->mTypeKind == KIND_INTEGER); - - if (!ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)) - return false; - - return llliGetNumber(szLocation, pType, ulNumber) < 0; -} - -static bool -isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth) -{ - - ASSERT(szLocation); - ASSERT(pType); - ASSERT(pType->mTypeKind == KIND_INTEGER); - - return llluGetNumber(szLocation, pType, ulNumber) >= zWidth; -} - -#endif // HAVE_UBSAN_SUPPORT diff --git a/Library/OcGuardLib/Ubsan.h b/Library/OcGuardLib/Ubsan.h deleted file mode 100644 index 1e34ef0f6..000000000 --- a/Library/OcGuardLib/Ubsan.h +++ /dev/null @@ -1,208 +0,0 @@ -/** @file - -OcGuardLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef UBSAN_H -#define UBSAN_H - -#include -#include -#include -#include -#include - -// Pretend UEFI to mean kernel mode. -#ifndef _KERNEL -#define _KERNEL 1 -#endif - -#if !defined(HAVE_UBSAN_SUPPORT) && defined(__clang__) -#define HAVE_UBSAN_SUPPORT 1 -#endif - - -// Mark long double as supported (since we may use softfp). -#ifndef __HAVE_LONG_DOUBLE -#define __HAVE_LONG_DOUBLE -#endif - -// Non-BSD environments do not support RCSID. -#ifndef __RCSID -#define __RCSID(x) -#endif - -#ifndef __KERNEL_RCSID -#define __KERNEL_RCSID(x, s) __RCSID(s) -#endif - -// Implement builtin via macros, because some toolchains do include stdint.h. -// This works only because Ubsan.c is not allowed to have any header inclusion. -#define int8_t INT8 -#define int16_t INT16 -#define int32_t INT32 -#define int64_t INT64 -#define uint8_t UINT8 -#define uint16_t UINT16 -#define uint32_t UINT32 -#define uint64_t UINT64 -#define bool BOOLEAN -#define intptr_t INTN -#define uintptr_t UINTN - -// Try to provide a somewhat adequate size_t implementation. -// Have to be careful about -Wformat warnings in Clang. -#ifdef __GNUC__ -#define ssize_t long -#define size_t unsigned long -#else -#define ssize_t INTN -#define size_t UINTN -#endif - -// Provide boolean declarations if missing. -#ifndef false -#define false FALSE -#define true TRUE -#endif - -// Provide va_list declarations. -#define va_list VA_LIST -#define va_start VA_START -#define va_end VA_END -#define va_arg VA_ARG - -// Printing macros are not supported in EDK2. -#ifndef PRIx8 -#define PRIx8 "hhx" -#define PRIx16 "hx" -#define PRIx32 "x" -#define PRIx64 "llx" -#define PRId32 "d" -#define PRId64 "lld" -#define PRIu32 "u" -#define PRIu64 "llu" -#endif - -// Hack limits in. -#ifndef UINT16_MAX -#define UINT8_MAX 0xffU -#define UINT16_MAX 0xffffU -#define UINT32_MAX 0xffffffffU -#define UINT64_MAX 0xffffffffffffffffULL -#endif - -// Avoid ASSERT/KASSERT conflict from DebugLib. -#ifdef ASSERT -#undef ASSERT -#endif - -// Implement KASSERT as the original EDK2 ASSERT. -#if !defined(MDEPKG_NDEBUG) - #define KASSERT(Expression) \ - do { \ - if (DebugAssertEnabled ()) { \ - if (!(Expression)) { \ - _ASSERT (Expression); \ - ANALYZER_UNREACHABLE (); \ - } \ - } \ - } while (FALSE) -#else - #define KASSERT(Expression) -#endif - -// PATH_MAX is an unoffical extension. -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -// CHAR_BIT may not be defined without limits.h. -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -// Bit manipulation is not present -#ifndef __BIT -#define __BIT(__n) \ - (((UINTN)(__n) >= CHAR_BIT * sizeof(UINTN)) ? 0 : \ - ((UINTN)1 << (UINTN)((__n) & (CHAR_BIT * sizeof(UINTN) - 1)))) -#endif - -// Extended bit manipulation is also not present -#ifndef __LOWEST_SET_BIT -/* find least significant bit that is set */ -#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) -#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask)) -#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask)) -#define __SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask)) -#endif - -// BSD-like bit manipulation is not present -#ifndef CLR -#define SET(t, f) ((t) |= (f)) -#define ISSET(t, f) ((t) & (f)) -#define CLR(t, f) ((t) &= ~(f)) -#endif - -// Note, that we do not use UEFI-like printf. -#ifndef __printflike -#ifdef __GNUC__ -#define __printflike(x, y) __attribute__((format(printf, (x), (y)))) -#else -#define __printflike(x, y) -#endif -#endif - -// Route arraycount to ARRAY_SIZE -#ifndef __arraycount -#define __arraycount(a) ARRAY_SIZE (a) -#endif - -// Support unreachable where possible -#ifndef __unreachable -#ifdef __GNUC__ -#define __unreachable() __builtin_unreachable() -#else -#define __unreachable() -#endif -#endif - -// C-style printing support. -#define TINYPRINTF_DEFINE_TFP_SPRINTF 1 -typedef void (*putcf) (void *, char); -void EFIAPI tfp_format(void *putp, putcf putf, const char *fmt, va_list va); -int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); -int EFIAPI tfp_snprintf(char *str, size_t size, const char *fmt, ...) __printflike(3, 4); -int EFIAPI tfp_vsprintf(char *str, const char *fmt, va_list ap); -int EFIAPI tfp_sprintf(char *str, const char *fmt, ...) __printflike(2, 3); - -// Redirect log printing to standard output. -#define snprintf tfp_snprintf -#define vprintf(f, v) \ - do { CHAR8 Tmp__[1024]; tfp_vsnprintf (Tmp__, sizeof (Tmp__), f, v); AsciiPrint ("%a", Tmp__); } while (0) -#define vpanic(f, v) \ - do { vprintf (f, v); do { } while (1); } while (0) - -// Avoid implementing memcpy as a function to avoid LTO conflicts. -#define memcpy(Dst, Src, Size) do { CopyMem(Dst, Src, Size); } while (0) - -// Forcing VOID for those as the return types actually differ. -#define strlcpy(Dst, Src, Size) do { AsciiStrnCpyS (Dst, Size, Src, AsciiStrLen(Src)); } while (0) -#define strlcat(Dst, Src, Size) do { AsciiStrnCatS (Dst, Size, Src, AsciiStrLen(Src)); } while (0) - - -#endif // UBSAN_H diff --git a/Library/OcGuardLib/UbsanPrintf.c b/Library/OcGuardLib/UbsanPrintf.c deleted file mode 100644 index 8ac283b96..000000000 --- a/Library/OcGuardLib/UbsanPrintf.c +++ /dev/null @@ -1,537 +0,0 @@ -/* -File: tinyprintf.c - -Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "Ubsan.h" - -#ifdef HAVE_UBSAN_SUPPORT - -/* - * Configuration - */ - -/* Enable long int support */ -#define PRINTF_LONG_SUPPORT - -/* Enable long long int support (implies long int support) */ -#define PRINTF_LONG_LONG_SUPPORT - -/* Enable %z (size_t) support */ -#define PRINTF_SIZE_T_SUPPORT - -/* - * Configuration adjustments - */ -#ifdef PRINTF_SIZE_T_SUPPORT -// #include -#endif - -#ifdef PRINTF_LONG_LONG_SUPPORT -# define PRINTF_LONG_SUPPORT -#endif - -/* __SIZEOF___ defined at least by gcc */ -#ifdef __SIZEOF_POINTER__ -# define SIZEOF_POINTER __SIZEOF_POINTER__ -#endif -#ifdef __SIZEOF_LONG_LONG__ -# define SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__ -#endif -#ifdef __SIZEOF_LONG__ -# define SIZEOF_LONG __SIZEOF_LONG__ -#endif -#ifdef __SIZEOF_INT__ -# define SIZEOF_INT __SIZEOF_INT__ -#endif - -#ifdef __GNUC__ -# define _TFP_GCC_NO_INLINE_ __attribute__ ((noinline)) -#else -# define _TFP_GCC_NO_INLINE_ -#endif - -/* - * Implementation - */ -struct param { - char lz:1; /**< Leading zeros */ - char alt:1; /**< alternate form */ - char uc:1; /**< Upper case (for base16 only) */ - char align_left:1; /**< 0 == align right (default), 1 == align left */ - unsigned int width; /**< field width */ - char sign; /**< The sign to display (if any) */ - unsigned int base; /**< number base (e.g.: 8, 10, 16) */ - char *bf; /**< Buffer to output */ -}; - - -#ifdef PRINTF_LONG_LONG_SUPPORT -static void _TFP_GCC_NO_INLINE_ ulli2a( - unsigned long long int num, struct param *p) -{ - int n = 0; - unsigned long long int d = 1; - char *bf = p->bf; - while (num / d >= p->base) - d *= p->base; - while (d != 0) { - int dgt = num / d; - num %= d; - d /= p->base; - if (n || dgt > 0 || d == 0) { - *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); - ++n; - } - } - *bf = 0; -} - -static void lli2a(long long int num, struct param *p) -{ - if (num < 0) { - num = -num; - p->sign = '-'; - } - ulli2a(num, p); -} -#endif - -#ifdef PRINTF_LONG_SUPPORT -static void uli2a(unsigned long int num, struct param *p) -{ - int n = 0; - unsigned long int d = 1; - char *bf = p->bf; - while (num / d >= p->base) - d *= p->base; - while (d != 0) { - int dgt = num / d; - num %= d; - d /= p->base; - if (n || dgt > 0 || d == 0) { - *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); - ++n; - } - } - *bf = 0; -} - -static void li2a(long num, struct param *p) -{ - if (num < 0) { - num = -num; - p->sign = '-'; - } - uli2a(num, p); -} -#endif - -static void ui2a(unsigned int num, struct param *p) -{ - int n = 0; - unsigned int d = 1; - char *bf = p->bf; - while (num / d >= p->base) - d *= p->base; - while (d != 0) { - int dgt = num / d; - num %= d; - d /= p->base; - if (n || dgt > 0 || d == 0) { - *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); - ++n; - } - } - *bf = 0; -} - -static void i2a(int num, struct param *p) -{ - if (num < 0) { - num = -num; - p->sign = '-'; - } - ui2a(num, p); -} - -static int a2d(char ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else - return -1; -} - -static char a2u(char ch, const char **src, int base, unsigned int *nump) -{ - const char *p = *src; - unsigned int num = 0; - int digit; - while ((digit = a2d(ch)) >= 0) { - if (digit > base) - break; - num = num * base + digit; - ch = *p++; - } - *src = p; - *nump = num; - return ch; -} - -static void putchw(void *putp, putcf putf, struct param *p) -{ - char ch; - int n = p->width; - char *bf = p->bf; - - /* Number of filling characters */ - while (*bf++ && n > 0) - n--; - if (p->sign) - n--; - if (p->alt && p->base == 16) - n -= 2; - else if (p->alt && p->base == 8) - n--; - - /* Fill with space to align to the right, before alternate or sign */ - if (!p->lz && !p->align_left) { - while (n-- > 0) - putf(putp, ' '); - } - - /* print sign */ - if (p->sign) - putf(putp, p->sign); - - /* Alternate */ - if (p->alt && p->base == 16) { - putf(putp, '0'); - putf(putp, (p->uc ? 'X' : 'x')); - } else if (p->alt && p->base == 8) { - putf(putp, '0'); - } - - /* Fill with zeros, after alternate or sign */ - if (p->lz) { - while (n-- > 0) - putf(putp, '0'); - } - - /* Put actual buffer */ - bf = p->bf; - while ((ch = *bf++)) - putf(putp, ch); - - /* Fill with space to align to the left, after string */ - if (!p->lz && p->align_left) { - while (n-- > 0) - putf(putp, ' '); - } -} - -void EFIAPI tfp_format(void *putp, putcf putf, const char *fmt, va_list va) -{ - struct param p; -#ifdef PRINTF_LONG_SUPPORT - char bf[23]; /* long = 64b on some architectures */ -#else - char bf[12]; /* int = 32b on some architectures */ -#endif - char ch; - p.bf = bf; - - while ((ch = *(fmt++))) { - if (ch != '%') { - putf(putp, ch); - } else { -#ifdef PRINTF_LONG_SUPPORT - char lng = 0; /* 1 for long, 2 for long long */ -#endif - /* Init parameter struct */ - p.lz = 0; - p.alt = 0; - p.width = 0; - p.align_left = 0; - p.sign = 0; - - /* Flags */ - while ((ch = *(fmt++))) { - switch (ch) { - case '-': - p.align_left = 1; - continue; - case '0': - p.lz = 1; - continue; - case '#': - p.alt = 1; - continue; - default: - break; - } - break; - } - - /* Width */ - if (ch >= '0' && ch <= '9') { - ch = a2u(ch, &fmt, 10, &(p.width)); - } - - /* We accept 'x.y' format but don't support it completely: - * we ignore the 'y' digit => this ignores 0-fill - * size and makes it == width (ie. 'x') */ - if (ch == '.') { - p.lz = 1; /* zero-padding */ - /* ignore actual 0-fill size: */ - do { - ch = *(fmt++); - } while ((ch >= '0') && (ch <= '9')); - } - -#ifdef PRINTF_SIZE_T_SUPPORT -# ifdef PRINTF_LONG_SUPPORT - if (ch == 'z') { - ch = *(fmt++); - if (sizeof(size_t) == sizeof(unsigned long int)) - lng = 1; -# ifdef PRINTF_LONG_LONG_SUPPORT - else if (sizeof(size_t) == sizeof(unsigned long long int)) - lng = 2; -# endif - } else -# endif -#endif - -#ifdef PRINTF_LONG_SUPPORT - if (ch == 'l') { - ch = *(fmt++); - lng = 1; -#ifdef PRINTF_LONG_LONG_SUPPORT - if (ch == 'l') { - ch = *(fmt++); - lng = 2; - } -#endif - } -#endif - switch (ch) { - case 0: - goto abort; - case 'u': - p.base = 10; - p.uc = 0; -#ifdef PRINTF_LONG_SUPPORT -#ifdef PRINTF_LONG_LONG_SUPPORT - if (2 == lng) - ulli2a(va_arg(va, unsigned long long int), &p); - else -#endif - if (1 == lng) - uli2a(va_arg(va, unsigned long int), &p); - else -#endif - ui2a(va_arg(va, unsigned int), &p); - putchw(putp, putf, &p); - break; - case 'd': - case 'i': - p.base = 10; -#ifdef PRINTF_LONG_SUPPORT -#ifdef PRINTF_LONG_LONG_SUPPORT - if (2 == lng) - lli2a(va_arg(va, long long int), &p); - else -#endif - if (1 == lng) - li2a(va_arg(va, long int), &p); - else -#endif - i2a(va_arg(va, int), &p); - putchw(putp, putf, &p); - break; -#ifdef SIZEOF_POINTER - case 'p': - p.alt = 1; -# if defined(SIZEOF_INT) && SIZEOF_POINTER <= SIZEOF_INT - lng = 0; -# elif defined(SIZEOF_LONG) && SIZEOF_POINTER <= SIZEOF_LONG - lng = 1; -# elif defined(SIZEOF_LONG_LONG) && SIZEOF_POINTER <= SIZEOF_LONG_LONG - lng = 2; -# endif - // Fallthrough -#endif - case 'x': - case 'X': - p.base = 16; - p.uc = (ch == 'X')?1:0; -#ifdef PRINTF_LONG_SUPPORT -#ifdef PRINTF_LONG_LONG_SUPPORT - if (2 == lng) - ulli2a(va_arg(va, unsigned long long int), &p); - else -#endif - if (1 == lng) - uli2a(va_arg(va, unsigned long int), &p); - else -#endif - ui2a(va_arg(va, unsigned int), &p); - putchw(putp, putf, &p); - break; - case 'o': - p.base = 8; - p.uc = 0; - ui2a(va_arg(va, unsigned int), &p); - putchw(putp, putf, &p); - break; - case 'c': - putf(putp, (char)(va_arg(va, int))); - break; - case 's': - p.bf = va_arg(va, char *); - putchw(putp, putf, &p); - p.bf = bf; - break; - case '%': - putf(putp, ch); - default: - break; - } - } - } - abort:; -} - -#if TINYPRINTF_DEFINE_TFP_PRINTF -static putcf stdout_putf; -static void *stdout_putp; - -void init_printf(void *putp, putcf putf) -{ - stdout_putf = putf; - stdout_putp = putp; -} - -void EFIAPI tfp_printf(char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - tfp_format(stdout_putp, stdout_putf, fmt, va); - va_end(va); -} -#endif - -#if TINYPRINTF_DEFINE_TFP_SPRINTF -struct _vsnprintf_putcf_data -{ - size_t dest_capacity; - char *dest; - size_t num_chars; -}; - -static void _vsnprintf_putcf(void *p, char c) -{ - struct _vsnprintf_putcf_data *data = (struct _vsnprintf_putcf_data*)p; - if (data->num_chars < data->dest_capacity) - data->dest[data->num_chars] = c; - data->num_chars ++; -} - -int tfp_vsnprintf(char *str, size_t size, const char *format, va_list ap) -{ - struct _vsnprintf_putcf_data data; - - if (size < 1) - return 0; - - data.dest = str; - data.dest_capacity = size-1; - data.num_chars = 0; - tfp_format(&data, _vsnprintf_putcf, format, ap); - - if (data.num_chars < data.dest_capacity) - data.dest[data.num_chars] = '\0'; - else - data.dest[data.dest_capacity] = '\0'; - - return data.num_chars; -} - -int EFIAPI tfp_snprintf(char *str, size_t size, const char *format, ...) -{ - va_list ap; - int retval; - - va_start(ap, format); - retval = tfp_vsnprintf(str, size, format, ap); - va_end(ap); - return retval; -} - -struct _vsprintf_putcf_data -{ - char *dest; - size_t num_chars; -}; - -static void _vsprintf_putcf(void *p, char c) -{ - struct _vsprintf_putcf_data *data = (struct _vsprintf_putcf_data*)p; - data->dest[data->num_chars++] = c; -} - -int EFIAPI tfp_vsprintf(char *str, const char *format, va_list ap) -{ - struct _vsprintf_putcf_data data; - data.dest = str; - data.num_chars = 0; - tfp_format(&data, _vsprintf_putcf, format, ap); - data.dest[data.num_chars] = '\0'; - return data.num_chars; -} - -int EFIAPI tfp_sprintf(char *str, const char *format, ...) -{ - va_list ap; - int retval; - - va_start(ap, format); - retval = tfp_vsprintf(str, format, ap); - va_end(ap); - return retval; -} -#endif - -#endif // HAVE_UBSAN_SUPPORT - diff --git a/Library/OcMemoryLib/LegacyRegionLock.c b/Library/OcMemoryLib/LegacyRegionLock.c deleted file mode 100755 index 3ffb77385..000000000 --- a/Library/OcMemoryLib/LegacyRegionLock.c +++ /dev/null @@ -1,81 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** Lock the legacy region specified to enable modification. - - @param[in] LegacyAddress The address of the region to lock. - @param[in] LegacyLength The size of the region to lock. - - @retval EFI_SUCCESS The region was locked successfully. -**/ -EFI_STATUS -LegacyRegionLock ( - IN UINT32 LegacyAddress, - IN UINT32 LegacyLength - ) -{ - EFI_STATUS Status; - - EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol; - UINT32 Granularity; - - LegacyRegionProtocol = NULL; - Status = gBS->LocateProtocol ( - &gEfiLegacyRegionProtocolGuid, - NULL, - (VOID **) &LegacyRegionProtocol - ); - - if (!EFI_ERROR(Status)) { - // - // Lock Region Using LegacyRegionProtocol - // - - Granularity = 0; - Status = LegacyRegionProtocol->Lock ( - LegacyRegionProtocol, - LegacyAddress, - LegacyLength, - &Granularity - ); - DEBUG (( - DEBUG_INFO, - "Lock LegacyRegion 0x%0X-0x%0X - %r\n", - LegacyAddress, - (LegacyAddress + (LegacyLength - 1)), - Status - )); - } - - return Status; -} diff --git a/Library/OcMemoryLib/LegacyRegionUnLock.c b/Library/OcMemoryLib/LegacyRegionUnLock.c deleted file mode 100755 index a5d4a4e53..000000000 --- a/Library/OcMemoryLib/LegacyRegionUnLock.c +++ /dev/null @@ -1,81 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** Unlock the legacy region specified to enable modification. - - @param[in] LegacyAddress The address of the region to unlock. - @param[in] LegacyLength The size of the region to unlock. - - @retval EFI_SUCCESS The region was unlocked successfully. -**/ -EFI_STATUS -LegacyRegionUnlock ( - IN UINT32 LegacyAddress, - IN UINT32 LegacyLength - ) -{ - EFI_STATUS Status; - - EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol; - UINT32 Granularity; - - Status = gBS->LocateProtocol ( - &gEfiLegacyRegionProtocolGuid, - NULL, - (VOID **) &LegacyRegionProtocol - ); - - if (!EFI_ERROR(Status)) { - // - // Unlock Region Using LegacyRegionProtocol - // - Granularity = 0; - Status = LegacyRegionProtocol->UnLock ( - LegacyRegionProtocol, - LegacyAddress, - LegacyLength, - &Granularity - ); - - DEBUG (( - DEBUG_INFO, - "Unlock LegacyRegion %0X-%0X - %r\n", - LegacyAddress, - (LegacyAddress + (LegacyLength - 1)), - Status - )); - } - - return Status; -} - diff --git a/Library/OcMemoryLib/MemoryAlloc.c b/Library/OcMemoryLib/MemoryAlloc.c deleted file mode 100644 index 14b7b2e77..000000000 --- a/Library/OcMemoryLib/MemoryAlloc.c +++ /dev/null @@ -1,197 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_STATUS -OcAllocatePagesFromTop ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory, - IN EFI_GET_MEMORY_MAP GetMemoryMap, - IN CHECK_ALLOCATION_RANGE CheckRange OPTIONAL - ) -{ - EFI_STATUS Status; - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MapKey; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR *Desc; - - Status = OcGetCurrentMemoryMapAlloc ( - &MemoryMapSize, - &MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion, - GetMemoryMap, - NULL - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - MemoryMapEnd = NEXT_MEMORY_DESCRIPTOR (MemoryMap, MemoryMapSize); - Desc = PREV_MEMORY_DESCRIPTOR (MemoryMapEnd, DescriptorSize); - - for ( ; Desc >= MemoryMap; Desc = PREV_MEMORY_DESCRIPTOR (Desc, DescriptorSize)) { - // - // We are looking for some free memory descriptor that contains enough - // space below the specified memory. - // - if (Desc->Type == EfiConventionalMemory && Pages <= Desc->NumberOfPages && - Desc->PhysicalStart + EFI_PAGES_TO_SIZE (Pages) <= *Memory) { - - // - // Free block found - // - if (Desc->PhysicalStart + EFI_PAGES_TO_SIZE (Desc->NumberOfPages) <= *Memory) { - // - // The whole block is under Memory: allocate from the top of the block - // - *Memory = Desc->PhysicalStart + EFI_PAGES_TO_SIZE (Desc->NumberOfPages - Pages); - } else { - // - // The block contains enough pages under Memory, but spans above it - allocate below Memory - // - *Memory = *Memory - EFI_PAGES_TO_SIZE (Pages); - } - - // - // Ensure that the found block does not overlap with the restricted area. - // - if (CheckRange != NULL && CheckRange (*Memory, EFI_PAGES_TO_SIZE (Pages))) { - continue; - } - - Status = gBS->AllocatePages ( - AllocateAddress, - MemoryType, - Pages, - Memory - ); - - break; - } - } - - FreePool (MemoryMap); - - return Status; -} - -UINT64 -OcCountRuntimePages ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize, - OUT UINTN *DescriptorCount OPTIONAL - ) -{ - UINTN DescNum; - UINT64 PageNum; - UINTN NumEntries; - UINTN Index; - EFI_MEMORY_DESCRIPTOR *Desc; - - DescNum = 0; - PageNum = 0; - NumEntries = MemoryMapSize / DescriptorSize; - Desc = MemoryMap; - - for (Index = 0; Index < NumEntries; ++Index) { - if (Desc->Type != EfiReservedMemoryType - && (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0) { - ++DescNum; - PageNum += Desc->NumberOfPages; - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - } - - if (DescriptorCount != NULL) { - *DescriptorCount = DescNum; - } - - return PageNum; -} - -UINTN -OcCountFreePages ( - OUT UINTN *LowerMemory OPTIONAL - ) -{ - UINTN MemoryMapSize; - UINTN DescriptorSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - EFI_MEMORY_DESCRIPTOR *EntryWalker; - UINTN FreePages; - - FreePages = 0; - if (LowerMemory != NULL) { - *LowerMemory = 0; - } - - MemoryMap = OcGetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL, NULL, FALSE); - if (MemoryMap == NULL) { - return 0; - } - - for ( - EntryWalker = MemoryMap; - (UINT8 *) EntryWalker < ((UINT8 *) MemoryMap + MemoryMapSize); - EntryWalker = NEXT_MEMORY_DESCRIPTOR (EntryWalker, DescriptorSize)) { - - if (EntryWalker->Type != EfiConventionalMemory) { - continue; - } - - // - // This cannot overflow even on 32-bit systems unless they have > 16 TB of RAM, - // just assert to ensure that we have valid MemoryMap. - // - ASSERT (EntryWalker->NumberOfPages <= MAX_UINTN); - ASSERT (MAX_UINTN - EntryWalker->NumberOfPages >= FreePages); - FreePages += (UINTN) EntryWalker->NumberOfPages; - - if (LowerMemory == NULL || EntryWalker->PhysicalStart >= BASE_4GB) { - continue; - } - - if (EntryWalker->PhysicalStart + EFI_PAGES_TO_SIZE (EntryWalker->NumberOfPages) > BASE_4GB) { - *LowerMemory += (UINTN) EFI_SIZE_TO_PAGES (BASE_4GB - EntryWalker->PhysicalStart); - } else { - *LowerMemory += (UINTN) EntryWalker->NumberOfPages; - } - } - - FreePool (MemoryMap); - - return FreePages; -} diff --git a/Library/OcMemoryLib/MemoryAttributes.c b/Library/OcMemoryLib/MemoryAttributes.c deleted file mode 100644 index e01e11d04..000000000 --- a/Library/OcMemoryLib/MemoryAttributes.c +++ /dev/null @@ -1,625 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Determine actual memory type from the attribute. - - @param[in] MemoryAttribute Attribute to inspect. -**/ -STATIC -UINT32 -OcRealMemoryType ( - IN EFI_MEMORY_DESCRIPTOR *MemoryAttribte - ) -{ - ASSERT (MemoryAttribte->Type == EfiRuntimeServicesCode - || MemoryAttribte->Type == EfiRuntimeServicesData); - - // - // Use code for write-protected areas. - // - if ((MemoryAttribte->Attribute & EFI_MEMORY_RO) != 0) { - return EfiRuntimeServicesCode; - } - - // - // Use data for executable-protected areas. - // - if ((MemoryAttribte->Attribute & EFI_MEMORY_XP) != 0) { - return EfiRuntimeServicesData; - } - - // - // Use whatever is set. - // - return MemoryAttribte->Type; -} - -/** - Split memory map descriptor by attribute. - - @param[in,out] RetMemoryMapEntry Pointer to descriptor in the memory map, updated to next proccessed. - @param[in,out] CurrentEntryIndex Current index of the descriptor in the memory map, updated on increase. - @param[in,out] CurrentEntryCount Number of descriptors in the memory map, updated on increase. - @param[in] TotalEntryCount Max number of descriptors in the memory map. - @param[in] MemoryAttribute Memory attribute used for splitting. - @param[in] DescriptorSize Memory map descriptor size. - - @retval EFI_SUCCESS on success. - @retval EFI_OUT_OF_RESOURCES when there are not enough free descriptor slots. -**/ -STATIC -EFI_STATUS -OcSplitMemoryEntryByAttribute ( - IN OUT EFI_MEMORY_DESCRIPTOR **RetMemoryMapEntry, - IN OUT UINTN *CurrentEntryIndex, - IN OUT UINTN *CurrentEntryCount, - IN UINTN TotalEntryCount, - IN EFI_MEMORY_DESCRIPTOR *MemoryAttribute, - IN UINTN DescriptorSize - - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; - UINTN DiffPages; - - MemoryMapEntry = *RetMemoryMapEntry; - - // - // Memory attribute starts after our descriptor. - // Shorten the existing descriptor and insert the new one after it. - // [DESC1] -> [DESC1][DESC2] - // - if (MemoryAttribute->PhysicalStart > MemoryMapEntry->PhysicalStart) { - if (*CurrentEntryCount == TotalEntryCount) { - return EFI_OUT_OF_RESOURCES; - } - - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - DiffPages = (UINTN) EFI_SIZE_TO_PAGES (MemoryAttribute->PhysicalStart - MemoryMapEntry->PhysicalStart); - CopyMem ( - NewMemoryMapEntry, - MemoryMapEntry, - DescriptorSize * (*CurrentEntryCount - *CurrentEntryIndex) - ); - MemoryMapEntry->NumberOfPages = DiffPages; - NewMemoryMapEntry->PhysicalStart = MemoryAttribute->PhysicalStart; - NewMemoryMapEntry->NumberOfPages -= DiffPages; - - MemoryMapEntry = NewMemoryMapEntry; - - // - // Current processed entry is now the one we inserted. - // - ++(*CurrentEntryIndex); - ++(*CurrentEntryCount); - } - - ASSERT (MemoryAttribute->PhysicalStart == MemoryMapEntry->PhysicalStart); - - // - // Memory attribute matches our descriptor. - // Simply update its protection. - // [DESC1] -> [DESC1*] - // - if (MemoryMapEntry->NumberOfPages == MemoryAttribute->NumberOfPages) { - MemoryMapEntry->Type = OcRealMemoryType (MemoryAttribute); - *RetMemoryMapEntry = MemoryMapEntry; - return EFI_SUCCESS; - } - - // - // Memory attribute is shorter than our descriptor. - // Shorten current descriptor, update its type, and inseret the new one after it. - // [DESC1] -> [DESC1*][DESC2] - // - if (*CurrentEntryCount == TotalEntryCount) { - return EFI_OUT_OF_RESOURCES; - } - - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - CopyMem ( - NewMemoryMapEntry, - MemoryMapEntry, - DescriptorSize * (*CurrentEntryCount - *CurrentEntryIndex) - ); - MemoryMapEntry->Type = OcRealMemoryType (MemoryAttribute); - MemoryMapEntry->NumberOfPages = MemoryAttribute->NumberOfPages; - NewMemoryMapEntry->PhysicalStart += EFI_PAGES_TO_SIZE (MemoryAttribute->NumberOfPages); - NewMemoryMapEntry->NumberOfPages -= MemoryAttribute->NumberOfPages; - - // - // Current processed entry is now the one we need to process. - // - ++(*CurrentEntryIndex); - ++(*CurrentEntryCount); - - *RetMemoryMapEntry = NewMemoryMapEntry; - - return EFI_SUCCESS; -} - -/** - Expand attributes table by adding memory map runtime entries into it. - Requires sorted memory map. - - @param[in,out] MemoryAttributesTable Memory attributes table. - @param[in,out] MemoryAttributesEntry Memory attributes descriptor. - @param[in] MaxDescriptors Maximum amount of descriptors in the attributes table. - @param[in] MemoryMapDescriptors Memory map descriptor count. - @param[in] MemoryMap Memory map. - @param[in] DescriptorSize Memory map descriptor size. - - @retval EFI_SUCCESS on success. - @retval EFI_NOT_FOUND nothing to do. -**/ -STATIC -EFI_STATUS -OcExpandAttributesByMap ( - IN OUT EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry, - IN UINTN MaxDescriptors, - IN UINTN MemoryMapDescriptors, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - EFI_STATUS Status; - UINTN MapIndex; - UINTN MatIndex; - EFI_PHYSICAL_ADDRESS LastMapAddress; - EFI_PHYSICAL_ADDRESS LastMatAddress; - EFI_PHYSICAL_ADDRESS NewNextGluedAddress; - EFI_PHYSICAL_ADDRESS NextGluedAddress; - BOOLEAN LastMat; - - MatIndex = 0; - Status = EFI_NOT_FOUND; - - for (MapIndex = 0; MapIndex < MemoryMapDescriptors; ++MapIndex) { - if (MemoryMap->Type == EfiRuntimeServicesCode - || MemoryMap->Type == EfiRuntimeServicesData) { - - LastMapAddress = LAST_DESCRIPTOR_ADDR (MemoryMap); - NextGluedAddress = MemoryMap->PhysicalStart; - LastMat = FALSE; - - while (MatIndex < MemoryAttributesTable->NumberOfEntries && !LastMat) { - // - // Process MAT with RT code or RT data type, which is the last one or resides at MAP entry or after. - // - LastMatAddress = LAST_DESCRIPTOR_ADDR (MemoryAttributesEntry); - LastMat = MatIndex + 1 == MemoryAttributesTable->NumberOfEntries; - if ((MemoryMap->Type == EfiRuntimeServicesCode || MemoryMap->Type == EfiRuntimeServicesData) - && (LastMatAddress >= MemoryMap->PhysicalStart || LastMat)) { - // - // MAT is a suffix of MAP (MAT ends at MAP end). - // - if (NextGluedAddress == MemoryAttributesEntry->PhysicalStart - && LastMatAddress == LastMapAddress) { - // - // Completed iterating over this MAP entry. - // - break; - } - - // - // MAT is a prefix or an infix of MAP: - // 1. MAT entry at the beginning of MAP entry. - // 2. MAT entry continuing previous MAT entry within MAP entry. - // If this MAT is last, we have a hole in the end. - // - if (NextGluedAddress == MemoryAttributesEntry->PhysicalStart && !LastMat) { - // - // MAT is required to be smaller or equal than MAP by UEFI spec. - // - ASSERT (MemoryAttributesEntry->NumberOfPages <= MemoryMap->NumberOfPages); - NextGluedAddress = LastMatAddress + 1; - } else { - // - // Have a hole between neighbouring MAT entries, 3 variants: - // - MAT is within MAP (but starts later). - // - MAT starts after MAP. - // - No MAT fully covers MAP end (this is the last MAT entry). - // Need to insert a new MAT entry to cover the hole. - // - if (MemoryAttributesTable->NumberOfEntries >= MaxDescriptors) { - return EFI_OUT_OF_RESOURCES; - } - - if (!LastMat) { - // - // Append to the middle. - // Choose the next processed address. This is the closest boundary for us: - // - First MAT address, when MAT is within MAP. - // - Last MAP address, when MAT starts after MAP. - // - NewNextGluedAddress = MIN (MemoryAttributesEntry->PhysicalStart, LastMapAddress + 1); - // - // Copy existing attributes to the right. - // - ASSERT (MemoryAttributesEntry->PhysicalStart > NextGluedAddress); - CopyMem ( - NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, MemoryAttributesTable->DescriptorSize), - MemoryAttributesEntry, - (MemoryAttributesTable->NumberOfEntries - MatIndex) * MemoryAttributesTable->DescriptorSize - ); - } else { - // - // Append to the end. - // Next processed address is the end of MAP. - // There are no MATs left to copy. - // - NewNextGluedAddress = LastMapAddress + 1; - // - // If current MAT is a prefix or an infix of MAP, take it into account. - // - if (MemoryAttributesEntry->PhysicalStart == NextGluedAddress) { - NextGluedAddress = LastMatAddress + 1; - } else { - ASSERT (MemoryAttributesEntry->PhysicalStart < NextGluedAddress); - } - // - // Update current entry the new the last entry we are about to write. - // - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, MemoryAttributesTable->DescriptorSize); - ++MatIndex; - } - // - // Write the new attribute. - // - MemoryAttributesEntry->Type = OcRealMemoryType (MemoryMap); - MemoryAttributesEntry->PhysicalStart = NextGluedAddress; - MemoryAttributesEntry->VirtualStart = 0; - MemoryAttributesEntry->NumberOfPages = EFI_SIZE_TO_PAGES (NewNextGluedAddress - NextGluedAddress); - MemoryAttributesEntry->Attribute = EFI_MEMORY_RUNTIME; - if (MemoryAttributesEntry->Type == EfiRuntimeServicesCode) { - MemoryAttributesEntry->Attribute |= EFI_MEMORY_RO; - } else { - MemoryAttributesEntry->Attribute |= EFI_MEMORY_XP; - } - // - // Update the next processed address. - // Increase the amount of MAT entries in the table. - // Report success. - // - NextGluedAddress = NewNextGluedAddress; - ++MemoryAttributesTable->NumberOfEntries; - Status = EFI_SUCCESS; - // - // Done processing MATs. - // - if (NextGluedAddress == LastMapAddress + 1) { - break; - } - } - } - // - // Process next MAT. - // Do not increment if it is the last MAT, as we need to fill holes in the end. - // - if (!LastMat) { - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - ++MatIndex; - } - } - } - - MemoryMap = NEXT_MEMORY_DESCRIPTOR ( - MemoryMap, - DescriptorSize - ); - } - - return Status; -} - -EFI_MEMORY_ATTRIBUTES_TABLE * -OcGetMemoryAttributes ( - OUT EFI_MEMORY_DESCRIPTOR **MemoryAttributesEntry OPTIONAL - ) -{ - EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - UINTN Index; - - for (Index = 0; Index < gST->NumberOfTableEntries; ++Index) { - if (CompareGuid (&gST->ConfigurationTable[Index].VendorGuid, &gEfiMemoryAttributesTableGuid)) { - MemoryAttributesTable = gST->ConfigurationTable[Index].VendorTable; - if (MemoryAttributesEntry != NULL) { - *MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *) (MemoryAttributesTable + 1); - } - return MemoryAttributesTable; - } - } - - return NULL; -} - -EFI_STATUS -OcRebuildAttributes ( - IN EFI_PHYSICAL_ADDRESS Address, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - UINTN MaxDescriptors; - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN DescriptorSize; - UINTN MapKey; - UINT32 DescriptorVersion; - - MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry); - if (MemoryAttributesTable == NULL) { - return EFI_UNSUPPORTED; - } - - // - // Some boards create entry duplicates and lose all non-PE entries - // after loading runtime drivers after EndOfDxe. - // REF: https://github.com/acidanthera/bugtracker/issues/491#issuecomment-609014334 - // - MaxDescriptors = MemoryAttributesTable->NumberOfEntries; - Status = OcDeduplicateDescriptors ( - &MemoryAttributesTable->NumberOfEntries, - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - if (!EFI_ERROR(Status)) { - // - // Statically allocate memory for the memory map to avoid allocations. - // - STATIC UINT8 mMemoryMap[OC_DEFAULT_MEMORY_MAP_SIZE]; - - // - // Assume effected and add missing entries. - // - if (GetMemoryMap == NULL) { - GetMemoryMap = gBS->GetMemoryMap; - } - - MemoryMapSize = sizeof (mMemoryMap); - MemoryMap = (EFI_MEMORY_DESCRIPTOR *) mMemoryMap; - - Status = GetMemoryMap ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - - if (!EFI_ERROR(Status)) { - OcSortMemoryMap ( - MemoryMapSize, - MemoryMap, - DescriptorSize - ); - - OcExpandAttributesByMap ( - MemoryAttributesTable, - MemoryAttributesEntry, - MaxDescriptors, - MemoryMapSize / DescriptorSize, - MemoryMap, - DescriptorSize - ); - } else { - // - // TODO: Scream in fear here? We cannot log, but for a fatal error it is "fine". - // - } - } - - // - // Some firmwares do not update MAT after loading runtime drivers after EndOfDxe. - // Since the memory used to allocate runtime driver resides in BINs, MAT has whatever - // permissions designated for unused memory. Mark unused memory containing our driver - // as executable here. - // REF: https://github.com/acidanthera/bugtracker/issues/491#issuecomment-606835337 - // - if (Address != 0) { - Status = OcUpdateDescriptors ( - MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize, - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize, - Address, - EfiRuntimeServicesCode, - EFI_MEMORY_RO, - EFI_MEMORY_XP - ); - } - - return Status; -} - -UINTN -OcCountSplitDescriptors ( - VOID - ) -{ - UINTN Index; - UINTN DescriptorCount; - CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - - MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry); - if (MemoryAttributesTable == NULL) { - return 0; - } - - DescriptorCount = 0; - for (Index = 0; Index < MemoryAttributesTable->NumberOfEntries; ++Index) { - if (MemoryAttributesEntry->Type == EfiRuntimeServicesCode - || MemoryAttributesEntry->Type == EfiRuntimeServicesData) { - ++DescriptorCount; - } - - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - } - - return DescriptorCount; -} - -EFI_STATUS -OcSplitMemoryMapByAttributes ( - IN UINTN MaxMemoryMapSize, - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - EFI_STATUS Status; - CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *LastAttributeEntry; - UINTN LastAttributeIndex; - UINTN Index; - UINTN Index2; - UINTN CurrentEntryCount; - UINTN TotalEntryCount; - UINTN AttributeCount; - BOOLEAN CanSplit; - BOOLEAN InDescAttrs; - - ASSERT (MaxMemoryMapSize >= *MemoryMapSize); - - MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry); - if (MemoryAttributesTable == NULL) { - return EFI_UNSUPPORTED; - } - - LastAttributeEntry = MemoryAttributesEntry; - LastAttributeIndex = 0; - MemoryMapEntry = MemoryMap; - CurrentEntryCount = *MemoryMapSize / DescriptorSize; - TotalEntryCount = MaxMemoryMapSize / DescriptorSize; - AttributeCount = MemoryAttributesTable->NumberOfEntries; - - // - // We assume that the memory map and attribute table are sorted. - // - Index = 0; - while (Index < CurrentEntryCount) { - // - // Split entry by as many attributes as possible. - // - CanSplit = TRUE; - while ((MemoryMapEntry->Type == EfiRuntimeServicesCode - || MemoryMapEntry->Type == EfiRuntimeServicesData) && CanSplit) { - // - // Find corresponding memory attribute. - // - InDescAttrs = FALSE; - MemoryAttributesEntry = LastAttributeEntry; - for (Index2 = LastAttributeIndex; Index2 < AttributeCount; ++Index2) { - if (MemoryAttributesEntry->Type == EfiRuntimeServicesCode - || MemoryAttributesEntry->Type == EfiRuntimeServicesData) { - // - // UEFI spec says attribute entries are fully within memory map entries. - // Find first one of a different type. - // - if (AREA_WITHIN_DESCRIPTOR ( - MemoryMapEntry, - MemoryAttributesEntry->PhysicalStart, - EFI_PAGES_TO_SIZE (MemoryAttributesEntry->NumberOfPages))) { - // - // We are within descriptor attribute sequence. - // - InDescAttrs = TRUE; - // - // No need to process the attribute of the same type. - // - if (OcRealMemoryType (MemoryAttributesEntry) != MemoryMapEntry->Type) { - // - // Start with the next attribute on the second iteration. - // - LastAttributeEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - LastAttributeIndex = Index2 + 1; - break; - } - } else if (InDescAttrs) { - // - // Reached the end of descriptor attribute sequence, abort. - // - InDescAttrs = FALSE; - break; - } - } - - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - } - - if (Index2 < AttributeCount && InDescAttrs) { - // - // Split current memory map entry. - // - Status = OcSplitMemoryEntryByAttribute ( - &MemoryMapEntry, - &Index, - &CurrentEntryCount, - TotalEntryCount, - MemoryAttributesEntry, - DescriptorSize - ); - if (EFI_ERROR(Status)) { - *MemoryMapSize = CurrentEntryCount * DescriptorSize; - return Status; - } - continue; - } else { - // - // Did not find a suitable attribute or processed all the attributes. - // - CanSplit = FALSE; - } - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryMapEntry, - DescriptorSize - ); - ++Index; - } - - *MemoryMapSize = CurrentEntryCount * DescriptorSize; - return EFI_SUCCESS; -} diff --git a/Library/OcMemoryLib/MemoryDebug.c b/Library/OcMemoryLib/MemoryDebug.c deleted file mode 100644 index 374f294dd..000000000 --- a/Library/OcMemoryLib/MemoryDebug.c +++ /dev/null @@ -1,166 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -STATIC CONST CHAR8 *mEfiMemoryTypeDesc[EfiMaxMemoryType] = { - "Reserved ", - "LDR Code ", - "LDR Data ", - "BS Code ", - "BS Data ", - "RT Code ", - "RT Data ", - "Available", - "Unusable ", - "ACPI RECL", - "ACPI NVS ", - "MemMapIO ", - "MemPortIO", - "PAL Code ", - "Persist " -}; - -STATIC -VOID -OcPrintMemoryDescritptor ( - IN EFI_MEMORY_DESCRIPTOR *Desc - ) -{ - CONST CHAR8 *Type; - CONST CHAR8 *SizeType; - UINT64 SizeValue; - - if (Desc->Type < ARRAY_SIZE (mEfiMemoryTypeDesc)) { - Type = mEfiMemoryTypeDesc[Desc->Type]; - } else { - Type = "Invalid "; - } - - SizeValue = EFI_PAGES_TO_SIZE (Desc->NumberOfPages); - if (SizeValue >= BASE_1MB) { - SizeValue /= BASE_1MB; - SizeType = "MB"; - } else { - SizeValue /= BASE_1KB; - SizeType = "KB"; - } - - DEBUG (( - DEBUG_INFO, - "OCMM: %a [%a|%a|%a|%a|%a|%a|%a|%a|%a|%a|%a|%a|%a|%a] 0x%016LX-0x%016LX -> 0x%016X (%Lu %a)\n", - Type, - (Desc->Attribute & EFI_MEMORY_RUNTIME) != 0 ? "RUN" : " ", - (Desc->Attribute & EFI_MEMORY_CPU_CRYPTO) != 0 ? "CRY" : " ", - (Desc->Attribute & EFI_MEMORY_SP) != 0 ? "SP" : " ", - (Desc->Attribute & EFI_MEMORY_RO) != 0 ? "RO" : " ", - (Desc->Attribute & EFI_MEMORY_MORE_RELIABLE) != 0 ? "MR" : " ", - (Desc->Attribute & EFI_MEMORY_NV) != 0 ? "NV" : " ", - (Desc->Attribute & EFI_MEMORY_XP) != 0 ? "XP" : " ", - (Desc->Attribute & EFI_MEMORY_RP) != 0 ? "RP" : " ", - (Desc->Attribute & EFI_MEMORY_WP) != 0 ? "WP" : " ", - (Desc->Attribute & EFI_MEMORY_UCE) != 0 ? "UCE" : " ", - (Desc->Attribute & EFI_MEMORY_WB) != 0 ? "WB" : " ", - (Desc->Attribute & EFI_MEMORY_WT) != 0 ? "WT" : " ", - (Desc->Attribute & EFI_MEMORY_WC) != 0 ? "WC" : " ", - (Desc->Attribute & EFI_MEMORY_UC) != 0 ? "UC" : " ", - Desc->PhysicalStart, - Desc->PhysicalStart + (EFI_PAGES_TO_SIZE (Desc->NumberOfPages) - 1), - Desc->VirtualStart, - SizeValue, - SizeType - )); -} - -VOID -OcPrintMemoryAttributesTable ( - VOID - ) -{ - UINTN Index; - UINTN RealSize; - CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - - MemoryAttributesTable = OcGetMemoryAttributes (NULL); - if (MemoryAttributesTable == NULL) { - DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable is not present!\n")); - return; - } - - // - // Printing may reallocate, so we create a copy of the memory attributes. - // - STATIC UINT8 mMemoryAttributesTable[OC_DEFAULT_MEMORY_MAP_SIZE]; - RealSize = (UINTN) (sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) - + MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize); - - if (RealSize > sizeof(mMemoryAttributesTable)) { - DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable has too large size %u!\n", (UINT32) RealSize)); - return; - } - - CopyMem (mMemoryAttributesTable, MemoryAttributesTable, RealSize); - - MemoryAttributesTable = (EFI_MEMORY_ATTRIBUTES_TABLE *) mMemoryAttributesTable; - MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *) (MemoryAttributesTable + 1); - - DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable:\n")); - DEBUG ((DEBUG_INFO, "OCMM: Version - 0x%08x\n", MemoryAttributesTable->Version)); - DEBUG ((DEBUG_INFO, "OCMM: NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); - DEBUG ((DEBUG_INFO, "OCMM: DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); - - for (Index = 0; Index < MemoryAttributesTable->NumberOfEntries; ++Index) { - OcPrintMemoryDescritptor (MemoryAttributesEntry); - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - } -} - -VOID -OcPrintMemoryMap ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - UINTN Index; - UINT32 NumberOfEntries; - - NumberOfEntries = (UINT32) (MemoryMapSize / DescriptorSize); - - DEBUG ((DEBUG_INFO, "OCMM: MemoryMap:\n")); - DEBUG ((DEBUG_INFO, "OCMM: Size - 0x%08x\n", MemoryMapSize)); - DEBUG ((DEBUG_INFO, "OCMM: NumberOfEntries - 0x%08x\n", NumberOfEntries)); - DEBUG ((DEBUG_INFO, "OCMM: DescriptorSize - 0x%08x\n", DescriptorSize)); - - for (Index = 0; Index < NumberOfEntries; ++Index) { - OcPrintMemoryDescritptor (MemoryMap); - MemoryMap = NEXT_MEMORY_DESCRIPTOR ( - MemoryMap, - DescriptorSize - ); - } -} diff --git a/Library/OcMemoryLib/MemoryMap.c b/Library/OcMemoryLib/MemoryMap.c deleted file mode 100644 index be13261d1..000000000 --- a/Library/OcMemoryLib/MemoryMap.c +++ /dev/null @@ -1,444 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -EFI_MEMORY_DESCRIPTOR * -OcGetCurrentMemoryMap ( - OUT UINTN *MemoryMapSize, - IN UINTN *DescriptorSize, - OUT UINTN *MapKey OPTIONAL, - OUT UINT32 *DescriptorVersion OPTIONAL, - OUT UINTN *OriginalMemoryMapSize OPTIONAL, - IN BOOLEAN IncludeSplitSpace - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMap = NULL; - EFI_STATUS Status; - UINTN MapKeyValue = 0; - UINTN OriginalSize; - UINTN ExtraSize; - UINT32 DescriptorVersionValue = 0; - BOOLEAN Result; - - *MemoryMapSize = 0; - Status = gBS->GetMemoryMap ( - MemoryMapSize, - NULL, - &MapKeyValue, - DescriptorSize, - &DescriptorVersionValue - ); - - if (Status != EFI_BUFFER_TOO_SMALL) { - return NULL; - } - - if (IncludeSplitSpace) { - ExtraSize = OcCountSplitDescriptors() * *DescriptorSize; - } else { - ExtraSize = 0; - } - - // - // Apple uses 1024 as constant, however it will grow by at least - // DescriptorSize. - // - Result = OcOverflowAddUN ( - *MemoryMapSize, - MAX(*DescriptorSize + ExtraSize, 1024 + ExtraSize), - MemoryMapSize - ); - - if (Result) { - return NULL; - } - - OriginalSize = *MemoryMapSize; - MemoryMap = AllocatePool (OriginalSize); - if (MemoryMap == NULL) { - return NULL; - } - - Status = gBS->GetMemoryMap ( - MemoryMapSize, - MemoryMap, - &MapKeyValue, - DescriptorSize, - &DescriptorVersionValue - ); - - if (EFI_ERROR(Status)) { - FreePool (MemoryMap); - return NULL; - } - - if (MapKey != NULL) { - *MapKey = MapKeyValue; - } - - if (DescriptorVersion != NULL) { - *DescriptorVersion = DescriptorVersionValue; - } - - if (OriginalMemoryMapSize != NULL) { - *OriginalMemoryMapSize = OriginalSize; - } - - return MemoryMap; -} - -EFI_STATUS -OcGetCurrentMemoryMapAlloc ( - OUT UINTN *MemoryMapSize, - OUT EFI_MEMORY_DESCRIPTOR **MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL, - IN OUT EFI_PHYSICAL_ADDRESS *TopMemory OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS MemoryMapAlloc; - - *MemoryMapSize = 0; - *MemoryMap = NULL; - - if (GetMemoryMap == NULL) { - GetMemoryMap = gBS->GetMemoryMap; - } - - Status = GetMemoryMap ( - MemoryMapSize, - *MemoryMap, - MapKey, - DescriptorSize, - DescriptorVersion - ); - - if (Status != EFI_BUFFER_TOO_SMALL) { - DEBUG ((DEBUG_INFO, "OCMM: Insane GetMemoryMap %r\n", Status)); - return Status; - } - - do { - // - // This is done because extra allocations may increase memory map size. - // - *MemoryMapSize += 512; - - // - // Requested to allocate from top via pages. - // This may be needed, because the pool memory may collide with the kernel. - // - if (TopMemory != NULL) { - MemoryMapAlloc = *TopMemory; - *TopMemory = EFI_SIZE_TO_PAGES (*MemoryMapSize); - - Status = OcAllocatePagesFromTop ( - EfiBootServicesData, - (UINTN) *TopMemory, - &MemoryMapAlloc, - GetMemoryMap, - NULL - ); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCMM: Temp memory map allocation from top failure - %r\n", Status)); - *MemoryMap = NULL; - return Status; - } - - *MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN) MemoryMapAlloc; - } else { - *MemoryMap = AllocatePool (*MemoryMapSize); - if (*MemoryMap == NULL) { - DEBUG ((DEBUG_INFO, "OCMM: Temp memory map direct allocation failure\n")); - return EFI_OUT_OF_RESOURCES; - } - } - - Status = GetMemoryMap ( - MemoryMapSize, - *MemoryMap, - MapKey, - DescriptorSize, - DescriptorVersion - ); - - if (EFI_ERROR(Status)) { - if (TopMemory != NULL) { - gBS->FreePages ( - (EFI_PHYSICAL_ADDRESS) ((UINTN) *MemoryMap), - (UINTN) *TopMemory - ); - } else { - FreePool (*MemoryMap); - } - - *MemoryMap = NULL; - } - } while (Status == EFI_BUFFER_TOO_SMALL); - - if (Status != EFI_SUCCESS) { - DEBUG ((DEBUG_INFO, "OCMM: Failed to obtain memory map - %r\n", Status)); - } - - return Status; -} - -VOID -OcSortMemoryMap ( - IN UINTN MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - 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); - } -} - -EFI_STATUS -OcShrinkMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - EFI_STATUS Status; - UINTN SizeFromDescToEnd; - UINT64 Bytes; - EFI_MEMORY_DESCRIPTOR *PrevDesc; - EFI_MEMORY_DESCRIPTOR *Desc; - BOOLEAN CanBeJoinedFree; - BOOLEAN CanBeJoinedRt; - BOOLEAN HasEntriesToRemove; - - Status = EFI_NOT_FOUND; - - if (*MemoryMapSize <= DescriptorSize) { - return Status; - } - - PrevDesc = MemoryMap; - Desc = NEXT_MEMORY_DESCRIPTOR (PrevDesc, DescriptorSize); - SizeFromDescToEnd = *MemoryMapSize - DescriptorSize; - *MemoryMapSize = DescriptorSize; - HasEntriesToRemove = FALSE; - - while (SizeFromDescToEnd > 0) { - Bytes = EFI_PAGES_TO_SIZE (PrevDesc->NumberOfPages); - CanBeJoinedFree = FALSE; - CanBeJoinedRt = FALSE; - if (Desc->Attribute == PrevDesc->Attribute - && PrevDesc->PhysicalStart + Bytes == Desc->PhysicalStart) { - // - // It *should* be safe to join this with conventional memory, because the firmware should not use - // GetMemoryMap for allocation, and for the kernel it does not matter, since it joins them. - // - CanBeJoinedFree = ( - Desc->Type == EfiBootServicesCode - || Desc->Type == EfiBootServicesData - || Desc->Type == EfiConventionalMemory - || Desc->Type == EfiLoaderCode - || Desc->Type == EfiLoaderData - ) && ( - PrevDesc->Type == EfiBootServicesCode - || PrevDesc->Type == EfiBootServicesData - || PrevDesc->Type == EfiConventionalMemory - || PrevDesc->Type == EfiLoaderCode - || PrevDesc->Type == EfiLoaderData - ); - - CanBeJoinedRt = ( - Desc->Type == EfiRuntimeServicesCode - && PrevDesc->Type == EfiRuntimeServicesCode - ) || ( - Desc->Type == EfiRuntimeServicesData - && PrevDesc->Type == EfiRuntimeServicesData - ); - } - - if (CanBeJoinedFree) { - // - // Two entries are the same/similar - join them - // - PrevDesc->Type = EfiConventionalMemory; - PrevDesc->NumberOfPages += Desc->NumberOfPages; - HasEntriesToRemove = TRUE; - Status = EFI_SUCCESS; - } else if (CanBeJoinedRt) { - PrevDesc->NumberOfPages += Desc->NumberOfPages; - HasEntriesToRemove = TRUE; - Status = EFI_SUCCESS; - } else { - // - // Cannot be joined - we need to move to next - // - *MemoryMapSize += DescriptorSize; - PrevDesc = NEXT_MEMORY_DESCRIPTOR (PrevDesc, DescriptorSize); - if (HasEntriesToRemove) { - // - // Have entries between PrevDesc and Desc which are joined to PrevDesc, - // we need to copy [Desc, end of list] to PrevDesc + 1 - // - CopyMem (PrevDesc, Desc, SizeFromDescToEnd); - Desc = PrevDesc; - HasEntriesToRemove = FALSE; - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - SizeFromDescToEnd -= DescriptorSize; - } - - // - // Handle last entries if they were merged. - // - if (HasEntriesToRemove) { - *MemoryMapSize += DescriptorSize; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -OcDeduplicateDescriptors ( - IN OUT UINT32 *EntryCount, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - EFI_STATUS Status; - UINTN EntriesToGo; - EFI_MEMORY_DESCRIPTOR *PrevDesc; - EFI_MEMORY_DESCRIPTOR *Desc; - BOOLEAN IsDuplicate; - BOOLEAN HasEntriesToRemove; - - Status = EFI_NOT_FOUND; - - if (*EntryCount <= 1) { - return Status; - } - - PrevDesc = MemoryMap; - Desc = NEXT_MEMORY_DESCRIPTOR (PrevDesc, DescriptorSize); - EntriesToGo = *EntryCount - 1; - *EntryCount = 1; - HasEntriesToRemove = FALSE; - - while (EntriesToGo > 0) { - IsDuplicate = Desc->PhysicalStart == PrevDesc->PhysicalStart - && Desc->NumberOfPages == PrevDesc->NumberOfPages; - - if (IsDuplicate) { - // - // Two entries are duplicate, remove them. - // - Status = EFI_SUCCESS; - HasEntriesToRemove = TRUE; - } else { - // - // Not duplicates - we need to move to next - // - ++(*EntryCount); - PrevDesc = NEXT_MEMORY_DESCRIPTOR (PrevDesc, DescriptorSize); - if (HasEntriesToRemove) { - // - // Have same entries between PrevDesc and Desc which are replaced by PrevDesc, - // we need to copy [Desc, end of list] to PrevDesc + 1. - // - CopyMem (PrevDesc, Desc, EntriesToGo * DescriptorSize); - Desc = PrevDesc; - HasEntriesToRemove = FALSE; - } - } - - Desc = NEXT_MEMORY_DESCRIPTOR (Desc, DescriptorSize); - --EntriesToGo; - } - - // - // Handle last entries if they were deduplicated. - // - if (HasEntriesToRemove) { - ++(*EntryCount); - } - - return Status; -} - -EFI_STATUS -OcUpdateDescriptors ( - IN UINTN MemoryMapSize, - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize, - IN EFI_PHYSICAL_ADDRESS Address, - IN EFI_MEMORY_TYPE Type, - IN UINT64 SetAttributes, - IN UINT64 DropAttributes - ) -{ - UINTN Index; - UINTN EntryCount; - - EntryCount = MemoryMapSize / DescriptorSize; - - for (Index = 0; Index < EntryCount; ++Index) { - if (AREA_WITHIN_DESCRIPTOR (MemoryMap, Address, 1)) { - MemoryMap->Type = Type; - MemoryMap->Attribute |= SetAttributes; - MemoryMap->Attribute &= ~DropAttributes; - return EFI_SUCCESS; - } - - MemoryMap = NEXT_MEMORY_DESCRIPTOR ( - MemoryMap, - DescriptorSize - ); - } - - return EFI_NOT_FOUND; -} diff --git a/Library/OcMemoryLib/OcMemoryLib.inf b/Library/OcMemoryLib/OcMemoryLib.inf deleted file mode 100755 index 22ec6c7ba..000000000 --- a/Library/OcMemoryLib/OcMemoryLib.inf +++ /dev/null @@ -1,57 +0,0 @@ -## @file -# -# Component description file for OcMemoryLib. -# -# Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcMemoryLib - FILE_GUID = EADEF108-EFA4-4425-A2C3-4682118B888B - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcMemoryLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# VALID_ARCHITECTURES = IA32 X64 - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - -[Guids] - gEfiMemoryAttributesTableGuid - -[Protocols] - gEfiLegacyRegionProtocolGuid - -[LibraryClasses] - BaseLib - UefiLib - OcGuardLib - OcStringLib - -[Sources] - MemoryAlloc.c - MemoryAttributes.c - MemoryDebug.c - MemoryMap.c - LegacyRegionLock.c - LegacyRegionUnLock.c - UmmMalloc.c - VirtualMemory.c - ../../Include/Library/OcMemoryLib.h diff --git a/Library/OcMemoryLib/UmmMalloc.c b/Library/OcMemoryLib/UmmMalloc.c deleted file mode 100755 index 1aad29e59..000000000 --- a/Library/OcMemoryLib/UmmMalloc.c +++ /dev/null @@ -1,493 +0,0 @@ -/* ---------------------------------------------------------------------------- - * umm_malloc.c - a memory allocator for embedded systems (microcontrollers) - * - * The MIT License (MIT) - * - * Copyright (c) 2015 Ralph Hempel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * ---------------------------------------------------------------------------- - * - * R.Hempel 2007-09-22 - Original - * R.Hempel 2008-12-11 - Added MIT License biolerplate - * - realloc() now looks to see if previous block is free - * - made common operations functions - * R.Hempel 2009-03-02 - Added macros to disable tasking - * - Added function to dump heap and check for valid free - * pointer - * R.Hempel 2009-03-09 - Changed name to umm_malloc to avoid conflicts with - * the mm_malloc() library functions - * - Added some test code to assimilate a free block - * with the very block if possible. Complicated and - * not worth the grief. - * D.Frank 2014-04-02 - Fixed heap configuration when UMM_TEST_MAIN is NOT set, - * added user-dependent configuration file umm_malloc_cfg.h - * R.Hempel 2016-12-04 - Add support for Unity test framework - * - Reorganize source files to avoid redundant content - * - Move integrity and poison checking to separate file - * R.Hempel 2017-12-29 - Fix bug in realloc when requesting a new block that - * results in OOM error - see Issue 11 - * vit9696 2018-02-07 - Changed types, masks and limits to support 32-bit pools - * - Removed realloc and calloc I do not need - * - Added pointer range check in free to detect memory that - * was not allocated by us - * - Made pool initialization external to avoid memset deps - * and to support initialization state - * - Switched to UEFI types, pragmas, renamed external API - * ---------------------------------------------------------------------------- - */ - -#include - -STATIC UINT8 *default_umm_heap; -STATIC UINT32 default_umm_heap_size; - -#define UMM_MALLOC_CFG_HEAP_SIZE default_umm_heap_size -#define UMM_MALLOC_CFG_HEAP_ADDR default_umm_heap - -#define UMM_BEST_FIT - -#define DBGLOG_DEBUG(format, ...) do { } while (0) -#define DBGLOG_TRACE(froamt, ...) do { } while (0) - -#define UMM_CRITICAL_ENTRY() -#define UMM_CRITICAL_EXIT() - -/* ------------------------------------------------------------------------- */ - -#pragma pack(1) - -typedef struct umm_ptr_t { - UINT32 next; - UINT32 prev; -} umm_ptr; - -typedef struct umm_block_t { - union { - umm_ptr used; - } header; - union { - umm_ptr free; - UINT8 data[4]; - } body; -} umm_block; - -#pragma pack() - -#define UMM_FREELIST_MASK (0x80000000) -#define UMM_BLOCKNO_MASK (0x7FFFFFFF) - -/* ------------------------------------------------------------------------- */ - -umm_block *umm_heap = NULL; -UINT32 umm_numblocks = 0; - -#define UMM_NUMBLOCKS (umm_numblocks) - -/* ------------------------------------------------------------------------ */ - -#define UMM_BLOCK(b) (umm_heap[b]) - -#define UMM_NBLOCK(b) (UMM_BLOCK(b).header.used.next) -#define UMM_PBLOCK(b) (UMM_BLOCK(b).header.used.prev) -#define UMM_NFREE(b) (UMM_BLOCK(b).body.free.next) -#define UMM_PFREE(b) (UMM_BLOCK(b).body.free.prev) -#define UMM_DATA(b) (UMM_BLOCK(b).body.data) - -/* ------------------------------------------------------------------------ */ - -STATIC UINT32 umm_blocks( UINT32 size ) { - - /* - * The calculation of the block size is not too difficult, but there are - * a few little things that we need to be mindful of. - * - * When a block removed from the free list, the space used by the free - * pointers is available for data. That's what the first calculation - * of size is doing. - */ - - if( size <= (sizeof(((umm_block *)0)->body)) ) - return( 1 ); - - /* - * If it's for more than that, then we need to figure out the number of - * additional whole blocks the size of an umm_block are required. - */ - - size -= ( 1 + (sizeof(((umm_block *)0)->body)) ); - - return( 2 + size/(sizeof(umm_block)) ); -} - -/* ------------------------------------------------------------------------ */ -/* - * Split the block `c` into two blocks: `c` and `c + blocks`. - * - * - `new_freemask` should be `0` if `c + blocks` used, or `UMM_FREELIST_MASK` - * otherwise. - * - * Note that free pointers are NOT modified by this function. - */ -STATIC VOID umm_split_block( UINT32 c, - UINT32 blocks, - UINT32 new_freemask ) { - - UMM_NBLOCK(c+blocks) = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) | new_freemask; - UMM_PBLOCK(c+blocks) = c; - - UMM_PBLOCK(UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) = (c+blocks); - UMM_NBLOCK(c) = (c+blocks); -} - -/* ------------------------------------------------------------------------ */ - -STATIC VOID umm_disconnect_from_free_list( UINT32 c ) { - /* Disconnect this block from the FREE list */ - - UMM_NFREE(UMM_PFREE(c)) = UMM_NFREE(c); - UMM_PFREE(UMM_NFREE(c)) = UMM_PFREE(c); - - /* And clear the free block indicator */ - - UMM_NBLOCK(c) &= (~UMM_FREELIST_MASK); -} - -/* ------------------------------------------------------------------------ - * The umm_assimilate_up() function assumes that UMM_NBLOCK(c) does NOT - * have the UMM_FREELIST_MASK bit set! - */ - -STATIC VOID umm_assimilate_up( UINT32 c ) { - - if( UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK ) { - /* - * The next block is a free block, so assimilate up and remove it from - * the free list - */ - - DBGLOG_DEBUG( "Assimilate up to next block, which is FREE\n" ); - - /* Disconnect the next block from the FREE list */ - - umm_disconnect_from_free_list( UMM_NBLOCK(c) ); - - /* Assimilate the next block with this one */ - - UMM_PBLOCK(UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) = c; - UMM_NBLOCK(c) = UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK; - } -} - -/* ------------------------------------------------------------------------ - * The umm_assimilate_down() function assumes that UMM_NBLOCK(c) does NOT - * have the UMM_FREELIST_MASK bit set! - */ - -STATIC UINT32 umm_assimilate_down( UINT32 c, UINT32 freemask ) { - - UMM_NBLOCK(UMM_PBLOCK(c)) = UMM_NBLOCK(c) | freemask; - UMM_PBLOCK(UMM_NBLOCK(c)) = UMM_PBLOCK(c); - - return( UMM_PBLOCK(c) ); -} - -/* ------------------------------------------------------------------------ */ - -VOID umm_init( VOID ) { - /* init heap pointer and size, and memset it to 0 */ - umm_heap = (umm_block *)UMM_MALLOC_CFG_HEAP_ADDR; - umm_numblocks = (UMM_MALLOC_CFG_HEAP_SIZE / sizeof(umm_block)); - - /* - * This is done at allocation step! - * memset(umm_heap, 0x00, UMM_MALLOC_CFG_HEAP_SIZE); - */ - - /* setup initial blank heap structure */ - { - /* index of the 0th `umm_block` */ - CONST UINT32 block_0th = 0; - /* index of the 1st `umm_block` */ - CONST UINT32 block_1th = 1; - /* index of the latest `umm_block` */ - CONST UINT32 block_last = UMM_NUMBLOCKS - 1; - - /* setup the 0th `umm_block`, which just points to the 1st */ - UMM_NBLOCK(block_0th) = block_1th; - UMM_NFREE(block_0th) = block_1th; - UMM_PFREE(block_0th) = block_1th; - - /* - * Now, we need to set the whole heap space as a huge free block. We should - * not touch the 0th `umm_block`, since it's special: the 0th `umm_block` - * is the head of the free block list. It's a part of the heap invariant. - * - * See the detailed explanation at the beginning of the file. - */ - - /* - * 1th `umm_block` has pointers: - * - * - next `umm_block`: the latest one - * - prev `umm_block`: the 0th - * - * Plus, it's a free `umm_block`, so we need to apply `UMM_FREELIST_MASK` - * - * And it's the last free block, so the next free block is 0. - */ - UMM_NBLOCK(block_1th) = block_last | UMM_FREELIST_MASK; - UMM_NFREE(block_1th) = 0; - UMM_PBLOCK(block_1th) = block_0th; - UMM_PFREE(block_1th) = block_0th; - - /* - * latest `umm_block` has pointers: - * - * - next `umm_block`: 0 (meaning, there are no more `umm_blocks`) - * - prev `umm_block`: the 1st - * - * It's not a free block, so we don't touch NFREE / PFREE at all. - */ - UMM_NBLOCK(block_last) = 0; - UMM_PBLOCK(block_last) = block_1th; - } -} - -/* ------------------------------------------------------------------------ */ - -BOOLEAN UmmInitialized ( VOID ) { - return default_umm_heap != NULL; -} - -/* ------------------------------------------------------------------------ */ - -VOID UmmSetHeap( VOID *heap, UINT32 size ) { - default_umm_heap = (UINT8 *)heap; - default_umm_heap_size = size; - umm_init(); -} - -/* ------------------------------------------------------------------------ */ - -BOOLEAN UmmFree( VOID *ptr ) { - - UINT32 c; - UINT8 *cptr = (UINT8 *)ptr; - - /* If we are not initialised, reuturn false! */ - if ( !UmmInitialized() ) - return FALSE; - - /* If we're being asked to free a NULL pointer, well that's just silly! */ - - if( (VOID *)0 == ptr ) { - DBGLOG_DEBUG( "free a null pointer -> do nothing\n" ); - - return FALSE; - } - - /* If we're being asked to free an unrelated pointer, return FALSE as well! */ - - if (cptr < default_umm_heap || cptr >= default_umm_heap + UMM_MALLOC_CFG_HEAP_SIZE) - return FALSE; - - /* - * FIXME: At some point it might be a good idea to add a check to make sure - * that the pointer we're being asked to free up is actually within - * the umm_heap! - * - * NOTE: See the new umm_info() function that you can use to see if a ptr is - * on the free list! - */ - - /* Protect the critical section... */ - UMM_CRITICAL_ENTRY(); - - /* Figure out which block we're in. Note the use of truncated division... */ - - c = (UINT32)((((UINT8 *)ptr)-(UINT8 *)(&(umm_heap[0])))/sizeof(umm_block)); - - DBGLOG_DEBUG( "Freeing block %6i\n", c ); - - /* Now let's assimilate this block with the next one if possible. */ - - umm_assimilate_up( c ); - - /* Then assimilate with the previous block if possible */ - - if( UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK ) { - - DBGLOG_DEBUG( "Assimilate down to next block, which is FREE\n" ); - - c = umm_assimilate_down(c, UMM_FREELIST_MASK); - } else { - /* - * The previous block is not a free block, so add this one to the head - * of the free list - */ - - DBGLOG_DEBUG( "Just add to head of free list\n" ); - - UMM_PFREE(UMM_NFREE(0)) = c; - UMM_NFREE(c) = UMM_NFREE(0); - UMM_PFREE(c) = 0; - UMM_NFREE(0) = c; - - UMM_NBLOCK(c) |= UMM_FREELIST_MASK; - } - - /* Release the critical section... */ - UMM_CRITICAL_EXIT(); - - return TRUE; -} - -/* ------------------------------------------------------------------------ */ - -VOID *UmmMalloc( UINT32 size ) { - UINT32 blocks; - UINT32 blockSize = 0; - - UINT32 bestSize; - UINT32 bestBlock; - - UINT32 cf; - - /* If we are not initialised, reuturn false! */ - if ( !UmmInitialized() ) - return NULL; - - /* - * the very first thing we do is figure out if we're being asked to allocate - * a size of 0 - and if we are we'll simply return a null pointer. if not - * then reduce the size by 1 byte so that the subsequent calculations on - * the number of blocks to allocate are easier... - */ - - if( 0 == size ) { - DBGLOG_DEBUG( "malloc a block of 0 bytes -> do nothing\n" ); - - return( (VOID *)NULL ); - } - - /* Protect the critical section... */ - UMM_CRITICAL_ENTRY(); - - blocks = umm_blocks( size ); - - /* - * Now we can scan through the free list until we find a space that's big - * enough to hold the number of blocks we need. - * - * This part may be customized to be a best-fit, worst-fit, or first-fit - * algorithm - */ - - cf = UMM_NFREE(0); - - bestBlock = UMM_NFREE(0); - bestSize = 0x7FFFFFFF; - - while( cf ) { - blockSize = (UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK) - cf; - - DBGLOG_TRACE( "Looking at block %6i size %6i\n", cf, blockSize ); - -#if defined UMM_BEST_FIT - if( (blockSize >= blocks) && (blockSize < bestSize) ) { - bestBlock = cf; - bestSize = blockSize; - } -#elif defined UMM_FIRST_FIT - /* This is the first block that fits! */ - if( (blockSize >= blocks) ) - break; -#else -# error "No UMM_*_FIT is defined - check umm_malloc_cfg.h" -#endif - - cf = UMM_NFREE(cf); - } - - if( 0x7FFFFFFF != bestSize ) { - cf = bestBlock; - blockSize = bestSize; - } - - if( UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK && blockSize >= blocks ) { - /* - * This is an existing block in the memory heap, we just need to split off - * what we need, unlink it from the free list and mark it as in use, and - * link the rest of the block back into the freelist as if it was a new - * block on the free list... - */ - - if( blockSize == blocks ) { - /* It's an exact fit and we don't neet to split off a block. */ - DBGLOG_DEBUG( "Allocating %6i blocks starting at %6i - exact\n", blocks, cf ); - - /* Disconnect this block from the FREE list */ - - umm_disconnect_from_free_list( cf ); - - } else { - /* It's not an exact fit and we need to split off a block. */ - DBGLOG_DEBUG( "Allocating %6i blocks starting at %6i - existing\n", blocks, cf ); - - /* - * split current free block `cf` into two blocks. The first one will be - * returned to user, so it's not free, and the second one will be free. - */ - umm_split_block( cf, blocks, UMM_FREELIST_MASK /*new block is free*/ ); - - /* - * `umm_split_block()` does not update the free pointers (it affects - * only free flags), but effectively we've just moved beginning of the - * free block from `cf` to `cf + blocks`. So we have to adjust pointers - * to and from adjacent free blocks. - */ - - /* previous free block */ - UMM_NFREE( UMM_PFREE(cf) ) = cf + blocks; - UMM_PFREE( cf + blocks ) = UMM_PFREE(cf); - - /* next free block */ - UMM_PFREE( UMM_NFREE(cf) ) = cf + blocks; - UMM_NFREE( cf + blocks ) = UMM_NFREE(cf); - } - } else { - /* Out of memory */ - - DBGLOG_DEBUG( "Can't allocate %5i blocks\n", blocks ); - - /* Release the critical section... */ - UMM_CRITICAL_EXIT(); - - return( (VOID *)NULL ); - } - - /* Release the critical section... */ - UMM_CRITICAL_EXIT(); - - return( (VOID *)&UMM_DATA(cf) ); -} - -/* ------------------------------------------------------------------------ */ diff --git a/Library/OcMemoryLib/VirtualMemory.c b/Library/OcMemoryLib/VirtualMemory.c deleted file mode 100755 index d468e65df..000000000 --- a/Library/OcMemoryLib/VirtualMemory.c +++ /dev/null @@ -1,417 +0,0 @@ -/** @file - Copyright (C) 2011, dmazar. All rights reserved. - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include - -PAGE_MAP_AND_DIRECTORY_POINTER * -OcGetCurrentPageTable ( - OUT UINTN *Flags OPTIONAL - ) -{ - PAGE_MAP_AND_DIRECTORY_POINTER *PageTable; - UINTN CR3; - - CR3 = AsmReadCr3 (); - - PageTable = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN) (CR3 & CR3_ADDR_MASK); - - if (Flags != NULL) { - *Flags = CR3 & (CR3_FLAG_PWT | CR3_FLAG_PCD); - } - - return PageTable; -} - -EFI_STATUS -OcGetPhysicalAddress ( - IN PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - OUT EFI_PHYSICAL_ADDRESS *PhysicalAddr - ) -{ - EFI_PHYSICAL_ADDRESS Start; - VIRTUAL_ADDR VA; - VIRTUAL_ADDR VAStart; - VIRTUAL_ADDR VAEnd; - PAGE_MAP_AND_DIRECTORY_POINTER *PML4; - PAGE_MAP_AND_DIRECTORY_POINTER *PDPE; - PAGE_MAP_AND_DIRECTORY_POINTER *PDE; - PAGE_TABLE_4K_ENTRY *PTE4K; - PAGE_TABLE_2M_ENTRY *PTE2M; - PAGE_TABLE_1G_ENTRY *PTE1G; - - if (PageTable == NULL) { - PageTable = OcGetCurrentPageTable (NULL); - } - - VA.Uint64 = (UINT64) VirtualAddr; - - // - // PML4 - // - PML4 = PageTable; - PML4 += VA.Pg4K.PML4Offset; - VAStart.Uint64 = 0; - VAStart.Pg4K.PML4Offset = VA.Pg4K.PML4Offset; - VA_FIX_SIGN_EXTEND (VAStart); - VAEnd.Uint64 = ~(UINT64) 0; - VAEnd.Pg4K.PML4Offset = VA.Pg4K.PML4Offset; - VA_FIX_SIGN_EXTEND (VAEnd); - - if (!PML4->Bits.Present) { - return EFI_NO_MAPPING; - } - - // - // PDPE - // - PDPE = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(PML4->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PDPE += VA.Pg4K.PDPOffset; - VAStart.Pg4K.PDPOffset = VA.Pg4K.PDPOffset; - VAEnd.Pg4K.PDPOffset = VA.Pg4K.PDPOffset; - - if (!PDPE->Bits.Present) { - return EFI_NO_MAPPING; - } - - if (PDPE->Bits.MustBeZero & 0x1) { - // - // 1GB PDPE - // - PTE1G = (PAGE_TABLE_1G_ENTRY *) PDPE; - Start = PTE1G->Uint64 & PAGING_1G_ADDRESS_MASK_64; - *PhysicalAddr = Start + VA.Pg1G.PhysPgOffset; - return EFI_SUCCESS; - } - - // - // PDE - // - PDE = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(PDPE->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PDE += VA.Pg4K.PDOffset; - VAStart.Pg4K.PDOffset = VA.Pg4K.PDOffset; - VAEnd.Pg4K.PDOffset = VA.Pg4K.PDOffset; - - if (!PDE->Bits.Present) { - return EFI_NO_MAPPING; - } - - if (PDE->Bits.MustBeZero & 0x1) { - // - // 2MB PDE - // - PTE2M = (PAGE_TABLE_2M_ENTRY *) PDE; - Start = PTE2M->Uint64 & PAGING_2M_ADDRESS_MASK_64; - *PhysicalAddr = Start + VA.Pg2M.PhysPgOffset; - return EFI_SUCCESS; - } - - // - // PTE - // - PTE4K = (PAGE_TABLE_4K_ENTRY *)(UINTN)(PDE->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PTE4K += VA.Pg4K.PTOffset; - VAStart.Pg4K.PTOffset = VA.Pg4K.PTOffset; - VAEnd.Pg4K.PTOffset = VA.Pg4K.PTOffset; - - if (!PTE4K->Bits.Present) { - return EFI_NO_MAPPING; - } - - Start = PTE4K->Uint64 & PAGING_4K_ADDRESS_MASK_64; - *PhysicalAddr = Start + VA.Pg4K.PhysPgOffset; - - return EFI_SUCCESS; -} - -EFI_STATUS -VmAllocateMemoryPool ( - OUT OC_VMEM_CONTEXT *Context, - IN UINTN NumPages, - IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Addr; - - Addr = BASE_4GB; - Status = OcAllocatePagesFromTop ( - EfiBootServicesData, - NumPages, - &Addr, - GetMemoryMap, - NULL - ); - - if (!EFI_ERROR(Status)) { - Context->MemoryPool = (UINT8 *)(UINTN)Addr; - Context->FreePages = NumPages; - } - - return Status; -} - -VOID * -VmAllocatePages ( - IN OUT OC_VMEM_CONTEXT *Context, - IN UINTN NumPages - ) -{ - VOID *AllocatedPages; - - AllocatedPages = NULL; - - if (Context->FreePages >= NumPages) { - AllocatedPages = Context->MemoryPool; - Context->MemoryPool += EFI_PAGES_TO_SIZE (NumPages); - Context->FreePages -= NumPages; - } - - return AllocatedPages; -} - -EFI_STATUS -VmMapVirtualPage ( - IN OUT OC_VMEM_CONTEXT *Context, - IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr - ) -{ - EFI_PHYSICAL_ADDRESS Start; - VIRTUAL_ADDR VA; - VIRTUAL_ADDR VAStart; - VIRTUAL_ADDR VAEnd; - PAGE_MAP_AND_DIRECTORY_POINTER *PML4; - PAGE_MAP_AND_DIRECTORY_POINTER *PDPE; - PAGE_MAP_AND_DIRECTORY_POINTER *PDE; - PAGE_TABLE_4K_ENTRY *PTE4K; - PAGE_TABLE_4K_ENTRY *PTE4KTmp; - PAGE_TABLE_2M_ENTRY *PTE2M; - PAGE_TABLE_1G_ENTRY *PTE1G; - UINTN Index; - - if (PageTable == NULL) { - PageTable = OcGetCurrentPageTable (NULL); - } - - VA.Uint64 = (UINT64) VirtualAddr; - - // - // PML4 - // - PML4 = PageTable; - PML4 += VA.Pg4K.PML4Offset; - - // - // There is a problem if our PML4 points to the same table as first PML4 entry - // since we may mess the mapping of first virtual region (happens in VBox and probably DUET). - // Check for this on first call and if true, just clear our PML4 - we'll rebuild at a later step. - // - if (PML4 != PageTable && PML4->Bits.Present - && PageTable->Bits.PageTableBaseAddress == PML4->Bits.PageTableBaseAddress) { - PML4->Uint64 = 0; - } - - VAStart.Uint64 = 0; - VAStart.Pg4K.PML4Offset = VA.Pg4K.PML4Offset; - VA_FIX_SIGN_EXTEND (VAStart); - VAEnd.Uint64 = ~(UINT64) 0; - VAEnd.Pg4K.PML4Offset = VA.Pg4K.PML4Offset; - VA_FIX_SIGN_EXTEND (VAEnd); - - if (!PML4->Bits.Present) { - PDPE = (PAGE_MAP_AND_DIRECTORY_POINTER *) VmAllocatePages (Context, 1); - - if (PDPE == NULL) { - return EFI_NO_MAPPING; - } - - ZeroMem (PDPE, EFI_PAGE_SIZE); - - // - // Init this whole 512 GB region with 512 1GB entry pages to map - // the first 512 GB physical space. - // - PTE1G = (PAGE_TABLE_1G_ENTRY *) PDPE; - Start = 0; - for (Index = 0; Index < 512; ++Index) { - PTE1G->Uint64 = Start & PAGING_1G_ADDRESS_MASK_64; - PTE1G->Bits.ReadWrite = 1; - PTE1G->Bits.Present = 1; - PTE1G->Bits.MustBe1 = 1; - PTE1G++; - Start += BASE_1GB; - } - - // - // Put it to PML4. - // - PML4->Uint64 = ((UINT64)(UINTN) PDPE) & PAGING_4K_ADDRESS_MASK_64; - PML4->Bits.ReadWrite = 1; - PML4->Bits.Present = 1; - } - - // - // PDPE - // - PDPE = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(PML4->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PDPE += VA.Pg4K.PDPOffset; - VAStart.Pg4K.PDPOffset = VA.Pg4K.PDPOffset; - VAEnd.Pg4K.PDPOffset = VA.Pg4K.PDPOffset; - - if (!PDPE->Bits.Present || (PDPE->Bits.MustBeZero & 0x1)) { - PDE = (PAGE_MAP_AND_DIRECTORY_POINTER *) VmAllocatePages(Context, 1); - - if (PDE == NULL) { - return EFI_NO_MAPPING; - } - - ZeroMem (PDE, EFI_PAGE_SIZE); - - if (PDPE->Bits.MustBeZero & 0x1) { - // - // This is 1 GB page. Init new PDE array to get the same - // mapping but with 2MB pages. - // - PTE2M = (PAGE_TABLE_2M_ENTRY *) PDE; - Start = PDPE->Uint64 & PAGING_1G_ADDRESS_MASK_64; - - for (Index = 0; Index < 512; ++Index) { - PTE2M->Uint64 = Start & PAGING_2M_ADDRESS_MASK_64; - PTE2M->Bits.ReadWrite = 1; - PTE2M->Bits.Present = 1; - PTE2M->Bits.MustBe1 = 1; - PTE2M++; - Start += BASE_2MB; - } - } - - // - // Put it to PDPE. - // - PDPE->Uint64 = ((UINT64)(UINTN) PDE) & PAGING_4K_ADDRESS_MASK_64; - PDPE->Bits.ReadWrite = 1; - PDPE->Bits.Present = 1; - } - - // - // PDE - // - PDE = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(PDPE->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PDE += VA.Pg4K.PDOffset; - VAStart.Pg4K.PDOffset = VA.Pg4K.PDOffset; - VAEnd.Pg4K.PDOffset = VA.Pg4K.PDOffset; - - if (!PDE->Bits.Present || (PDE->Bits.MustBeZero & 0x1)) { - PTE4K = (PAGE_TABLE_4K_ENTRY *) VmAllocatePages (Context, 1); - - if (PTE4K == NULL) { - return EFI_NO_MAPPING; - } - - ZeroMem (PTE4K, EFI_PAGE_SIZE); - - if (PDE->Bits.MustBeZero & 0x1) { - // - // This is 2 MB page. Init new PTE array to get the same - // mapping but with 4KB pages. - // - PTE4KTmp = (PAGE_TABLE_4K_ENTRY *)PTE4K; - Start = PDE->Uint64 & PAGING_2M_ADDRESS_MASK_64; - - for (Index = 0; Index < 512; ++Index) { - PTE4KTmp->Uint64 = Start & PAGING_4K_ADDRESS_MASK_64; - PTE4KTmp->Bits.ReadWrite = 1; - PTE4KTmp->Bits.Present = 1; - PTE4KTmp++; - Start += BASE_4KB; - } - } - - // - // Put it to PDE. - // - PDE->Uint64 = ((UINT64)(UINTN) PTE4K) & PAGING_4K_ADDRESS_MASK_64; - PDE->Bits.ReadWrite = 1; - PDE->Bits.Present = 1; - } - - // - // PTE - // - PTE4K = (PAGE_TABLE_4K_ENTRY *)(UINTN)(PDE->Uint64 & PAGING_4K_ADDRESS_MASK_64); - PTE4K += VA.Pg4K.PTOffset; - VAStart.Pg4K.PTOffset = VA.Pg4K.PTOffset; - VAEnd.Pg4K.PTOffset = VA.Pg4K.PTOffset; - - // - // Put it to PTE. - // - PTE4K->Uint64 = ((UINT64) PhysicalAddr) & PAGING_4K_ADDRESS_MASK_64; - PTE4K->Bits.ReadWrite = 1; - PTE4K->Bits.Present = 1; - - return EFI_SUCCESS; -} - -EFI_STATUS -VmMapVirtualPages ( - IN OUT OC_VMEM_CONTEXT *Context, - IN OUT PAGE_MAP_AND_DIRECTORY_POINTER *PageTable OPTIONAL, - IN EFI_VIRTUAL_ADDRESS VirtualAddr, - IN UINT64 NumPages, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr - ) -{ - EFI_STATUS Status; - - if (PageTable == NULL) { - PageTable = OcGetCurrentPageTable (NULL); - } - - Status = EFI_SUCCESS; - - while (NumPages > 0 && !EFI_ERROR(Status)) { - Status = VmMapVirtualPage ( - Context, - PageTable, - VirtualAddr, - PhysicalAddr - ); - - VirtualAddr += EFI_PAGE_SIZE; - PhysicalAddr += EFI_PAGE_SIZE; - NumPages--; - } - - return Status; -} - -VOID -VmFlushCaches ( - VOID - ) -{ - // - // Simply reload CR3 register. - // - AsmWriteCr3 (AsmReadCr3 ()); -} diff --git a/Library/OcMiscLib/DataPatcher.c b/Library/OcMiscLib/DataPatcher.c deleted file mode 100644 index d7284b6a0..000000000 --- a/Library/OcMiscLib/DataPatcher.c +++ /dev/null @@ -1,117 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include - -INT32 -FindPattern ( - IN CONST UINT8 *Pattern, - IN CONST UINT8 *PatternMask OPTIONAL, - IN CONST UINT32 PatternSize, - IN CONST UINT8 *Data, - IN UINT32 DataSize, - IN INT32 DataOff - ) -{ - BOOLEAN Matches; - UINT32 Index; - - ASSERT (DataOff >= 0); - - if (PatternSize == 0 || DataSize == 0 || (DataOff < 0) || (UINT32)DataOff >= DataSize || DataSize - DataOff < PatternSize) { - return -1; - } - - while (DataOff + PatternSize < DataSize) { - Matches = TRUE; - for (Index = 0; Index < PatternSize; ++Index) { - if ((PatternMask == NULL && Data[DataOff + Index] != Pattern[Index]) - || (PatternMask != NULL && (Data[DataOff + Index] & PatternMask[Index]) != Pattern[Index])) { - Matches = FALSE; - break; - } - } - - if (Matches) { - return DataOff; - } - ++DataOff; - } - - return -1; -} - -UINT32 -ApplyPatch ( - IN CONST UINT8 *Pattern, - IN CONST UINT8 *PatternMask OPTIONAL, - IN CONST UINT32 PatternSize, - IN CONST UINT8 *Replace, - IN CONST UINT8 *ReplaceMask OPTIONAL, - IN UINT8 *Data, - IN UINT32 DataSize, - IN UINT32 Count, - IN UINT32 Skip - ) -{ - UINT32 ReplaceCount; - INT32 DataOff; - - ReplaceCount = 0; - DataOff = 0; - - do { - DataOff = FindPattern (Pattern, PatternMask, PatternSize, Data, DataSize, DataOff); - - if (DataOff >= 0) { - // - // Skip this finding if requested. - // - if (Skip > 0) { - --Skip; - DataOff += PatternSize; - continue; - } - - // - // Perform replacement. - // - if (ReplaceMask == NULL) { - CopyMem (&Data[DataOff], Replace, PatternSize); - } else { - for (UINTN Index = 0; Index < PatternSize; ++Index) { - Data[DataOff + Index] = (Data[DataOff + Index] & ~ReplaceMask[Index]) | (Replace[Index] & ReplaceMask[Index]); - } - } - ++ReplaceCount; - DataOff += PatternSize; - - // - // Check replace count if requested. - // - if (Count > 0) { - --Count; - if (Count == 0) { - break; - } - } - } - - } while (DataOff >= 0); - - return ReplaceCount; -} diff --git a/Library/OcMiscLib/DirectReset.c b/Library/OcMiscLib/DirectReset.c deleted file mode 100644 index 71ba26135..000000000 --- a/Library/OcMiscLib/DirectReset.c +++ /dev/null @@ -1,29 +0,0 @@ -/** @file - Reset System Library functions for OVMF - - Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include - -VOID -DirectRestCold ( - VOID - ) -{ - volatile UINTN Index; - IoWrite8 (0xCF9, BIT2 | BIT1); // 1st choice: PIIX3 RCR, RCPU|SRST - - for (Index = 0; Index < 100; ++Index) { - ; - } - - IoWrite8 (0x64, 0xfe); // 2nd choice: keyboard controller - CpuDeadLoop (); -} diff --git a/Library/OcMiscLib/Math.c b/Library/OcMiscLib/Math.c deleted file mode 100644 index 07c6a2d27..000000000 --- a/Library/OcMiscLib/Math.c +++ /dev/null @@ -1,60 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - **/ - -#include -#include - -/** - MultThenDivU64x64x32 is from MdeModulePkg's PciRootBridgeIo.c - - Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - **/ -UINT64 -MultThenDivU64x64x32 ( - IN UINT64 Multiplicand, - IN UINT64 Multiplier, - IN UINT32 Divisor, - OUT UINT32 *Remainder OPTIONAL - ) -{ - UINT64 Uint64; - UINT32 LocalRemainder; - UINT32 Uint32; - if (Multiplicand > DivU64x64Remainder (MAX_UINT64, Multiplier, NULL)) { - // - // Make sure Multiplicand is the bigger one. - // - if (Multiplicand < Multiplier) { - Uint64 = Multiplicand; - Multiplicand = Multiplier; - Multiplier = Uint64; - } - // - // Because Multiplicand * Multiplier overflows, - // Multiplicand * Multiplier / Divisor - // = (2 * Multiplicand' + 1) * Multiplier / Divisor - // = 2 * (Multiplicand' * Multiplier / Divisor) + Multiplier / Divisor - // - Uint64 = MultThenDivU64x64x32 (RShiftU64 (Multiplicand, 1), Multiplier, Divisor, &LocalRemainder); - Uint64 = LShiftU64 (Uint64, 1); - Uint32 = 0; - if ((Multiplicand & 0x1) == 1) { - Uint64 += DivU64x32Remainder (Multiplier, Divisor, &Uint32); - } - return Uint64 + DivU64x32Remainder (Uint32 + LShiftU64 (LocalRemainder, 1), Divisor, Remainder); - } else { - return DivU64x32Remainder (MultU64x64 (Multiplicand, Multiplier), Divisor, Remainder); - } -} diff --git a/Library/OcMiscLib/OcMiscLib.inf b/Library/OcMiscLib/OcMiscLib.inf deleted file mode 100755 index 5e296ff3e..000000000 --- a/Library/OcMiscLib/OcMiscLib.inf +++ /dev/null @@ -1,53 +0,0 @@ -## @file -# -# Component description file for OcMisclibrary. -# -# Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcMiscLib - FILE_GUID = E9DF6F29-95AC-429A-8E42-FCE1F5B81148 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcMiscLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# VALID_ARCHITECTURES = IA32 X64 - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[Protocols] - gEfiPciIoProtocolGuid - gEfiShellParametersProtocolGuid - gEfiLoadedImageProtocolGuid - -[LibraryClasses] - BaseLib - UefiLib - OcFileLib - OcGuardLib - OcStringLib - -[Sources] - DataPatcher.c - DirectReset.c - ReleaseUsbOwnership.c - ProtocolSupport.c - Math.c - ../../Include/Library/OcMiscLib.h diff --git a/Library/OcMiscLib/ProtocolSupport.c b/Library/OcMiscLib/ProtocolSupport.c deleted file mode 100644 index ef02168cb..000000000 --- a/Library/OcMiscLib/ProtocolSupport.c +++ /dev/null @@ -1,138 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include - -EFI_STATUS -GetArguments ( - OUT UINTN *Argc, - OUT CHAR16 ***Argv - ) -{ - EFI_STATUS Status; - EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - - Status = gBS->HandleProtocol ( - gImageHandle, - &gEfiShellParametersProtocolGuid, - (VOID**) &ShellParameters - ); - if (!EFI_ERROR(Status)) { - *Argc = ShellParameters->Argc; - *Argv = ShellParameters->Argv; - return EFI_SUCCESS; - } - - Status = gBS->HandleProtocol ( - gImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID**) &LoadedImage - ); - if (EFI_ERROR(Status) || LoadedImage->LoadOptions == NULL) { - return EFI_NOT_FOUND; - } - - STATIC CHAR16 *StArgv[2] = {L"Self", NULL}; - StArgv[1] = LoadedImage->LoadOptions; - *Argc = ARRAY_SIZE (StArgv); - *Argv = StArgv; - return EFI_SUCCESS; -} - -EFI_STATUS -OcUninstallAllProtocolInstances ( - EFI_GUID *Protocol - ) -{ - EFI_STATUS Status; - EFI_HANDLE *Handles; - UINTN Index; - UINTN NoHandles; - VOID *OriginalProto; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - Protocol, - NULL, - &NoHandles, - &Handles - ); - - if (Status == EFI_NOT_FOUND) { - return EFI_SUCCESS; - } - - if (EFI_ERROR(Status)) { - return Status; - } - - for (Index = 0; Index < NoHandles; ++Index) { - Status = gBS->HandleProtocol ( - Handles[Index], - Protocol, - &OriginalProto - ); - - if (EFI_ERROR(Status)) { - break; - } - - Status = gBS->UninstallProtocolInterface ( - Handles[Index], - Protocol, - OriginalProto - ); - - if (EFI_ERROR(Status)) { - break; - } - } - - gBS->FreePool (Handles); - - return Status; -} - -EFI_STATUS -OcHandleProtocolFallback ( - IN EFI_HANDLE Handle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = gBS->HandleProtocol ( - Handle, - Protocol, - Interface - ); - if (EFI_ERROR(Status)) { - Status = gBS->LocateProtocol ( - Protocol, - NULL, - Interface - ); - } - - return Status; -} diff --git a/Library/OcMiscLib/ReleaseUsbOwnership.c b/Library/OcMiscLib/ReleaseUsbOwnership.c deleted file mode 100644 index 2d5faa5fc..000000000 --- a/Library/OcMiscLib/ReleaseUsbOwnership.c +++ /dev/null @@ -1,605 +0,0 @@ -/** @file - Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include - -#include - -#include -#include -#include -#include - -#define XHC_HCCPARAMS_OFFSET 0x10 -#define XHC_NEXT_CAPABILITY_MASK 0xFF00 -#define XHC_CAPABILITY_ID_MASK 0xFF -#define XHC_USBCMD_OFFSET 0x0 ///< USB Command Register Offset -#define XHC_USBSTS_OFFSET 0x4 ///< USB Status Register Offset -#define XHC_POLL_DELAY 1000 - -#define EHC_BAR_INDEX 0x0 -#define EHC_HCCPARAMS_OFFSET 0x8 -#define EHC_USBCMD_OFFSET 0x0 ///< USB Command Register Offset -#define EHC_USBSTS_OFFSET 0x4 ///< USB Status Register Offset -#define EHC_USBINT_OFFSET 0x8 ///< USB Interrupt Enable Register - -/** - Release XHCI USB controllers ownership. - - @param[in] PciIo PCI I/O protocol for the device. - - @retval EFI_NOT_FOUND No XHCI controllers had ownership incorrectly set. - @retval EFI_SUCCESS Corrected XHCI controllers ownership to OS. -**/ -STATIC -EFI_STATUS -XhciReleaseOwnership ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - EFI_STATUS Status; - - UINT32 HcCapParams; - UINT32 ExtendCap; - UINT32 Value; - INT32 TimeOut; - - // - // XHCI controller, then disable legacy support, if enabled. - // - - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - XHC_HCCPARAMS_OFFSET, - 1, - &HcCapParams - ); - - ExtendCap = EFI_ERROR(Status) ? 0 : ((HcCapParams >> 14U) & 0x3FFFCU); - - while (ExtendCap) { - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap, - 1, - &Value - ); - - if (EFI_ERROR(Status)) { - break; - } - - if ((Value & XHC_CAPABILITY_ID_MASK) == 1) { - // - // Do nothing if BIOS ownership is cleared. - // - if (!(Value & BIT16)) { - break; - } - - Value |= BIT24; - - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap, - 1, - &Value - ); - - TimeOut = 40; - while (TimeOut--) { - gBS->Stall (500); - - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap, - 1, - &Value - ); - - if (EFI_ERROR(Status) || !(Value & BIT16)) { - break; - } - } - - // - // Disable all SMI in USBLEGCTLSTS - // - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap + 4, - 1, - &Value - ); - - if (EFI_ERROR(Status)) { - break; - } - - Value &= 0x1F1FEEU; - Value |= 0xE0000000U; - - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap + 4, - 1, - &Value - ); - - // - // Clear all ownership - // - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap, - 1, - &Value - ); - - if (EFI_ERROR(Status)) { - break; - } - - Value &= ~(BIT24 | BIT16); - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - XHC_USBCMD_OFFSET, - ExtendCap, - 1, - &Value - ); - - break; - } - - if (!(Value & XHC_NEXT_CAPABILITY_MASK)) { - break; - } - - ExtendCap += ((Value >> 6U) & 0x3FCU); - } - - return Status; -} - -/** - Release EHCI USB controllers ownership. - - @param[in] PciIo PCI I/O protocol for the device. - - @retval EFI_NOT_FOUND No EHCI controllers had ownership incorrectly set. - @retval EFI_SUCCESS Corrected EHCI controllers ownership to OS. - **/ -STATIC -EFI_STATUS -EhciReleaseOwnership ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - EFI_STATUS Status; - UINT32 Value; - UINT32 Base; - UINT32 OpAddr; - UINT32 ExtendCap; - UINT32 UsbCmd; - UINT32 UsbLegSup; - UINT32 UsbLegCtlSts; - UINTN IsOsOwned; - UINTN IsBiosOwned; - BOOLEAN IsOwnershipConflict; - UINT32 HcCapParams; - INT32 TimeOut; - - Value = 0x0002; - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x04, - 1, - &Value - ); - - Base = 0; - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0x10, - 1, - &Base - ); - - if (MmioRead8 (Base) < 0x0C) { - // - // Config space too small: no legacy implementation. - // - return EFI_NOT_FOUND; - } - - // - // Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0). - // - OpAddr = Base + MmioRead8 (Base); - - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - EHC_BAR_INDEX, - EHC_HCCPARAMS_OFFSET, - 1, - &HcCapParams - ); - - ExtendCap = (HcCapParams >> 8U) & 0xFFU; - - // - // Read PCI Config 32bit USBLEGSUP (eecp+0). - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &UsbLegSup - ); - - IsBiosOwned = (UsbLegSup & BIT16) != 0; - if (!IsBiosOwned) { - // - // No BIOS ownership, ignore. - // - return EFI_NOT_FOUND; - } - - // - // Read PCI Config 32bit USBLEGCTLSTS (eecp+4). - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap + 0x4, - 1, - &UsbLegCtlSts - ); - - // - // Disable the SMI in USBLEGCTLSTS firstly. - // - UsbLegCtlSts &= 0xFFFF0000U; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap + 0x4, - 1, - &UsbLegCtlSts - ); - - UsbCmd = MmioRead32 (OpAddr + EHC_USBCMD_OFFSET); - - // - // Clear registers to default. - // - UsbCmd = UsbCmd & 0xFFFFFF00U; - MmioWrite32 (OpAddr + EHC_USBCMD_OFFSET, UsbCmd); - MmioWrite32 (OpAddr + EHC_USBINT_OFFSET, 0); - MmioWrite32 (OpAddr + EHC_USBSTS_OFFSET, 0x1000); - - Value = 1; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - // - // Read 32bit USBLEGSUP (eecp+0). - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &UsbLegSup - ); - - IsBiosOwned = (UsbLegSup & BIT16) != 0; - IsOsOwned = (UsbLegSup & BIT24) != 0; - - // - // Read 32bit USBLEGCTLSTS (eecp+4). - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap + 0x4, - 1, - &UsbLegCtlSts - ); - - // - // Get EHCI Ownership from legacy bios. - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &UsbLegSup - ); - - IsOwnershipConflict = IsBiosOwned && IsOsOwned; - - if (IsOwnershipConflict) { - // - // EHCI - Ownership conflict - attempting soft reset. - // - Value = 0; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint8, - ExtendCap + 3, - 1, - &Value - ); - - TimeOut = 40; - while (TimeOut--) { - gBS->Stall (500); - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - if ((Value & BIT24) == 0x0) { - break; - } - } - } - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - Value |= BIT24; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - TimeOut = 40; - while (TimeOut--) { - gBS->Stall (500); - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - if ((Value & BIT16) == 0x0) { - break; - } - } - - IsOwnershipConflict = (Value & BIT16) != 0x0; - if (IsOwnershipConflict) { - // - // Soft reset has failed. Assume SMI being ignored and do hard reset. - // - Value = 0; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint8, - ExtendCap + 2, - 1, - &Value - ); - - TimeOut = 40; - while (TimeOut--) { - gBS->Stall (500); - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap, - 1, - &Value - ); - - if ((Value & BIT16) == 0x0) { - break; - } - } - - // - // Disable further SMI events. - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap + 0x4, - 1, - &UsbLegCtlSts - ); - - UsbLegCtlSts &= 0xFFFF0000U; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - ExtendCap + 0x4, - 1, - &UsbLegCtlSts - ); - } - - if (Value & BIT16) { - // - // EHCI controller unable to take control from BIOS. - // - Status = EFI_NOT_FOUND; - } - - return Status; -} - -/** - Release UHCI USB controllers ownership. - - @param[in] PciIo PCI I/O protocol for the device. - - @retval EFI_NOT_FOUND No UHCI controllers had ownership incorrectly set. - @retval EFI_SUCCESS Corrected UHCI controllers ownership to OS. - **/ -STATIC -EFI_STATUS -UhciReleaseOwnership ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - EFI_STATUS Status; - UINT32 Base; - UINT32 PortBase; - UINT16 Command; - - Base = 0; - - Status = PciIo->Pci.Read( - PciIo, - EfiPciIoWidthUint32, - 0x20, - 1, - &Base - ); - - PortBase = (Base >> 5) & 0x07ff; - - Command = 0x8f00; - - Status = PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0xC0, - 1, - &Command - ); - - if (PortBase != 0 && (PortBase & BIT0) == 0) { - IoWrite16 (PortBase, 0x0002); - gBS->Stall (500); - IoWrite16 (PortBase + 4, 0); - gBS->Stall (500); - IoWrite16 (PortBase, 0); - } - - return Status; -} - -EFI_STATUS -ReleaseUsbOwnership ( - VOID - ) -{ - EFI_STATUS Result; - EFI_STATUS Status; - EFI_HANDLE *HandleArray; - UINTN HandleArrayCount; - UINTN Index; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 Pci; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleArrayCount, - &HandleArray - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - Result = EFI_UNSUPPORTED; - - for (Index = 0; Index < HandleArrayCount; ++Index) { - Status = gBS->HandleProtocol ( - HandleArray[Index], - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo - ); - - if (EFI_ERROR(Status)) { - continue; - } - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (Pci) / sizeof (UINT32), - &Pci - ); - - if (EFI_ERROR(Status) - || Pci.Hdr.ClassCode[1] != PCI_CLASS_SERIAL_USB - || Pci.Hdr.ClassCode[2] != PCI_CLASS_SERIAL) { - continue; - } - - if (Pci.Hdr.ClassCode[0] == PCI_IF_XHCI) { - Result = XhciReleaseOwnership (PciIo); - } else if (Pci.Hdr.ClassCode[0] == PCI_IF_EHCI) { - Result = EhciReleaseOwnership (PciIo); - } else if (Pci.Hdr.ClassCode[0] == PCI_IF_UHCI) { - Result = UhciReleaseOwnership (PciIo); - } - } - - gBS->FreePool (HandleArray); - return Result; -} diff --git a/Library/OcOSInfoLib/OcOSInfoLib.c b/Library/OcOSInfoLib/OcOSInfoLib.c deleted file mode 100644 index 8bf622171..000000000 --- a/Library/OcOSInfoLib/OcOSInfoLib.c +++ /dev/null @@ -1,237 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -STATIC UINTN mBootVTdEnabled; -STATIC CHAR8 *mOSName; -STATIC CHAR8 *mOSVendor; -STATIC BOOLEAN mAppleOSLoadedSignaled; - -STATIC -VOID -InternalOSInfoSet ( - VOID - ) -{ - UINTN Index; - UINTN Length; - CHAR8 *VersionPtr; - UINT32 MajorVersion; - UINT32 MinorVersion; - - DEBUG (( - DEBUG_INFO, - "OCOS: OS set: %a %a\n", - mOSVendor != NULL ? mOSVendor : "", - mOSName != NULL ? mOSName : "" - )); - - if (mOSVendor == NULL) { - return; - } - - if (AsciiStrCmp (mOSVendor, EFI_OS_INFO_APPLE_VENDOR_NAME) == 0) { - if (!mAppleOSLoadedSignaled) { - EfiNamedEventSignal (&gAppleOSLoadedNamedEventGuid); - mAppleOSLoadedSignaled = TRUE; - } - - if (mOSName == NULL) { - return; - } - - Length = AsciiStrLen (mOSName); - for (Index = 0; Index < Length; ++Index) { - if (mOSName[Index] == '.') { - break; - } - } - - if (Index == Length || Index == 0 || mOSName[Index + 1] == '\0') { - return; - } - - VersionPtr = &mOSName[Index - 1]; - while (VersionPtr > mOSName) { - if (*VersionPtr < '0' || *VersionPtr > '9') { - ++VersionPtr; - break; - } - --VersionPtr; - } - - if (&mOSName[Index] == VersionPtr) { - return; - } - - MajorVersion = 0; - while (VersionPtr < &mOSName[Index]) { - MajorVersion = MajorVersion * 10 + (*VersionPtr - '0'); - ++VersionPtr; - } - - VersionPtr = &mOSName[Index + 1]; - MinorVersion = 0; - while (*VersionPtr != '\0') { - if (*VersionPtr < '0' || *VersionPtr > '9') { - break; - } - MinorVersion = MinorVersion * 10 + (*VersionPtr - '0'); - ++VersionPtr; - } - - if (&mOSName[Index + 1] == VersionPtr) { - return; - } - - if (((MajorVersion << 16U) | MinorVersion) > ((10U << 16U) | 9U)) { - // - // if (BootCurrent == 0x80) RTC[0x30] |= 0x1U; - // REF: E121EC07-9C42-45EE-B0B6-FFF8EF03C521, gAppleRtcRamProtocolGuid. - // - DEBUG ((DEBUG_VERBOSE, "OCOS: Should use black background\n")); - } else { - // - // if (BootCurrent == 0x80) RTC[0x30] &= ~0x1U; - // - DEBUG ((DEBUG_VERBOSE, "OCOS: Should use grey background\n")); - } - } -} - -STATIC -VOID -EFIAPI -SetName ( - IN CHAR8 *OSName - ) -{ - UINTN Size; - CHAR8 *Buffer; - - if (mOSName != NULL) { - FreePool (mOSName); - mOSName = NULL; - } - - Size = AsciiStrSize (OSName); - Buffer = AllocateCopyPool (Size, OSName); - - mOSName = Buffer; - - InternalOSInfoSet (); -} - -VOID -EFIAPI -SetVendor ( - IN CHAR8 *OSVendor - ) -{ - UINTN Size; - CHAR8 *Buffer; - - if (mOSVendor != NULL) { - FreePool (mOSVendor); - mOSVendor = NULL; - } - - Size = AsciiStrSize (OSVendor); - Buffer = AllocateCopyPool (Size, OSVendor); - - mOSVendor = Buffer; - - InternalOSInfoSet (); -} - -STATIC -VOID -EFIAPI -SetBootVTdEnabled ( - IN UINTN *BootVTdEnabled - ) -{ - mBootVTdEnabled = *BootVTdEnabled; -} - -STATIC -VOID -EFIAPI -GetBootVTdEnabled ( - OUT UINTN *BootVTdEnabled - ) -{ - *BootVTdEnabled = mBootVTdEnabled; -} - -STATIC -EFI_OS_INFO_PROTOCOL -mOSInfoProtocol = { - EFI_OS_INFO_PROTOCOL_REVISION3, - SetName, - SetVendor, - SetBootVTdEnabled, - GetBootVTdEnabled -}; - -EFI_OS_INFO_PROTOCOL * -OcOSInfoInstallProtocol ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - EFI_OS_INFO_PROTOCOL *Protocol; - - DEBUG ((DEBUG_VERBOSE, "OcOSInfoInstallProtocol\n")); - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gEfiOSInfoProtocolGuid); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCOS: Uninstall failed: %r\n", Status)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gEfiOSInfoProtocolGuid, - NULL, - (VOID *) &Protocol - ); - - if (!EFI_ERROR(Status)) { - return Protocol; - } - } - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gEfiOSInfoProtocolGuid, - (VOID *) &mOSInfoProtocol, - NULL - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - return &mOSInfoProtocol; -} diff --git a/Library/OcOSInfoLib/OcOSInfoLib.inf b/Library/OcOSInfoLib/OcOSInfoLib.inf deleted file mode 100755 index 266575f28..000000000 --- a/Library/OcOSInfoLib/OcOSInfoLib.inf +++ /dev/null @@ -1,54 +0,0 @@ -## @file -# -# Component description file for the library producing the OS Info protocol. -# -# Copyright (C) 2020, vit9696. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcOSInfoLib - FILE_GUID = 74DD65A5-60FC-4511-ABA6-C1016088B7CC - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcOSInfoLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - OcOSInfoLib.c - ../../Include/Library/OcOSInfoLib.h - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[Guids] - gAppleOSLoadedNamedEventGuid - -[Protocols] - gEfiOSInfoProtocolGuid - -[LibraryClasses] - BaseLib - DebugLib - MemoryAllocationLib - OcMiscLib - UefiLib - UefiBootServicesTableLib diff --git a/Library/OcRngLib/Ia32/RngDelay.nasm b/Library/OcRngLib/Ia32/RngDelay.nasm deleted file mode 100644 index 1492aa034..000000000 --- a/Library/OcRngLib/Ia32/RngDelay.nasm +++ /dev/null @@ -1,72 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 32 -DEFAULT REL - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT64 -; EFIAPI -; AsmAddRngJitter ( -; IN UINT64 Value -; ); -;------------------------------------------------------------------------------ -align 8 -global ASM_PFX(AsmAddRngJitter) -ASM_PFX(AsmAddRngJitter): - ; This assembly code corresponds to Hamming Weight implementation for targets - ; with fast multiplication. - ; REF: https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation - push esi - mov edx, [esp+8] - mov eax, [esp+12] - mov ecx, edx - shr ecx, 1 - mov esi, eax - shr esi, 1 - and esi, 55555555h - and ecx, 55555555h - sub edx, ecx - sbb eax, esi - mov ecx, eax - and ecx, 33333333h - mov esi, edx - and esi, 33333333h - shr edx, 2 - shr eax, 2 - and eax, 33333333h - add eax, ecx - and edx, 33333333h - add edx, esi - mov ecx, eax - shld ecx, edx, 1Ch - mov esi, eax - shr esi, 4 - add ecx, edx - adc esi, eax - and esi, 0F0F0F0Fh - and ecx, 0F0F0F0Fh - mov edx, 1010101h - mov eax, ecx - mul edx - imul ecx, 1010101h - add ecx, edx - imul eax, esi, 1010101h - add eax, ecx - shr eax, 18h - pop esi - ret diff --git a/Library/OcRngLib/OcRngInternals.h b/Library/OcRngLib/OcRngInternals.h deleted file mode 100644 index d1ac4a359..000000000 --- a/Library/OcRngLib/OcRngInternals.h +++ /dev/null @@ -1,81 +0,0 @@ -/** @file - Copyright (C) 2020, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OC_RNG_INTERNALS_H -#define OC_RNG_INTERNALS_H - -#include - -/** - Performs delay on target platform to cause microoperating scheduling - and introduce timing entropy. - - @param[in] Value Dummy value. - - @retval Dummy value. -**/ -UINT64 -EFIAPI -AsmAddRngJitter ( - IN UINT64 Value - ); - -// -// Limited retry number when valid random data is returned. -// Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32 -// Architectures Software Developer's Mannual". -// -#define RDRAND_RETRY_LIMIT 10 - -// -// Maximum amount of bytes emitted by PRNG before next reseed. -// -#define MAX_BYTES_TO_EMIT 1600000 - -// -// Maximum bytes in one buffer. -// -#define MAX_BYTES_IN_BUF (16*64) - -/** - Random Number Generator context. -**/ -typedef struct OC_RNG_CONTEXT_ { - // - // Hardware random number generator available. - // - BOOLEAN HardwareRngAvailable; - // - // Done initialising pseudo random number generator. - // - BOOLEAN PrngInitialised; - // - // Amount of bytes to emit before next reseed. - // - UINT32 BytesTillReseed; - // - // Amount of bytes in the current buffer. - // - UINT32 BytesInBuffer; - // - // Current CPRNG buffer. - // - UINT8 Buffer[MAX_BYTES_IN_BUF]; - // - // ChaCha context. - // - CHACHA_CONTEXT ChaCha; -} OC_RNG_CONTEXT; - -#endif // OC_RNG_INTERNALS_H diff --git a/Library/OcRngLib/OcRngLib.c b/Library/OcRngLib/OcRngLib.c deleted file mode 100644 index f8cba9471..000000000 --- a/Library/OcRngLib/OcRngLib.c +++ /dev/null @@ -1,415 +0,0 @@ -/** @file - Random number generator services that uses RdRand instruction access - to provide high-quality random numbers. - In addition to that we provide interfaces that generate pseudo random - numbers through TSC, which can be used when RdRand is not available. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - - Copyright (c) 2019, vit9696 - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include -#include -#include - -#include - -#include "OcRngInternals.h" - -STATIC OC_RNG_CONTEXT mRng; - -STATIC -VOID -ChaChaRngStir ( - IN UINT32 BytesNeeded - ) -{ - // - // Implementation design based on arc4random from FreeBSD. - // - - UINTN Index; - UINT32 KeySeed[CHACHA_KEY_SIZE / sizeof (UINT32)]; - UINT32 IvSeed[CHACHA_IV_SIZE / sizeof (UINT32)]; - BOOLEAN Result; - -// STATIC_ASSERT (CHACHA_KEY_SIZE % sizeof (UINT32) == 0, "Unexpected key size"); -// STATIC_ASSERT (CHACHA_IV_SIZE % sizeof (UINT32) == 0, "Unexpected key size"); - -// ASSERT (BytesNeeded <= MAX_BYTES_TO_EMIT); - - // - // Do not reseed if we are initialised and do not yet need a reseed. - // - if (mRng.PrngInitialised && mRng.BytesTillReseed >= BytesNeeded) { - mRng.BytesTillReseed -= BytesNeeded; - return; - } - - // - // Generate seeds. - // - for (Index = 0; Index < ARRAY_SIZE (KeySeed); ++Index) { - Result = GetRandomNumber32 (&KeySeed[Index]); - if (!Result) { - ASSERT (FALSE); - CpuDeadLoop (); - } - } - - for (Index = 0; Index < ARRAY_SIZE (IvSeed); ++Index) { - Result = GetRandomNumber32 (&IvSeed[Index]); - if (!Result) { - ASSERT (FALSE); - CpuDeadLoop (); - } - } - - // - // Reinitialize if we are making a second loop. - // - if (mRng.PrngInitialised) { - ZeroMem (mRng.Buffer, sizeof (mRng.Buffer)); - // - // Fill buffer with keystream. - // - ChaChaCryptBuffer (&mRng.ChaCha, mRng.Buffer, mRng.Buffer, sizeof (mRng.Buffer)); - // - // Mix in RNG data. - // - for (Index = 0; Index < ARRAY_SIZE (KeySeed); ++Index) { - mRng.Buffer[Index] ^= KeySeed[Index]; - } - for (Index = 0; Index < ARRAY_SIZE (IvSeed); ++Index) { - mRng.Buffer[ARRAY_SIZE (KeySeed) + Index] ^= KeySeed[Index]; - } - } else { - mRng.PrngInitialised = TRUE; - } - - // - // Setup ChaCha context. - // - ChaChaInitCtx (&mRng.ChaCha, (UINT8 *) KeySeed, (UINT8 *) IvSeed, 0); - - SecureZeroMem (KeySeed, sizeof (KeySeed)); - SecureZeroMem (IvSeed, sizeof (IvSeed)); - - mRng.BytesTillReseed = MAX_BYTES_TO_EMIT - BytesNeeded; - mRng.BytesInBuffer = 0; - - ZeroMem (mRng.Buffer, sizeof (mRng.Buffer)); -} - -STATIC -VOID -ChaChaRngGenerate ( - OUT UINT8 *Data, - IN UINT32 Size - ) -{ - UINT32 CurrentSize; - - ASSERT (Size <= MAX_BYTES_TO_EMIT); - - ChaChaRngStir (Size); - - while (Size > 0) { - if (mRng.BytesInBuffer > 0) { - CurrentSize = MIN (Size, mRng.BytesInBuffer); - - CopyMem (Data, mRng.Buffer + sizeof (mRng.Buffer) - mRng.BytesInBuffer, CurrentSize); - ZeroMem (mRng.Buffer + sizeof (mRng.Buffer) - mRng.BytesInBuffer, CurrentSize); - - Data += CurrentSize; - Size -= CurrentSize; - mRng.BytesInBuffer -= CurrentSize; - } - - if (mRng.BytesInBuffer == 0) { - ZeroMem (mRng.Buffer, sizeof (mRng.Buffer)); - // - // Fill buffer with keystream. - // - ChaChaCryptBuffer (&mRng.ChaCha, mRng.Buffer, mRng.Buffer, sizeof (mRng.Buffer)); - // - // Immediately reinit for backtracking resistance. - // - ChaChaInitCtx (&mRng.ChaCha, &mRng.Buffer[0], &mRng.Buffer[CHACHA_KEY_SIZE], 0); - ZeroMem (mRng.Buffer, CHACHA_KEY_SIZE + CHACHA_IV_SIZE); - mRng.BytesInBuffer = sizeof (mRng.Buffer) - CHACHA_KEY_SIZE - CHACHA_IV_SIZE; - } - } -} - -STATIC -UINT64 -GetEntropyBits ( - IN UINTN Bits - ) -{ - UINTN Index; - UINT64 Entropy; - UINT64 Tmp; - - // - // Uses non-deterministic CPU execution. - // REF: https://static.lwn.net/images/conf/rtlws11/random-hardware.pdf - // REF: https://www.osadl.org/fileadmin/dam/presentations/RTLWS11/okech-inherent-randomness.pdf - // REF: http://lkml.iu.edu/hypermail/linux/kernel/1909.3/03714.html - // - Entropy = 0; - for (Index = 0; Index < Bits; ++Index) { - Tmp = AsmReadTsc () + AsmAddRngJitter (AsmReadTsc ()); - if ((Tmp & BIT0) != 0) { - Entropy |= LShiftU64 (1, Index); - } - } - - return Entropy; -} - -/** - The constructor function checks whether or not RDRAND instruction is supported - by the host hardware. - - The constructor function checks whether or not RDRAND instruction is supported. - It will ASSERT() if RDRAND instruction is not supported. - It will always return EFI_SUCCESS. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -OcRngLibConstructor ( - VOID - ) -{ - CPUID_VERSION_INFO_ECX RegEcx; - - // - // Determine RDRAND support by examining bit 30 of the ECX register returned by - // CPUID. A value of 1 indicates that processor support RDRAND instruction. - // - AsmCpuid (1, 0, 0, &RegEcx.Uint32, 0); - mRng.HardwareRngAvailable = RegEcx.Bits.RDRAND != 0; - - // - // Initialize PRNG. - // - ChaChaRngStir (0); - - return EFI_SUCCESS; -} - -/** - Generates a 16-bit random number. - - if Rand is NULL, then ASSERT(). - - @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 -GetRandomNumber16 ( - OUT UINT16 *Rand - ) -{ - UINT32 Index; - - ASSERT (Rand != NULL); - - if (mRng.HardwareRngAvailable) { - // - // A loop to fetch a 16 bit random value with a retry count limit. - // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand16 (Rand)) { - return TRUE; - } - } - } - - *Rand = (UINT16) GetEntropyBits (sizeof (UINT16) * OC_CHAR_BIT); - return TRUE; -} - -/** - Generates a 32-bit random number. - - if Rand is NULL, then ASSERT(). - - @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 -GetRandomNumber32 ( - OUT UINT32 *Rand - ) -{ - UINT32 Index; - - ASSERT (Rand != NULL); - - if (mRng.HardwareRngAvailable) { - // - // A loop to fetch a 32 bit random value with a retry count limit. - // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand32 (Rand)) { - return TRUE; - } - } - } - - *Rand = (UINT32) GetEntropyBits (sizeof (UINT32) * OC_CHAR_BIT); - return TRUE; -} - -/** - Generates a 64-bit random number. - - if Rand is NULL, then ASSERT(). - - @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 -GetRandomNumber64 ( - OUT UINT64 *Rand - ) -{ - UINT32 Index; - - ASSERT (Rand != NULL); - - if (mRng.HardwareRngAvailable) { - // - // A loop to fetch a 64 bit random value with a retry count limit. - // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand64 (Rand)) { - return TRUE; - } - } - } - - *Rand = GetEntropyBits (sizeof (UINT64) * OC_CHAR_BIT); - return TRUE; -} - -/** - Generates a 128-bit random number. - - if Rand is NULL, then ASSERT(). - - @param[out] Rand Buffer pointer to store the 128-bit random value. - - @retval TRUE Random number generated successfully. - @retval FALSE Failed to generate the random number. - -**/ -BOOLEAN -EFIAPI -GetRandomNumber128 ( - OUT UINT64 *Rand - ) -{ - ASSERT (Rand != NULL); - - if (mRng.HardwareRngAvailable) { - // - // Read 64 bits twice - // - if (GetRandomNumber64 (&Rand[0]) - && GetRandomNumber64 (&Rand[1])) { - return TRUE; - } - } - - Rand[0] = GetEntropyBits (sizeof (UINT64) * OC_CHAR_BIT); - Rand[1] = GetEntropyBits (sizeof (UINT64) * OC_CHAR_BIT); - return TRUE; -} - -/** - Generates a 16-bit pseudo random number. - - @retval 16-bit pseudo random number. -**/ -UINT16 -EFIAPI -GetPseudoRandomNumber16 ( - VOID - ) -{ - UINT16 Rand; - - ChaChaRngGenerate ((UINT8 *) &Rand, sizeof (Rand)); - - return Rand; -} - -/** - Generates a 32-bit pseudo random number. - - @retval 32-bit pseudo random number. -**/ -UINT32 -EFIAPI -GetPseudoRandomNumber32 ( - VOID - ) -{ - UINT32 Rand; - - ChaChaRngGenerate ((UINT8 *) &Rand, sizeof (Rand)); - - return Rand; -} - -/** - Generates a 64-bit pseudo random number. - - @retval 64-bit pseudo random number. -**/ -UINT64 -EFIAPI -GetPseudoRandomNumber64 ( - VOID - ) -{ - UINT64 Rand; - - ChaChaRngGenerate ((UINT8 *) &Rand, sizeof (Rand)); - - return Rand; -} diff --git a/Library/OcRngLib/OcRngLib.inf b/Library/OcRngLib/OcRngLib.inf deleted file mode 100644 index 91e0739ea..000000000 --- a/Library/OcRngLib/OcRngLib.inf +++ /dev/null @@ -1,50 +0,0 @@ -## @file -# OcRngLib -# -# Copyright (c) 2019, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcRngLib - FILE_GUID = 416BA864-86D7-4AB5-A508-3B91DC52CFC9 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = RngLib - CONSTRUCTOR = OcRngLibConstructor - -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources.Ia32, Sources.X64] - OcRngLib.c - OcRngInternals.h - ../../Include/Library/OcRngLib.h - -[Sources.Ia32] - Ia32/RngDelay.nasm - -[Sources.X64] - X64/RngDelay.nasm - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - OcCryptoLib diff --git a/Library/OcRngLib/X64/RngDelay.nasm b/Library/OcRngLib/X64/RngDelay.nasm deleted file mode 100644 index b578d2f37..000000000 --- a/Library/OcRngLib/X64/RngDelay.nasm +++ /dev/null @@ -1,53 +0,0 @@ -;------------------------------------------------------------------------------ -; @file -; Copyright (C) 2020, vit9696. All rights reserved. -; -; All rights reserved. -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;------------------------------------------------------------------------------ - -BITS 64 -DEFAULT REL - -SECTION .text - -;------------------------------------------------------------------------------ -; UINT64 -; EFIAPI -; AsmAddRngJitter ( -; IN UINT64 Value -; ); -;------------------------------------------------------------------------------ -align 8 -global ASM_PFX(AsmAddRngJitter) -ASM_PFX(AsmAddRngJitter): - ; This assembly code corresponds to Hamming Weight implementation for targets - ; with fast multiplication. - ; REF: https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation - mov rax, rcx - shr rax, 1 - mov rdx, 5555555555555555h - and rdx, rax - sub rcx, rdx - mov rax, 3333333333333333h - mov rdx, rcx - and rdx, rax - shr rcx, 2 - and rcx, rax - add rcx, rdx - mov rax, rcx - shr rax, 4 - lea rax, [rax+rcx] - mov rcx, 0F0F0F0F0F0F0F0Fh - and rcx, rax - mov rax, 101010101010101h - imul rax, rcx - shr rax, 38h - ret diff --git a/Library/OcRtcLib/AppleRtcRam.c b/Library/OcRtcLib/AppleRtcRam.c deleted file mode 100644 index 824d4e9f0..000000000 --- a/Library/OcRtcLib/AppleRtcRam.c +++ /dev/null @@ -1,367 +0,0 @@ -/** @file - - OcRtcLib - library with RTC I/O functions - - Copyright (c) 2020, vit9696 - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "OcRtcLibInternal.h" - -STATIC EFI_LOCK mAppleRtcRamLock; -STATIC UINT8 mEmulatedRtcArea[APPLE_RTC_TOTAL_SIZE]; -STATIC BOOLEAN mEmulatedRtcStatus[APPLE_RTC_TOTAL_SIZE]; - - -STATIC -EFI_STATUS -SyncRtcRead ( - IN UINT8 Address, - IN UINT8 *ValuePtr - ) -{ - EFI_STATUS Status; - - if (mEmulatedRtcStatus[Address]) { - return mEmulatedRtcArea[Address]; - } - - Status = EfiAcquireLockOrFail (&mAppleRtcRamLock); - if (EFI_ERROR(Status)) { - return Status; - } - - *ValuePtr = OcRtcRead (Address); - EfiReleaseLock (&mAppleRtcRamLock); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SyncRtcWrite ( - IN UINT8 Address, - IN UINT8 Value - ) -{ - EFI_STATUS Status; - - if (mEmulatedRtcStatus[Address]) { - mEmulatedRtcArea[Address] = Value; - return EFI_SUCCESS; - } - - Status = EfiAcquireLockOrFail (&mAppleRtcRamLock); - if (EFI_ERROR(Status)) { - return Status; - } - - OcRtcWrite (Address, Value); - EfiReleaseLock (&mAppleRtcRamLock); - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SyncRtcWaitForReady ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Count; - UINT8 RegisterA; - - for (Count = 0; Count < 100; ++Count) { - Status = EfiAcquireLockOrFail (&mAppleRtcRamLock); - - if (!EFI_ERROR(Status)) { - RegisterA = OcRtcRead (RTC_ADDRESS_REGISTER_A); - EfiReleaseLock (&mAppleRtcRamLock); - - if ((RegisterA & RTC_UPDATE_IN_PROGRESS) == 0) { - return EFI_SUCCESS; - } - } - - // - // Wait 1 ms and retry. - // - gBS->Stall (1000); - } - - return EFI_TIMEOUT; -} - -STATIC -UINTN -EFIAPI -AppleRtcGetAvailableMemory ( - IN APPLE_RTC_RAM_PROTOCOL *This - ) -{ - return APPLE_RTC_TOTAL_SIZE; -} - -STATIC -EFI_STATUS -EFIAPI -AppleRtcRamReadData ( - IN APPLE_RTC_RAM_PROTOCOL *This, - OUT UINT8 *Buffer, - IN UINTN BufferSize, - IN UINTN Address - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT8 Temp; - - if (Buffer == NULL - || BufferSize == 0 - || Address >= APPLE_RTC_TOTAL_SIZE - || BufferSize >= APPLE_RTC_TOTAL_SIZE - || Address + BufferSize > APPLE_RTC_TOTAL_SIZE) { - return EFI_INVALID_PARAMETER; - } - - for (Index = 0; Index < BufferSize; ++Index) { - Status = SyncRtcWaitForReady (); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = SyncRtcRead ((UINT8) Address, Buffer); - if (EFI_ERROR(Status)) { - return Status; - } - - if (Address == APPLE_RTC_BG_COLOR_ADDR) { - Status = SyncRtcWaitForReady (); - if (EFI_ERROR(Status)) { - return Status; - } - - Status = SyncRtcRead (APPLE_RTC_BG_COMPLEMENT_ADDR, &Temp); - if (EFI_ERROR(Status)) { - return Status; - } - - if ((Temp ^ *Buffer) != 0xFF) { - *Buffer = 0; - } - } - - ++Buffer; - ++Address; - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AppleRtcRamWriteData ( - IN APPLE_RTC_RAM_PROTOCOL *This, - IN CONST UINT8 *Buffer, - IN UINTN BufferSize, - IN UINTN Address - ) -{ - EFI_STATUS Status; - UINT8 TempBuffer[APPLE_RTC_TOTAL_SIZE]; - UINTN Index; - UINT16 Checksum; - - if (Buffer == NULL - || BufferSize == 0 - || Address < APPLE_RTC_CHECKSUM_START - || Address >= APPLE_RTC_TOTAL_SIZE - || BufferSize >= APPLE_RTC_TOTAL_SIZE - || Address + BufferSize > APPLE_RTC_TOTAL_SIZE) { - return EFI_INVALID_PARAMETER; - } - - Status = AppleRtcRamReadData (This, TempBuffer, APPLE_RTC_TOTAL_SIZE, 0); - if (EFI_ERROR(Status)) { - return Status; ///< This is not checked in the original. - } - - for (Index = 0; Index < BufferSize; ++Index) { - if (Address != APPLE_RTC_BG_COMPLEMENT_ADDR) { - TempBuffer[Address] = *Buffer; - - if (Address == APPLE_RTC_BG_COLOR_ADDR) { - TempBuffer[APPLE_RTC_BG_COMPLEMENT_ADDR] = (UINT8) ~((UINT32) *Buffer); - } - } - - ++Buffer; - ++Address; - } - - Checksum = OcRtcChecksumApple (TempBuffer, APPLE_RTC_CORE_CHECKSUM_ADDR1); - TempBuffer[APPLE_RTC_CORE_CHECKSUM_ADDR1] = APPLE_RTC_CORE_CHECKSUM_BYTE1 (Checksum); - TempBuffer[APPLE_RTC_CORE_CHECKSUM_ADDR2] = APPLE_RTC_CORE_CHECKSUM_BYTE2 (Checksum); - - TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR1] = 0; - TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR2] = 0; - Checksum = OcRtcChecksumApple (TempBuffer, APPLE_RTC_TOTAL_SIZE); - TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR1] = APPLE_RTC_MAIN_CHECKSUM_BYTE1 (Checksum); - TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR2] = APPLE_RTC_MAIN_CHECKSUM_BYTE2 (Checksum); - - for (Index = APPLE_RTC_CHECKSUM_START; Index < APPLE_RTC_TOTAL_SIZE; ++Index) { - SyncRtcWrite ((UINT8) Index, TempBuffer[Index]); ///< Does not check the error code. - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EFIAPI -AppleRtcRamReset ( - IN APPLE_RTC_RAM_PROTOCOL *This - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT8 Buffer[APPLE_RTC_TOTAL_SIZE]; - - ZeroMem (Buffer, sizeof (Buffer)); - - for (Index = APPLE_RTC_CHECKSUM_START; Index < APPLE_RTC_CORE_SIZE; ++Index) { - Status = SyncRtcWaitForReady (); - if (!EFI_ERROR(Status)) { - SyncRtcRead ((UINT8) Index, &Buffer[Index]); - } - } - - Status = SyncRtcWaitForReady (); - if (!EFI_ERROR(Status)) { - SyncRtcRead ((UINT8) APPLE_RTC_FIRMWARE_57_ADDR, &Buffer[APPLE_RTC_FIRMWARE_57_ADDR]); - } - - for (Index = APPLE_RTC_RESERVED_ADDR; Index < APPLE_RTC_RESERVED_ADDR + APPLE_RTC_RESERVED_LENGTH; ++Index) { - Status = SyncRtcWaitForReady (); - if (!EFI_ERROR(Status)) { - SyncRtcRead ((UINT8) Index, &Buffer[Index]); - } - } - - return AppleRtcRamWriteData ( - This, - Buffer + APPLE_RTC_CHECKSUM_START, - APPLE_RTC_TOTAL_SIZE - APPLE_RTC_CHECKSUM_START, - APPLE_RTC_CHECKSUM_START - ); -} - -STATIC -APPLE_RTC_RAM_PROTOCOL -mAppleRtcRamProtocol = { - AppleRtcGetAvailableMemory, - AppleRtcRamReadData, - AppleRtcRamWriteData, - AppleRtcRamReset, -}; - -APPLE_RTC_RAM_PROTOCOL * -OcAppleRtcRamInstallProtocol ( - IN BOOLEAN Reinstall - ) -{ - EFI_STATUS Status; - APPLE_RTC_RAM_PROTOCOL *Protocol; - UINT8 *RtcBlacklist; - UINTN Index; - UINTN RtcBlacklistSize; - - DEBUG ((DEBUG_VERBOSE, "OCRTC: OcAppleRtcRamInstallProtocol\n")); - - if (Reinstall) { - Status = OcUninstallAllProtocolInstances (&gAppleRtcRamProtocolGuid); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "OCRTC: Uninstall failed: %r\n", Status)); - return NULL; - } - } else { - Status = gBS->LocateProtocol ( - &gAppleRtcRamProtocolGuid, - NULL, - (VOID *) &Protocol - ); - - if (!EFI_ERROR(Status)) { - return Protocol; - } - } - - DEBUG (( - DEBUG_INFO, - "OCRTC: Wake log is 0x%02X 0x%02X % 3d 0x%02X\n", - OcRtcRead (APPLE_RTC_TRACE_DATA_ADDR), - OcRtcRead (APPLE_RTC_WL_MASK_ADDR), - OcRtcRead (APPLE_RTC_WL_EVENT_ADDR), - OcRtcRead (APPLE_RTC_WL_EVENT_EXTRA_ADDR) - )); - - Status = GetVariable2 ( - OC_RTC_BLACKLIST_VARIABLE_NAME, - &gOcVendorVariableGuid, - (VOID **) &RtcBlacklist, - &RtcBlacklistSize - ); - - if (!EFI_ERROR(Status)) { - for (Index = 0; Index < RtcBlacklistSize; ++Index) { - mEmulatedRtcStatus[RtcBlacklist[Index]] = TRUE; - DEBUG ((DEBUG_INFO, "OCRTC: Blacklisted %02x address\n", RtcBlacklist[Index])); - } - - FreePool (RtcBlacklist); - } - - // - // Note, for debugging on QEMU this will need to changed to TPL_CALLBACK. - // By default we follow AppleRtcRam implementation. - // Also, AppleRtcRam function may be called after ExitBootServices or around - // GetMemoryMap, so debugging is not perfectly safe. - // - EfiInitializeLock (&mAppleRtcRamLock, TPL_NOTIFY); - - // - // Note, Apple implementation calls AppleRtcRamReset on checksum mismatch. - // - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gAppleRtcRamProtocolGuid, - (VOID *) &mAppleRtcRamProtocol, - NULL - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - return &mAppleRtcRamProtocol; -} diff --git a/Library/OcRtcLib/OcRtcLib.c b/Library/OcRtcLib/OcRtcLib.c deleted file mode 100644 index a50a21536..000000000 --- a/Library/OcRtcLib/OcRtcLib.c +++ /dev/null @@ -1,144 +0,0 @@ -/** @file - -OcRtcLib - library with RTC I/O functions - -Copyright (c) 2017-2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include "OcRtcLibInternal.h" - -UINT8 -OcRtcRead ( - IN UINT8 Offset - ) -{ - UINT8 RtcIndexPort; - UINT8 RtcDataPort; - UINT8 RtcIndexNmi; - - if (Offset < RTC_BANK_SIZE) { - RtcIndexPort = R_PCH_RTC_INDEX; - RtcDataPort = R_PCH_RTC_TARGET; - } else { - RtcIndexPort = R_PCH_RTC_EXT_INDEX; - RtcDataPort = R_PCH_RTC_EXT_TARGET; - } - - RtcIndexNmi = IoRead8 (RtcIndexPort) & RTC_NMI_MASK; - IoWrite8 (RtcIndexPort, (Offset & RTC_DATA_MASK) | RtcIndexNmi); - return IoRead8 (RtcDataPort); -} - -VOID -OcRtcWrite ( - IN UINT8 Offset, - IN UINT8 Value - ) -{ - UINT8 RtcIndexPort; - UINT8 RtcDataPort; - UINT8 RtcIndexNmi; - - if (Offset < RTC_BANK_SIZE) { - RtcIndexPort = R_PCH_RTC_INDEX; - RtcDataPort = R_PCH_RTC_TARGET; - } else { - RtcIndexPort = R_PCH_RTC_EXT_INDEX; - RtcDataPort = R_PCH_RTC_EXT_TARGET; - } - - RtcIndexNmi = IoRead8 (RtcIndexPort) & RTC_NMI_MASK; - IoWrite8 (RtcIndexPort, (Offset & RTC_DATA_MASK) | RtcIndexNmi); - IoWrite8 (RtcDataPort, Value); -} - -UINT16 -OcRtcChecksumApple ( - IN CONST VOID *Data, - IN UINTN Size - ) -{ - CONST UINT8 *Buffer; - CONST UINT8 *BufferEnd; - UINT16 Checksum; - UINTN Index; - - Buffer = Data; - BufferEnd = Buffer + Size; - Checksum = 0; - - while (Buffer < BufferEnd) { - Checksum ^= *Buffer++; - for (Index = 0; Index < APPLE_RTC_CHECKSUM_ROUNDS; ++Index) { - if (Checksum & 1U) { - Checksum >>= 1U; - Checksum ^= APPLE_RTC_CHECKSUM_POLYNOMIAL; - } else { - Checksum >>= 1U; - } - } - } - - return Checksum; -} - -UINT8 -OcRtcReadIvy ( - IN UINT8 Offset - ) -{ - UINT8 RtcIndexPort; - UINT8 RtcDataPort; - - // - // CMOS access registers (using alternative access not to handle NMI bit) - // - if (Offset < RTC_BANK_SIZE) { - RtcIndexPort = R_PCH_RTC_INDEX_ALT; - RtcDataPort = R_PCH_RTC_TARGET_ALT; - } else { - RtcIndexPort = R_PCH_RTC_EXT_INDEX_ALT; - RtcDataPort = R_PCH_RTC_EXT_TARGET_ALT; - } - - IoWrite8 (RtcIndexPort, Offset & RTC_DATA_MASK); - return IoRead8 (RtcDataPort); -} - -VOID -OcRtcWriteIvy ( - IN UINT8 Offset, - IN UINT8 Value - ) -{ - UINT8 RtcIndexPort; - UINT8 RtcDataPort; - - // - // CMOS access registers (using alternative access not to handle NMI bit) - // - if (Offset < RTC_BANK_SIZE) { - RtcIndexPort = R_PCH_RTC_INDEX_ALT; - RtcDataPort = R_PCH_RTC_TARGET_ALT; - } else { - RtcIndexPort = R_PCH_RTC_EXT_INDEX_ALT; - RtcDataPort = R_PCH_RTC_EXT_TARGET_ALT; - } - - IoWrite8 (RtcIndexPort, Offset & RTC_DATA_MASK); - IoWrite8 (RtcDataPort, Value); -} diff --git a/Library/OcRtcLib/OcRtcLib.inf b/Library/OcRtcLib/OcRtcLib.inf deleted file mode 100644 index 52750654e..000000000 --- a/Library/OcRtcLib/OcRtcLib.inf +++ /dev/null @@ -1,55 +0,0 @@ -## @file -# OcRtcLib - library with RTC I/O functions -# -# Copyright (c) 2017-2018, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcRtcLib - FILE_GUID = DDFDC74D-E1AC-4A9F-A667-5DB8B6D8A67E - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcRtcLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - AppleRtcRam.c - OcRtcLib.c - OcRtcLibInternal.h - ../../Include/Library/OcRtcLib.h - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[Guids] - gOcVendorVariableGuid - -[Protocols] - gAppleRtcRamProtocolGuid - -[LibraryClasses] - BaseMemoryLib - DebugLib - IoLib - MemoryAllocationLib - OcMiscLib - UefiLib - UefiBootServicesTableLib diff --git a/Library/OcRtcLib/OcRtcLibInternal.h b/Library/OcRtcLib/OcRtcLibInternal.h deleted file mode 100644 index 9c1343570..000000000 --- a/Library/OcRtcLib/OcRtcLibInternal.h +++ /dev/null @@ -1,72 +0,0 @@ -/** @file - - OcRtcLib - library with RTC I/O functions - - Copyright (c) 2020, vit9696 - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef OC_RTC_LIB_INTERNAL_H -#define OC_RTC_LIB_INTERNAL_H - -// -// Available on all platforms, requires NMI bit handling. -// -#define R_PCH_RTC_INDEX 0x70 -#define R_PCH_RTC_TARGET 0x71 -#define R_PCH_RTC_EXT_INDEX 0x72 -#define R_PCH_RTC_EXT_TARGET 0x73 - -// -// Available on Ivy Bridge and newer. Ignores NMI bit. -// -#define R_PCH_RTC_INDEX_ALT 0x74 -#define R_PCH_RTC_TARGET_ALT 0x75 -#define R_PCH_RTC_EXT_INDEX_ALT 0x76 -#define R_PCH_RTC_EXT_TARGET_ALT 0x77 - -// -// RTC Memory bank size -// -#define RTC_BANK_SIZE 0x80 - -// -// RTC INDEX bit mask -// -#define RTC_DATA_MASK 0x7F -#define RTC_NMI_MASK 0x80 - -// -// Standard register addresses. -// -#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59 -#define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59 -#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59 -#define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59 -#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM -#define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM -#define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7 -#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31 -#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12 -#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99 -#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7] -#define RTC_ADDRESS_REGISTER_B 11 // R/W -#define RTC_ADDRESS_REGISTER_C 12 // RO -#define RTC_ADDRESS_REGISTER_D 13 // RO - -// -// Register A update in progress bit. -// -#define RTC_UPDATE_IN_PROGRESS 0x80U - -#endif // OC_RTC_LIB_INTERNAL_H diff --git a/Library/OcSerializeLib/OcSerializeLib.c b/Library/OcSerializeLib/OcSerializeLib.c deleted file mode 100644 index 779612dc3..000000000 --- a/Library/OcSerializeLib/OcSerializeLib.c +++ /dev/null @@ -1,418 +0,0 @@ -/** @file - -OcSerializeLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include - -#if DEBUG -STATIC -CONST CHAR8 * -mSchemaTypeNames[] = { - [OC_SCHEMA_VALUE_BOOLEAN] = "boolean", - [OC_SCHEMA_VALUE_INTEGER] = "integer", - [OC_SCHEMA_VALUE_DATA] = "data", - [OC_SCHEMA_VALUE_STRING] = "string", - [OC_SCHEMA_VALUE_MDATA] = "mdata" -}; - - -STATIC -CONST CHAR8 * -GetSchemaTypeName ( - IN UINT32 Type - ) -{ - if (Type < ARRAY_SIZE (mSchemaTypeNames)) { - return mSchemaTypeNames[Type]; - } - return "custom"; -} -#endif - -OC_SCHEMA * -LookupConfigSchema ( - IN OC_SCHEMA *SortedList, - IN UINT32 Size, - IN CONST CHAR8 *Name - ) -{ - UINT32 Start; - UINT32 End; - UINT32 Curr; - INTN Cmp; - - if (Size == 0) { - return NULL; - } - - // - // Classic binary search in a sorted string list. - // - Start = 0; - End = Size - 1; - - while (Start <= End) { - Curr = (Start + End) / 2; - Cmp = AsciiStrCmp (SortedList[Curr].Name, Name); - - if (Cmp == 0) { - return &SortedList[Curr]; - } else if (Cmp < 0) { - Start = Curr + 1; - } else if (Curr > 0) { - End = Curr - 1; - } else { - // - // Even the first element does not match, required due to unsigned End. - // - return NULL; - } - } - - return NULL; -} - -VOID -ParseSerializedDict ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ) -{ - UINT32 DictSize; - UINT32 Index; - CONST CHAR8 *CurrentKey; - XML_NODE *CurrentValue; - XML_NODE *OldValue; - OC_SCHEMA *NewSchema; - - DictSize = PlistDictChildren (Node); - - for (Index = 0; Index < DictSize; Index++) { - CurrentKey = PlistKeyValue (PlistDictChild (Node, Index, &CurrentValue)); - - if (CurrentKey == NULL) { - DEBUG ((DEBUG_WARN, "OCS: No serialized key at %u index, context <%a>!\n", Index, Context)); - continue; - } - - // - // Skip comments. - // - if (CurrentKey[0] == '#') { - continue; - } - - DEBUG ((DEBUG_VERBOSE, "OCS: Parsing serialized at %a at %u index!\n", CurrentKey, Index)); - - // - // We do not protect from duplicating serialized entries. - // - NewSchema = LookupConfigSchema (Info->Dict.Schema, Info->Dict.SchemaSize, CurrentKey); - - if (NewSchema == NULL) { - DEBUG ((DEBUG_WARN, "OCS: No schema for %a at %u index, context <%a>!\n", CurrentKey, Index, Context)); - continue; - } - - OldValue = CurrentValue; - CurrentValue = PlistNodeCast (CurrentValue, NewSchema->Type); - if (CurrentValue == NULL) { - DEBUG (( - DEBUG_WARN, - "OCS: No type match for %a at %u index, expected type %a got %a, context <%a>!\n", - CurrentKey, - Index, - GetSchemaTypeName (NewSchema->Type), - XmlNodeName (OldValue), - Context - )); - continue; - } - - NewSchema->Apply (Serialized, CurrentValue, &NewSchema->Info, CurrentKey); - } -} - -VOID -ParseSerializedValue ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ) -{ - BOOLEAN Result; - VOID *Field; - UINT32 Size; - - Result = FALSE; - Field = OC_SCHEMA_FIELD (Serialized, VOID, Info->Value.Field); - Size = Info->Value.FieldSize; - - switch (Info->Value.Type) { - case OC_SCHEMA_VALUE_BOOLEAN: - Result = PlistBooleanValue (Node, (BOOLEAN *) Field); - break; - case OC_SCHEMA_VALUE_INTEGER: - Result = PlistIntegerValue (Node, Field, Size, FALSE); - break; - case OC_SCHEMA_VALUE_DATA: - Result = PlistDataValue (Node, Field, &Size); - break; - case OC_SCHEMA_VALUE_STRING: - Result = PlistStringValue (Node, Field, &Size); - break; - case OC_SCHEMA_VALUE_MDATA: - Result = PlistMetaDataValue (Node, Field, &Size); - break; - } - - if (Result == FALSE) { - DEBUG (( - DEBUG_WARN, - "OCS: Failed to parse %a field as value with type %a and <%a> contents, context <%a>!\n", - XmlNodeName (Node), - GetSchemaTypeName (Info->Value.Type), - XmlNodeContent (Node) != NULL ? XmlNodeContent (Node) : "empty", - Context - )); - } -} - -VOID -ParseSerializedBlob ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ) -{ - BOOLEAN Result; - VOID *Field; - UINT32 Size; - VOID *BlobMemory; - UINT32 *BlobSize; - - Result = FALSE; - - switch (Info->Blob.Type) { - case OC_SCHEMA_BLOB_DATA: - Result = PlistDataSize (Node, &Size); - break; - case OC_SCHEMA_BLOB_STRING: - Result = PlistStringSize (Node, &Size); - break; - case OC_SCHEMA_BLOB_MDATA: - Result = PlistMetaDataSize (Node, &Size); - break; - } - - if (Result == FALSE) { - DEBUG (( - DEBUG_WARN, - "OCS: Failed to calculate size of %a field containing <%a> as type %a, context <%a>!\n", - XmlNodeName (Node), - XmlNodeContent (Node) != NULL ? XmlNodeContent (Node) : "empty", - GetSchemaTypeName (Info->Blob.Type), - Context - )); - return; - } - - Field = OC_SCHEMA_FIELD (Serialized, VOID, Info->Blob.Field); - BlobMemory = OcBlobAllocate (Field, Size, &BlobSize); - - if (BlobMemory == NULL) { - DEBUG (( - DEBUG_INFO, - "OCS: Failed to allocate %u bytes %a field of type %a, context <%a>!\n", - Size, - XmlNodeName (Node), - GetSchemaTypeName (Info->Value.Type), - Context - )); - return; - } - - Result = FALSE; - - switch (Info->Blob.Type) { - case OC_SCHEMA_BLOB_DATA: - Result = PlistDataValue (Node, (UINT8 *) BlobMemory, BlobSize); - break; - case OC_SCHEMA_BLOB_STRING: - Result = PlistStringValue (Node, (CHAR8 *) BlobMemory, BlobSize); - break; - case OC_SCHEMA_BLOB_MDATA: - Result = PlistMetaDataValue (Node, (UINT8 *) BlobMemory, BlobSize); - break; - } - - if (Result == FALSE) { - DEBUG (( - DEBUG_WARN, - "OCS: Failed to parse %a field as blob with type %a and <%a> contents, context <%a>!\n", - XmlNodeName (Node), - GetSchemaTypeName (Info->Value.Type), - XmlNodeContent (Node) != NULL ? XmlNodeContent (Node) : "empty", - Context - )); - } -} - -VOID -ParseSerializedMap ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ) -{ - UINT32 DictSize; - UINT32 Index; - CONST CHAR8 *CurrentKey; - UINT32 CurrentKeyLen; - XML_NODE *ChildNode; - VOID *NewValue; - VOID *NewKey; - VOID *NewKeyValue; - BOOLEAN Success; - - DictSize = PlistDictChildren (Node); - - for (Index = 0; Index < DictSize; Index++) { - CurrentKey = PlistKeyValue (PlistDictChild (Node, Index, &ChildNode)); - CurrentKeyLen = CurrentKey != NULL ? (UINT32) (AsciiStrLen (CurrentKey) + 1) : 0; - - if (CurrentKeyLen == 0) { - DEBUG ((DEBUG_INFO, "OCS: No get serialized key at %u index!\n", Index)); - continue; - } - - // - // Skip comments. - // - if (CurrentKey[0] == '#') { - continue; - } - - if (PlistNodeCast (ChildNode, Info->List.Schema->Type) == NULL) { - DEBUG ((DEBUG_INFO, "OCS: No valid serialized value at %u index!\n", Index)); - continue; - } - - Success = OcListEntryAllocate ( - OC_SCHEMA_FIELD (Serialized, VOID, Info->List.Field), - &NewValue, - &NewKey - ); - if (Success == FALSE) { - DEBUG ((DEBUG_INFO, "OCS: Couldn't insert dict serialized at %u index!\n", Index)); - continue; - } - - NewKeyValue = OcBlobAllocate (NewKey, CurrentKeyLen, NULL); - if (NewKeyValue != NULL) { - AsciiStrnCpyS ((CHAR8 *) NewKeyValue, CurrentKeyLen, CurrentKey, CurrentKeyLen - 1); - } else { - DEBUG ((DEBUG_INFO, "OCS: Couldn't allocate key name at %u index!\n", Index)); - } - - Info->List.Schema->Apply (NewValue, ChildNode, &Info->List.Schema->Info, CurrentKey); - } -} - -VOID -ParseSerializedArray ( - OUT VOID *Serialized, - IN XML_NODE *Node, - IN OC_SCHEMA_INFO *Info, - IN CONST CHAR8 *Context OPTIONAL - ) -{ - UINT32 ArraySize; - UINT32 Index; - XML_NODE *ChildNode; - VOID *NewValue; - BOOLEAN Success; - - ArraySize = XmlNodeChildren (Node); - - for (Index = 0; Index < ArraySize; Index++) { - ChildNode = PlistNodeCast (XmlNodeChild (Node, Index), Info->List.Schema->Type); - - DEBUG ((DEBUG_VERBOSE, "OCS: Processing array %u/%u element\n", Index + 1, ArraySize)); - - if (ChildNode == NULL) { - DEBUG ((DEBUG_INFO, "OCS: Couldn't get array serialized at %u index!\n", Index)); - continue; - } - - Success = OcListEntryAllocate ( - OC_SCHEMA_FIELD (Serialized, VOID, Info->List.Field), - &NewValue, - NULL - ); - if (Success == FALSE) { - DEBUG ((DEBUG_INFO, "OCS: Couldn't insert array serialized at %u index!\n", Index)); - continue; - } - - Info->List.Schema->Apply (NewValue, ChildNode, &Info->List.Schema->Info, Context); - } -} - -BOOLEAN -ParseSerialized ( - OUT VOID *Serialized, - IN OC_SCHEMA_INFO *RootSchema, - IN VOID *PlistBuffer, - IN UINT32 PlistSize - ) -{ - XML_DOCUMENT *Document; - XML_NODE *RootDict; - - Document = XmlDocumentParse (PlistBuffer, PlistSize, FALSE); - - if (Document == NULL) { - DEBUG ((DEBUG_INFO, "OCS: Couldn't parse serialized file!\n")); - return FALSE; - } - - RootDict = PlistNodeCast (PlistDocumentRoot (Document), PLIST_NODE_TYPE_DICT); - - if (RootDict == NULL) { - DEBUG ((DEBUG_INFO, "OCS: Couldn't get serialized root!\n")); - XmlDocumentFree (Document); - return FALSE; - } - - ParseSerializedDict ( - Serialized, - RootDict, - RootSchema, - "root" - ); - - XmlDocumentFree (Document); - return TRUE; -} diff --git a/Library/OcSerializeLib/OcSerializeLib.inf b/Library/OcSerializeLib/OcSerializeLib.inf deleted file mode 100755 index fa0ed7830..000000000 --- a/Library/OcSerializeLib/OcSerializeLib.inf +++ /dev/null @@ -1,43 +0,0 @@ -## @file -# OcSerializeLib -# -# Copyright (c) 2018, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcSerializeLib - FILE_GUID = CABE9035-D604-4504-B338-A5BCEFCDEE95 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcSerializeLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - OcSerializeLib.c - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - OcTemplateLib - OcXmlLib diff --git a/Library/OcStorageLib/OcStorageLib.c b/Library/OcStorageLib/OcStorageLib.c deleted file mode 100644 index 437a548ed..000000000 --- a/Library/OcStorageLib/OcStorageLib.c +++ /dev/null @@ -1,447 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -OC_STRUCTORS (OC_STORAGE_VAULT_HASH, ()) -OC_MAP_STRUCTORS (OC_STORAGE_VAULT_FILES) -OC_STRUCTORS (OC_STORAGE_VAULT, ()) - -#pragma pack(push, 1) - -typedef PACKED struct { - VENDOR_DEFINED_DEVICE_PATH Vendor; - EFI_DEVICE_PATH_PROTOCOL End; -} DUMMY_BOOT_DEVICE_PATH; - -typedef PACKED struct { - VENDOR_DEFINED_DEVICE_PATH Vendor; - VENDOR_DEFINED_DEVICE_PATH VendorFile; - EFI_DEVICE_PATH_PROTOCOL End; -} DUMMY_BOOT_DEVICE_FILE_PATH; - -#pragma pack(pop) - -// -// We do not want to expose these for the time being!. -// - -#define INTERNAL_STORAGE_GUID \ - { 0x33B5C65A, 0x5B82, 0x403D, {0x87, 0xA5, 0xD4, 0x67, 0x62, 0x50, 0xEC, 0x59} } - -#define INTERNAL_STORAGE_FILE_GUID \ - { 0x1237EC17, 0xD3CE, 0x401D, {0xA8, 0x41, 0xB1, 0xD8, 0x18, 0xF8, 0xAF, 0x1A} } - -STATIC -DUMMY_BOOT_DEVICE_PATH -mDummyBootDevicePath = { - .Vendor = { - .Header = { - .Type = HARDWARE_DEVICE_PATH, - .SubType = HW_VENDOR_DP, - .Length = {sizeof (VENDOR_DEFINED_DEVICE_PATH), 0} - }, - .Guid = INTERNAL_STORAGE_GUID - }, - .End = { - .Type = END_DEVICE_PATH_TYPE, - .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE, - .Length = {END_DEVICE_PATH_LENGTH, 0} - } -}; - -STATIC -DUMMY_BOOT_DEVICE_FILE_PATH -mDummyBootDeviceFilePath = { - .Vendor = { - .Header = { - .Type = HARDWARE_DEVICE_PATH, - .SubType = HW_VENDOR_DP, - .Length = {sizeof (VENDOR_DEFINED_DEVICE_PATH), 0} - }, - .Guid = INTERNAL_STORAGE_GUID - }, - .VendorFile = { - .Header = { - .Type = HARDWARE_DEVICE_PATH, - .SubType = HW_VENDOR_DP, - .Length = {sizeof (VENDOR_DEFINED_DEVICE_PATH), 0} - }, - .Guid = INTERNAL_STORAGE_FILE_GUID - }, - .End = { - .Type = END_DEVICE_PATH_TYPE, - .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE, - .Length = {END_DEVICE_PATH_LENGTH, 0} - } -}; - -STATIC -OC_SCHEMA -mVaultFilesSchema = OC_SCHEMA_DATAF (NULL, UINT8 [SHA256_DIGEST_SIZE]); - -/// -/// WARNING: Field list must be alpabetically ordered here! -/// -STATIC -OC_SCHEMA -mVaultNodesSchema[] = { - OC_SCHEMA_MAP_IN ("Files", OC_STORAGE_VAULT, Files, &mVaultFilesSchema), - OC_SCHEMA_INTEGER_IN ("Version", OC_STORAGE_VAULT, Version), -}; - -STATIC -OC_SCHEMA_INFO -mVaultSchema = { - .Dict = {mVaultNodesSchema, ARRAY_SIZE (mVaultNodesSchema)} -}; - - -STATIC -EFI_STATUS -OcStorageInitializeVault ( - IN OUT OC_STORAGE_CONTEXT *Context, - IN VOID *Vault OPTIONAL, - IN UINT32 VaultSize, - IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL, - IN VOID *Signature OPTIONAL, - IN UINT32 SignatureSize OPTIONAL - ) -{ - if (Signature != NULL && Vault == NULL) { - DEBUG ((DEBUG_ERROR, "OCST: Missing vault with signature\n")); - return EFI_SECURITY_VIOLATION; - } - - if (Vault == NULL) { - DEBUG ((DEBUG_INFO, "OCST: Missing vault data, ignoring...\n")); - return EFI_SUCCESS; - } - - if (Signature != NULL) { - ASSERT (StorageKey != NULL); - - if (!RsaVerifySigDataFromKey (StorageKey, Signature, SignatureSize, Vault, VaultSize, OcSigHashTypeSha256)) { - DEBUG ((DEBUG_ERROR, "OCST: Invalid vault signature\n")); - return EFI_SECURITY_VIOLATION; - } - } - - OC_STORAGE_VAULT_CONSTRUCT (&Context->Vault, sizeof (Context->Vault)); - if (!ParseSerialized (&Context->Vault, &mVaultSchema, Vault, VaultSize)) { - OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault)); - DEBUG ((DEBUG_ERROR, "OCST: Invalid vault data\n")); - return EFI_INVALID_PARAMETER; - } - - if (Context->Vault.Version != OC_STORAGE_VAULT_VERSION) { - OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault)); - DEBUG (( - DEBUG_ERROR, - "OCST: Unsupported vault data verion %u vs %u\n", - Context->Vault.Version, - OC_STORAGE_VAULT_VERSION - )); - return EFI_UNSUPPORTED; - } - - Context->HasVault = TRUE; - - return EFI_SUCCESS; -} - -STATIC -UINT8 * -OcStorageGetDigest ( - IN OUT OC_STORAGE_CONTEXT *Context, - IN CONST CHAR16 *Filename - ) -{ - UINT32 Index; - UINTN StrIndex; - CHAR8 *VaultFilePath; - UINTN FilenameSize; - - if (!Context->HasVault) { - return NULL; - } - - FilenameSize = StrLen (Filename) + 1; - - for (Index = 0; Index < Context->Vault.Files.Count; ++Index) { - if (Context->Vault.Files.Keys[Index]->Size != (UINT32) FilenameSize) { - continue; - } - - VaultFilePath = OC_BLOB_GET (Context->Vault.Files.Keys[Index]); - - for (StrIndex = 0; StrIndex < FilenameSize; ++StrIndex) { - if (Filename[StrIndex] != VaultFilePath[StrIndex]) { - break; - } - } - - if (StrIndex == FilenameSize) { - return &Context->Vault.Files.Values[Index]->Hash[0]; - } - } - - return NULL; -} - -EFI_STATUS -OcStorageInitFromFs ( - OUT OC_STORAGE_CONTEXT *Context, - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, - IN CONST CHAR16 *Path, - IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL *RootVolume; - VOID *Vault; - VOID *Signature; - UINT32 DataSize; - UINT32 SignatureSize; - - ZeroMem (Context, sizeof (*Context)); - - Context->FileSystem = FileSystem; - - Status = FileSystem->OpenVolume (FileSystem, &RootVolume); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCST: FileSystem volume cannot be opened - %r\n", Status)); - return Status; - } - - Status = SafeFileOpen ( - RootVolume, - &Context->StorageRoot, - (CHAR16 *) Path, - EFI_FILE_MODE_READ, - 0 - ); - - RootVolume->Close (RootVolume); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCST: Directory %s cannot be opened - %r\n", Path, Status)); - return Status; - } - - SignatureSize = 0; - - if (StorageKey) { - Signature = OcStorageReadFileUnicode ( - Context, - OC_STORAGE_VAULT_SIGNATURE_PATH, - &SignatureSize - ); - - if (Signature == NULL) { - DEBUG ((DEBUG_ERROR, "OCS: Missing vault signature\n")); - OcStorageFree (Context); - return EFI_SECURITY_VIOLATION; - } - } else { - Signature = NULL; - } - - DataSize = 0; - Vault = OcStorageReadFileUnicode ( - Context, - OC_STORAGE_VAULT_PATH, - &DataSize - ); - - Status = OcStorageInitializeVault (Context, Vault, DataSize, StorageKey, Signature, SignatureSize); - - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_INFO, "OCST: Vault init failure %p (%u) - %r\n", Vault, DataSize, Status)); - } - - gBS->InstallProtocolInterface ( - &Context->StorageHandle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - &mDummyBootDevicePath - ); - Context->DummyDevicePath = &mDummyBootDeviceFilePath.Vendor.Header; - Context->DummyFilePath = &mDummyBootDeviceFilePath.VendorFile.Header; - - if (Signature != NULL) { - FreePool (Signature); - } - - if (Vault != NULL) { - FreePool (Vault); - } - - return Status; -} - -VOID -OcStorageFree ( - IN OUT OC_STORAGE_CONTEXT *Context - ) -{ - if (Context->StorageRoot != NULL) { - Context->StorageRoot->Close (Context->StorageRoot); - Context->StorageRoot = NULL; - } - - if (Context->HasVault) { - OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault)); - Context->HasVault = FALSE; - } -} - -BOOLEAN -OcStorageExistsFileUnicode ( - IN OC_STORAGE_CONTEXT *Context, - IN CONST CHAR16 *FilePath - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL *File; - UINT8 *VaultDigest; - - // - // Using this API with empty filename is also not allowed. - // - ASSERT (Context != NULL); - ASSERT (FilePath != NULL); - ASSERT (StrLen (FilePath) > 0); - - VaultDigest = OcStorageGetDigest (Context, FilePath); - - if (VaultDigest != NULL) { - return TRUE; - } - - if (Context->StorageRoot == NULL) { - return FALSE; - } - - Status = SafeFileOpen ( - Context->StorageRoot, - &File, - (CHAR16 *) FilePath, - EFI_FILE_MODE_READ, - 0 - ); - - if (!EFI_ERROR(Status)) { - File->Close (File); - return TRUE; - } - - return FALSE; -} - -VOID * -OcStorageReadFileUnicode ( - IN OC_STORAGE_CONTEXT *Context, - IN CONST CHAR16 *FilePath, - OUT UINT32 *FileSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL *File; - UINT32 Size; - UINT8 *FileBuffer; - UINT8 *VaultDigest; - UINT8 FileDigest[SHA256_DIGEST_SIZE]; - - // - // Using this API with empty filename is also not allowed. - // - ASSERT (Context != NULL); - ASSERT (FilePath != NULL); - ASSERT (StrLen (FilePath) > 0); - - VaultDigest = OcStorageGetDigest (Context, FilePath); - - if (Context->HasVault && VaultDigest == NULL) { - DEBUG ((DEBUG_ERROR, "OCST: Aborting %s file access not present in vault\n", FilePath)); - return NULL; - } - - if (Context->StorageRoot == NULL) { - // - // TODO: expand support for other contexts. - // - return NULL; - } - - Status = SafeFileOpen ( - Context->StorageRoot, - &File, - (CHAR16 *) FilePath, - EFI_FILE_MODE_READ, - 0 - ); - - if (EFI_ERROR(Status)) { - return NULL; - } - - Status = GetFileSize (File, &Size); - if (EFI_ERROR(Status) || Size >= MAX_UINT32 - 1) { - File->Close (File); - return NULL; - } - - FileBuffer = AllocatePool (Size + 2); - if (FileBuffer == NULL) { - File->Close (File); - return NULL; - } - - Status = GetFileData (File, 0, Size, FileBuffer); - File->Close (File); - if (EFI_ERROR(Status)) { - FreePool (FileBuffer); - return NULL; - } - - if (VaultDigest != 0) { - Sha256 (FileDigest, FileBuffer, Size); - if (CompareMem (FileDigest, VaultDigest, SHA256_DIGEST_SIZE) != 0) { - DEBUG ((DEBUG_ERROR, "OCST: Aborting corrupted %s file access\n", FilePath)); - FreePool (FileBuffer); - return NULL; - } - } - - FileBuffer[Size] = 0; - FileBuffer[Size + 1] = 0; - - if (FileSize != NULL) { - *FileSize = Size; - } - - return FileBuffer; -} diff --git a/Library/OcStorageLib/OcStorageLib.inf b/Library/OcStorageLib/OcStorageLib.inf deleted file mode 100755 index 7e9df3f99..000000000 --- a/Library/OcStorageLib/OcStorageLib.inf +++ /dev/null @@ -1,51 +0,0 @@ -## @file -# -# Component description file for OcFileLibrary. -# -# Copyright (C) 2019, vit9696. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcStorageLib - FILE_GUID = 2B20EC2A-ACAB-4A98-B34A-B5B9BFB05746 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcStorageLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER - -# VALID_ARCHITECTURES = IA32 X64 - -[Sources] - OcStorageLib.c - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - MemoryAllocationLib - OcFileLib - OcSerializeLib - OcStringLib - OcTemplateLib - -[Guids] - gEfiFileInfoGuid ## CONSUMES - gEfiFileSystemInfoGuid ## CONSUMES - gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES - -[Protocols] - gEfiFirmwareVolume2ProtocolGuid diff --git a/Library/OcStringLib/OcAsciiLib.c b/Library/OcStringLib/OcAsciiLib.c deleted file mode 100755 index 3a8f1c1df..000000000 --- a/Library/OcStringLib/OcAsciiLib.c +++ /dev/null @@ -1,168 +0,0 @@ -/** @file - Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include - -// IsAsciiPrint -/** Check if character is printable - - @param[in] Char The ascii character to check if is printable. - - @retval TRUE, if character is printable. -**/ -BOOLEAN -IsAsciiPrint ( - IN CHAR8 Char - ) -{ - return ((Char >= ' ') && (Char < '~')); -} - -// IsAsciiSpace -/** Check if character is a white space character - - @param[in] Char The ascii character to check if is white space. - - @retval TRUE, if character is a white space character -**/ -INTN -IsAsciiSpace ( - IN CHAR8 Char - ) -{ - return ((Char == ' ') - || (Char == '\t') - || (Char == '\v') - || (Char == '\f') - || (Char == '\r') - || (Char == '\n')); -} - -/** Convert null terminated ascii string to unicode. - - @param[in] String1 A pointer to the ascii string to convert to unicode. - @param[in] Length Length or 0 to calculate the length of the ascii string to convert. - - @retval A pointer to the converted unicode string allocated from pool. -**/ -CHAR16 * -AsciiStrCopyToUnicode ( - IN CONST CHAR8 *AsciiString, - IN UINTN Length - ) -{ - CHAR16 *UnicodeString; - CHAR16 *UnicodeStringWalker; - UINTN UnicodeStringSize; - - ASSERT (AsciiString != NULL); - - if (Length == 0) { - Length = AsciiStrLen (AsciiString); - } - - UnicodeStringSize = (Length + 1) * sizeof (CHAR16); - UnicodeString = AllocatePool (UnicodeStringSize); - - if (UnicodeString != NULL) { - UnicodeStringWalker = UnicodeString; - while (*AsciiString != '\0' && Length--) { - *(UnicodeStringWalker++) = *(AsciiString++); - } - *UnicodeStringWalker = L'\0'; - } - - return UnicodeString; -} - -BOOLEAN -AsciiUint64ToLowerHex ( - OUT CHAR8 *Buffer, - IN UINT32 BufferSize, - IN UINT64 Value - ) -{ - CONST UINT32 MaxShifts = (sizeof (UINT64) * 8) - 4; - UINT32 Index; - BOOLEAN Printed; - UINT8 Curr; - - if (BufferSize < 4) { - return FALSE; - } - - *Buffer++ = '0'; - *Buffer++ = 'x'; - - if (Value > 0) { - BufferSize -= 2; - for (Printed = FALSE, Index = MaxShifts; Index <= MaxShifts; Index -= 4) { - Curr = (UINT8) (RShiftU64 (Value, Index) & 0xFU); - Printed |= Curr > 0; - if (Printed) { - *Buffer++ = "0123456789abcdef"[Curr]; - if (--BufferSize == 0) { - return FALSE; - } - } - } - } else { - *Buffer++ = '0'; - } - - *Buffer++ = '\0'; - return TRUE; -} - -EFI_STATUS -EFIAPI -OcAsciiSafeSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Marker; - VA_LIST Marker2; - UINTN NumberOfPrinted; - - ASSERT (StartOfBuffer != NULL); - ASSERT (BufferSize > 0); - ASSERT (FormatString != NULL); - - VA_START (Marker, FormatString); - - VA_COPY (Marker2, Marker); - NumberOfPrinted = SPrintLengthAsciiFormat (FormatString, Marker2); - VA_END (Marker2); - - if (BufferSize - 1 >= NumberOfPrinted) { - AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); - Status = EFI_SUCCESS; - } else { - Status = EFI_OUT_OF_RESOURCES; - } - - VA_END (Marker); - - return Status; -} diff --git a/Library/OcStringLib/OcStringLib.inf b/Library/OcStringLib/OcStringLib.inf deleted file mode 100755 index d940f750a..000000000 --- a/Library/OcStringLib/OcStringLib.inf +++ /dev/null @@ -1,50 +0,0 @@ -## @file -# -# Component description file for OcStringlibrary. -# -# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
-# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcStringLib - FILE_GUID = 1E0810F7-9E40-43D0-A036-185407D0231D - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcStringLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - OcAsciiLib.c - OcUnicodeLib.c - ../../Include/Library/OcStringLib.h - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdePkg/MdePkg.dec - -[Pcd] - gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength ## SOMETIMES_CONSUMES - -[LibraryClasses] - BaseLib - BaseMemoryLib - MemoryAllocationLib - PrintLib diff --git a/Library/OcStringLib/OcUnicodeLib.c b/Library/OcStringLib/OcUnicodeLib.c deleted file mode 100755 index fa0df514f..000000000 --- a/Library/OcStringLib/OcUnicodeLib.c +++ /dev/null @@ -1,273 +0,0 @@ -/** @file - Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -INTN -EFIAPI -OcStriCmp ( - IN CHAR16 *FirstString, - IN CHAR16 *SecondString - ) -{ - CHAR16 UpperFirstString; - CHAR16 UpperSecondString; - - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - UpperFirstString = CharToUpper (*FirstString); - UpperSecondString = CharToUpper (*SecondString); - while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) { - FirstString++; - SecondString++; - UpperFirstString = CharToUpper (*FirstString); - UpperSecondString = CharToUpper (*SecondString); - } - - return UpperFirstString - UpperSecondString; -} - -INTN -EFIAPI -OcStrniCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString, - IN UINTN Length - ) -{ - CHAR16 UpperFirstString; - CHAR16 UpperSecondString; - - if (Length == 0) { - return 0; - } - - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside StrLen(). - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { - ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); - } - - UpperFirstString = CharToUpper (*FirstString); - UpperSecondString = CharToUpper (*SecondString); - while ((*FirstString != L'\0') && - (*SecondString != L'\0') && - (UpperFirstString == UpperSecondString) && - (Length > 1)) { - FirstString++; - SecondString++; - UpperFirstString = CharToUpper (*FirstString); - UpperSecondString = CharToUpper (*SecondString); - Length--; - } - - return UpperFirstString - UpperSecondString; -} - -CHAR16 * -EFIAPI -OcStriStr ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *SearchString - ) -{ - CONST CHAR16 *FirstMatch; - CONST CHAR16 *SearchStringTmp; - - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside StrLen(). - // - ASSERT (StrSize (String) != 0); - ASSERT (StrSize (SearchString) != 0); - - if (*SearchString == L'\0') { - return (CHAR16 *) String; - } - - while (*String != L'\0') { - SearchStringTmp = SearchString; - FirstMatch = String; - - while ((CharToUpper (*String) == CharToUpper (*SearchStringTmp)) - && (*String != L'\0')) { - String++; - SearchStringTmp++; - } - - if (*SearchStringTmp == L'\0') { - return (CHAR16 *) FirstMatch; - } - - if (*String == L'\0') { - return NULL; - } - - String = FirstMatch + 1; - } - - return NULL; -} - -CONST CHAR16 * -OcStrStrLength ( - CONST CHAR16 *String, - UINTN StringLength, - CONST CHAR16 *SearchString, - UINTN SearchStringLength - ) -{ - UINTN Index; - UINTN Index2; - UINTN Index3; - INTN CmpResult; - CONST CHAR16 *Y; - CONST CHAR16 *X; - - // - // REF: http://www-igm.univ-mlv.fr/~lecroq/string/node13.html#SECTION00130 - // - - if (SearchStringLength > StringLength - || SearchStringLength == 0 - || StringLength == 0) { - return NULL; - } - - if (SearchStringLength > 1) { - Index = 0; - - Y = (CONST CHAR16 *) String; - X = (CONST CHAR16 *) SearchString; - - if (X[0] == X[1]) { - Index2 = 2; - Index3 = 1; - } else { - Index2 = 1; - Index3 = 2; - } - - while (Index <= StringLength - SearchStringLength) { - if (X[1] != Y[Index+1]) { - Index += Index2; - } else { - CmpResult = CompareMem (X+2, Y+Index+2, (SearchStringLength - 2) * sizeof (*SearchString)); - if (CmpResult == 0 && X[0] == Y[Index]) { - return &Y[Index]; - } - - Index += Index3; - } - } - } else { - return ScanMem16 (String, StringLength * sizeof (*SearchString), *SearchString); - } - - return NULL; -} - -VOID -UnicodeUefiSlashes ( - IN OUT CHAR16 *String - ) -{ - CHAR16 *Needle; - - while ((Needle = StrStr (String, L"/")) != NULL) { - *Needle = L'\\'; - } -} - -VOID -UnicodeFilterString ( - IN OUT CHAR16 *String, - IN BOOLEAN SingleLine - ) -{ - while (*String != L'\0') { - if ((*String & 0x7FU) != *String) { - // - // Remove all unicode characters. - // - *String = L'_'; - } else if (SingleLine && (*String == L'\r' || *String == L'\n')) { - // - // Stop after printing one line. - // - *String = L'\0'; - break; - } else if (*String < 0x20 || *String == 0x7F) { - // - // Drop all unprintable spaces but space including tabs. - // - *String = L'_'; - } - - ++String; - } -} - -EFI_STATUS -EFIAPI -OcUnicodeSafeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Marker; - VA_LIST Marker2; - UINTN NumberOfPrinted; - - ASSERT (StartOfBuffer != NULL); - ASSERT (BufferSize > 0); - ASSERT (FormatString != NULL); - - VA_START (Marker, FormatString); - - VA_COPY (Marker2, Marker); - NumberOfPrinted = SPrintLength (FormatString, Marker2); - VA_END (Marker2); - - if (BufferSize - 1 >= NumberOfPrinted) { - UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); - Status = EFI_SUCCESS; - } else { - Status = EFI_OUT_OF_RESOURCES; - } - - VA_END (Marker); - - return Status; -} diff --git a/Library/OcTemplateLib/OcTemplateLib.c b/Library/OcTemplateLib/OcTemplateLib.c deleted file mode 100644 index a5181d9ea..000000000 --- a/Library/OcTemplateLib/OcTemplateLib.c +++ /dev/null @@ -1,323 +0,0 @@ -/** @file - -OcTemplateLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include - -#define PRIV_OC_BLOB_FIELDS(_, __) \ - OC_BLOB (CHAR8, [], {0}, _, __) - OC_DECLARE (PRIV_OC_BLOB) - -#define PRIV_OC_MAP_FIELDS(_, __) \ - OC_MAP (PRIV_OC_BLOB, PRIV_OC_BLOB, _, __) - OC_DECLARE (PRIV_OC_MAP) - -#define PRIV_OC_ARRAY_FIELDS(_, __) \ - OC_ARRAY (PRIV_OC_BLOB, _, __) - OC_DECLARE (PRIV_OC_ARRAY) - -typedef union PRIV_OC_LIST_ { - PRIV_OC_MAP Map; - PRIV_OC_ARRAY Array; -} PRIV_OC_LIST; - -// -// We have to be a bit careful about this hack, so assert that type layouts match at the very least. -// -#if 0 // defined(__GNUC__) || defined(__clang__) -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, Count) == OFFSET_OF (PRIV_OC_MAP, Count), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, AllocCount) == OFFSET_OF (PRIV_OC_MAP, AllocCount), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, Construct) == OFFSET_OF (PRIV_OC_MAP, Construct), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, Destruct) == OFFSET_OF (PRIV_OC_MAP, Destruct), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, Values) == OFFSET_OF (PRIV_OC_MAP, Values), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -STATIC_ASSERT(OFFSET_OF (PRIV_OC_ARRAY, ValueSize) == OFFSET_OF (PRIV_OC_MAP, ValueSize), "PRIV_OC_ARRAY vs PRIV_OC_MAP"); -#endif - -VOID -OcFreePointer ( - VOID *Pointer, - UINT32 Size - ) -{ - VOID **Field = (VOID **) Pointer; - if (*Field) { - FreePool (*Field); - *Field = NULL; - } -} - -VOID -OcZeroField ( - VOID *Pointer, - UINT32 Size - ) -{ - ZeroMem (Pointer, Size); -} - -VOID -OcDestructEmpty ( - VOID *Pointer, - UINT32 Size - ) -{ - (VOID) Pointer; - (VOID) Size; -} - -STATIC -VOID -OcFreeList ( - VOID *Pointer, - BOOLEAN HasKeys - ) -{ - UINT32 Index; - PRIV_OC_LIST *List; - - List = (PRIV_OC_LIST *) Pointer; - - for (Index = 0; Index < List->Array.Count; Index++) { - List->Array.Destruct (List->Array.Values[Index], List->Array.ValueSize); - FreePool (List->Array.Values[Index]); - - if (HasKeys) { - List->Map.KeyDestruct (List->Map.Keys[Index], List->Map.KeySize); - FreePool (List->Map.Keys[Index]); - } - } - - OcFreePointer (&List->Array.Values, List->Array.AllocCount * List->Array.ValueSize); - if (HasKeys) { - OcFreePointer (&List->Map.Keys, List->Array.AllocCount * List->Map.KeySize); - } - - List->Array.Count = 0; - List->Array.AllocCount = 0; -} - -VOID -OcFreeMap ( - VOID *Pointer, - UINT32 Size - ) -{ - OcFreeList (Pointer, TRUE); -} - -VOID -OcFreeArray ( - VOID *Pointer, - UINT32 Size - ) -{ - OcFreeList (Pointer, FALSE); -} - - -VOID * -OcBlobAllocate ( - VOID *Pointer, - UINT32 Size, - UINT32 **OutSize OPTIONAL - ) -{ - PRIV_OC_BLOB *Blob; - VOID *DynValue; - - Blob = (PRIV_OC_BLOB *) Pointer; - - DEBUG ((DEBUG_VERBOSE, "OCTPL: Allocating %u bytes in blob %p with size %u/%u curr %p\n", - Size, Blob, Blob->Size, Blob->MaxSize, Blob->DynValue)); - - // - // We fit into static space - // - if (Size <= Blob->MaxSize) { - OcFreePointer (&Blob->DynValue, Blob->Size); - Blob->Size = Size; - if (OutSize != NULL) { - *OutSize = &Blob->Size; - } - return Blob->Value; - } - - // - // We do not fit into dynamic space - // - if (Size > Blob->Size) { - OcFreePointer (&Blob->DynValue, Blob->Size); - DynValue = AllocatePool (Size); - if (DynValue == NULL) { - DEBUG ((DEBUG_VERBOSE, "OCTPL: Failed to fit %u bytes in OC_BLOB\n", Size)); - return NULL; - } - // - // Propagate default value. - // - CopyMem (DynValue, Blob->Value, Blob->MaxSize); - Blob->DynValue = DynValue; - } - - Blob->Size = Size; - if (OutSize != NULL) { - *OutSize = &Blob->Size; - } - - return Blob->DynValue; -} - -BOOLEAN -OcListEntryAllocate ( - VOID *Pointer, - VOID **Value, - VOID **Key - ) -{ - PRIV_OC_LIST *List; - UINT32 Count; - UINT32 AllocCount; - VOID **NewValues; - VOID **NewKeys; - - List = (PRIV_OC_LIST *) Pointer; - - // - // Prepare new pair. - // - *Value = AllocatePool (List->Array.ValueSize); - if (*Value == NULL) { - return FALSE; - } - - if (Key != NULL) { - *Key = AllocatePool (List->Map.KeySize); - if (*Key == NULL) { - FreePool (*Value); - return FALSE; - } - } - - // - // Initialize new pair. - // - List->Array.Construct (*Value, List->Array.ValueSize); - if (Key != NULL) { - List->Map.KeyConstruct (*Key, List->Map.KeySize); - } - - Count = 0; - AllocCount = 1; - - // - // Push new entry if there is enough room. - // - if (List->Array.Values != NULL) { - Count = List->Array.Count; - AllocCount = List->Array.AllocCount; - - if (AllocCount > Count) { - List->Array.Count++; - List->Array.Values[Count] = *Value; - if (Key != NULL) { - List->Map.Keys[Count] = *Key; - } - return TRUE; - } - } - - // - // Allocate twice more room and destruct on failure. - // - AllocCount *= 2; - - NewValues = (VOID **) AllocatePool ( - sizeof (VOID *) * AllocCount - ); - - if (NewValues == NULL) { - List->Array.Destruct (*Value, List->Array.ValueSize); - FreePool (*Value); - if (Key != NULL) { - List->Map.KeyDestruct (*Key, List->Map.KeySize); - FreePool (*Key); - } - return FALSE; - } - - if (Key != NULL) { - NewKeys = (VOID **) AllocatePool ( - sizeof (VOID *) * AllocCount - ); - - if (NewKeys == NULL) { - List->Array.Destruct (*Value, List->Array.ValueSize); - List->Map.KeyDestruct (*Key, List->Map.KeySize); - FreePool (NewValues); - FreePool (*Value); - FreePool (*Key); - return FALSE; - } - } else { - NewKeys = NULL; - } - - // - // Insert and return. - // - if (List->Array.Values != NULL) { - CopyMem ( - &NewValues[0], - &List->Array.Values[0], - sizeof (VOID *) * Count - ); - - FreePool (List->Array.Values); - } - - if (Key != NULL && List->Map.Keys != NULL) { - CopyMem ( - &NewKeys[0], - &List->Map.Keys[0], - sizeof (VOID *) * Count - ); - - FreePool (List->Map.Keys); - } - - List->Array.Count++; - List->Array.AllocCount = AllocCount; - - NewValues[Count] = *Value; - List->Array.Values = (PRIV_OC_BLOB **) NewValues; - - if (Key != NULL) { - NewKeys[Count] = *Key; - List->Map.Keys = (PRIV_OC_BLOB **) NewKeys; - } - - return TRUE; -} - -OC_BLOB_STRUCTORS (OC_STRING) -OC_BLOB_STRUCTORS (OC_DATA) -OC_MAP_STRUCTORS (OC_ASSOC) diff --git a/Library/OcTemplateLib/OcTemplateLib.inf b/Library/OcTemplateLib/OcTemplateLib.inf deleted file mode 100755 index d868829da..000000000 --- a/Library/OcTemplateLib/OcTemplateLib.inf +++ /dev/null @@ -1,43 +0,0 @@ -## @file -# OcTemplateLib -# -# Copyright (c) 2018, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcTemplateLib - FILE_GUID = E40ABEF1-29B0-4D59-92B1-BF94A3CEB994 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcTemplateLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - OcTemplateLib.c - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryAllocationLib diff --git a/Library/OcXmlLib/OcXmlLib.c b/Library/OcXmlLib/OcXmlLib.c deleted file mode 100755 index f6c178bd8..000000000 --- a/Library/OcXmlLib/OcXmlLib.c +++ /dev/null @@ -1,1738 +0,0 @@ -/** @file - -OcXmlLib - -Copyright (c) 2018, vit9696 - -All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -// -// Copyright (c) 2012 ooxi/xml.c -// https://github.com/ooxi/xml.c -// -// This software is provided 'as-is', without any express or implied warranty. -// In no event will the authors be held liable for any damages arising from the -// use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software in a -// product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#include -#include -#include -#include -#include -#include -#include - -// -// Minimal extra allocation size during export. -// -#define XML_EXPORT_MIN_ALLOCATION_SIZE 4096 - -struct XML_NODE_LIST_; -struct XML_PARSER_; - -typedef struct XML_NODE_LIST_ XML_NODE_LIST; -typedef struct XML_PARSER_ XML_PARSER; - -// -// An XML_NODE will always contain a tag name and possibly a list of -// children or text content. -// -struct XML_NODE_ { - CONST CHAR8 *Name; - CONST CHAR8 *Attributes; - CONST CHAR8 *Content; - XML_NODE *Real; - XML_NODE_LIST *Children; -}; - -struct XML_NODE_LIST_ { - UINT32 NodeCount; - UINT32 AllocCount; - XML_NODE *NodeList[]; -}; - -typedef struct { - UINT32 RefCount; - UINT32 RefAllocCount; - XML_NODE **RefList; -} XML_REFLIST; - -// -// An XML_DOCUMENT simply contains the root node and the underlying buffer. -// -struct XML_DOCUMENT_ { - struct { - CHAR8 *Buffer; - UINT32 Length; - } Buffer; - - XML_NODE *Root; - XML_REFLIST References; -}; - -// -// Parser context. -// -struct XML_PARSER_ { - CHAR8 *Buffer; - UINT32 Position; - UINT32 Length; - UINT32 Level; -}; - -// -// Character offsets. -// -typedef enum XML_PARSER_OFFSET_ { - NO_CHARACTER = -1, - CURRENT_CHARACTER = 0, - NEXT_CHARACTER = 1, -} XML_PARSER_OFFSET; - -// -// Plist node types. -// -CONST CHAR8 * -PlistNodeTypes[PLIST_NODE_TYPE_MAX] = { - NULL, - "array", - "dict", - "key", - "string", - "data", - "date", - "true", - "false", - "real", - "integer" -}; - - -STATIC -BOOLEAN -XmlParseAttributeNumber ( - CONST CHAR8 *Attributes, - CONST CHAR8 *Argument, - UINT32 ArgumentLength, - UINT32 *ArgumentValue - ) -{ - CONST CHAR8 *ArgumentStart; - CONST CHAR8 *ArgumentEnd; - UINTN Number; - CHAR8 NumberStr[16]; - - // - // FIXME: This may give false positives. - // - - ArgumentStart = AsciiStrStr (Attributes, Argument); - if (ArgumentStart == NULL) { - return FALSE; - } - - ArgumentStart += ArgumentLength; - ArgumentEnd = AsciiStrStr (ArgumentStart, "\""); - Number = ArgumentEnd - ArgumentStart; - - if (ArgumentEnd == NULL || Number > sizeof (NumberStr) - 1) { - return FALSE; - } - - CopyMem (&NumberStr, ArgumentStart, Number); - NumberStr[Number] = '\0'; - *ArgumentValue = (UINT32) AsciiStrDecimalToUint64 (NumberStr); - - return TRUE; -} - -// -// Allocates the node with contents. -// -STATIC -XML_NODE * -XmlNodeCreate ( - CONST CHAR8 *Name, - CONST CHAR8 *Attributes, - CONST CHAR8 *Content, - XML_NODE *Real, - XML_NODE_LIST *Children - ) -{ - XML_NODE *Node; - - Node = AllocatePool (sizeof (XML_NODE)); - - if (Node != NULL) { - Node->Name = Name; - Node->Attributes = Attributes; - Node->Content = Content; - Node->Real = Real; - Node->Children = Children; - } - - return Node; -} - -// -// Adds child nodes to node. -// -STATIC -BOOLEAN -XmlNodeChildPush ( - XML_NODE *Node, - XML_NODE *Child - ) -{ - UINT32 NodeCount; - UINT32 AllocCount; - XML_NODE_LIST *NewList; - - NodeCount = 0; - AllocCount = 1; - - // - // Push new node if there is enough room. - // - if (Node->Children != NULL) { - NodeCount = Node->Children->NodeCount; - AllocCount = Node->Children->AllocCount; - - if (NodeCount < XML_PARSER_NODE_COUNT && AllocCount > NodeCount) { - Node->Children->NodeList[NodeCount] = Child; - Node->Children->NodeCount++; - return TRUE; - } - } - - // - // Insertion will exceed the limit. - // - if (NodeCount >= XML_PARSER_NODE_COUNT - 1) { - return FALSE; - } - - // - // Allocate three times more room. - // This balances performance and memory usage on large files like prelinked plist. - // - AllocCount *= 3; - - NewList = (XML_NODE_LIST *) AllocatePool ( - sizeof (XML_NODE_LIST) + sizeof (NewList->NodeList[0]) * AllocCount - ); - - if (NewList == NULL) { - return FALSE; - } - - NewList->NodeCount = NodeCount + 1; - NewList->AllocCount = AllocCount; - - if (Node->Children != NULL) { - CopyMem ( - &NewList->NodeList[0], - &Node->Children->NodeList[0], - sizeof (NewList->NodeList[0]) * NodeCount - ); - - FreePool (Node->Children); - } - - NewList->NodeList[NodeCount] = Child; - Node->Children = NewList; - - return TRUE; -} - -STATIC -BOOLEAN -XmlPushReference ( - XML_REFLIST *References, - XML_NODE *Node, - UINT32 ReferenceNumber - ) -{ - XML_NODE **NewReferences; - UINT32 NewRefAllocCount; - - if (ReferenceNumber >= XML_PARSER_MAX_REFERENCE_COUNT) { - return FALSE; - } - - if (ReferenceNumber >= References->RefAllocCount) { - if (OcOverflowAddMulU32 (ReferenceNumber, 1, 2, &NewRefAllocCount)) { - return FALSE; - } - - NewReferences = AllocateZeroPool (NewRefAllocCount * sizeof (References->RefList[0])); - if (NewReferences == NULL) { - return FALSE; - } - - if (References->RefList != NULL) { - CopyMem ( - &NewReferences[0], - &References->RefList[0], - References->RefCount * sizeof (References->RefList[0]) - ); - FreePool (References->RefList); - } - - References->RefList = NewReferences; - References->RefAllocCount = NewRefAllocCount; - } - - References->RefList[ReferenceNumber] = Node; - if (ReferenceNumber >= References->RefCount) { - References->RefCount = ReferenceNumber + 1; - } - - return TRUE; -} - -STATIC -XML_NODE * -XmlNodeReal ( - XML_REFLIST *References, - CONST CHAR8 *Attributes - ) -{ - BOOLEAN HasArgument; - UINT32 Number; - - if (References == NULL || Attributes == NULL) { - return NULL; - } - - HasArgument = XmlParseAttributeNumber ( - Attributes, - "IDREF=\"", - L_STR_LEN ("IDREF=\""), - &Number - ); - - if (!HasArgument || Number >= References->RefCount) { - return NULL; - } - - return References->RefList[Number]; -} - -// -// Frees the resources allocated by the node. -// -STATIC -VOID -XmlNodeFree ( - XML_NODE *Node - ) -{ - UINT32 Index; - - if (Node->Children != NULL) { - for (Index = 0; Index < Node->Children->NodeCount; ++Index) { - XmlNodeFree (Node->Children->NodeList[Index]); - } - FreePool (Node->Children); - } - - FreePool (Node); -} - -STATIC -VOID -XmlFreeRefs ( - XML_REFLIST *References - ) -{ - if (References->RefList != NULL) { - FreePool (References->RefList); - References->RefList = NULL; - } -} - -// -// Echos the parsers call stack for debugging purposes. -// -#ifdef XML_PARSER_VERBOSE -#define XML_PARSER_INFO(Parser, Message) \ - DEBUG ((DEBUG_VERBOSE, "OCXML: XML_PARSER_INFO %a\n", Message)); -#define XML_PARSER_TAG(Parser, Tag) \ - DEBUG ((DEBUG_VERBOSE, "OCXML: XML_PARSER_TAG %a\n", Tag)); -#else -#define XML_PARSER_INFO(Parser, Message) do {} while (0) -#define XML_PARSER_TAG(Parser, Tag) do {} while (0) -#endif - -// -// Echos an error regarding the parser's source to the console. -// -VOID -XmlParserError ( - XML_PARSER *Parser, - XML_PARSER_OFFSET Offset, - CONST CHAR8 *Message - ) -{ - UINT32 Character = 0; - UINT32 Position; - UINT32 Row = 0; - UINT32 Column = 0; - - if (Parser->Length > 0 && (Parser->Position > 0 || NO_CHARACTER != Offset)) { - Character = Parser->Position + Offset; - if (Character > Parser->Length-1) { - Character = Parser->Length-1; - } - - for (Position = 0; Position <= Character; ++Position) { - Column++; - - if ('\n' == Parser->Buffer[Position]) { - Row++; - Column = 0; - } - } - } - - if (NO_CHARACTER != Offset) { - DEBUG ((DEBUG_INFO, "OCXML: XmlParserError at %u:%u (is %c): %a\n", - Row + 1, Column, Parser->Buffer[Character], Message - )); - } else { - DEBUG ((DEBUG_INFO, "OCXML: XmlParserError at %u:%u: %a\n", - Row + 1, Column, Message - )); - } -} - -// -// Conditionally enable error printing. -// -#ifdef XML_PRINT_ERRORS -#define XML_PARSER_ERROR(Parser, Offset, Message) \ - XmlParserError (Parser, Offset, Message) -#define XML_USAGE_ERROR(Message) \ - DEBUG ((DEBUG_VERBOSE, "OCXML: %a\n", Message)); -#else -#define XML_PARSER_ERROR(Parser, Offset, Message) do {} while (0) -#define XML_USAGE_ERROR(X) do {} while (0) -#endif - -// -// Returns the n-th not-whitespace byte in parser and 0 if such a byte does not -// exist. -// -STATIC -CHAR8 -XmlParserPeek ( - XML_PARSER *Parser, - UINT32 N - ) -{ - UINT32 Position; - - if (!OcOverflowAddU32 (Parser->Position, N, &Position) - && Position < Parser->Length) { - return Parser->Buffer[Position]; - } - - return 0; -} - - -// -// Moves the parser's position n bytes. If the new position would be out of -// bounds, it will be converted to the bounds itself. -// -STATIC -VOID -XmlParserConsume ( - XML_PARSER *Parser, - UINT32 N - ) -{ -#ifdef XML_PARSER_VERBOSE - CHAR8 *Consumed; - CHAR8 *MessageBuffer; - UINT32 Left; - - // - // Debug information. - // - - Consumed = AllocatePool ((N + 1) * sizeof (CHAR8)); - MessageBuffer = AllocatePool (512 * sizeof (CHAR8)); - if (Consumed != NULL && MessageBuffer != NULL) { - Left = N; - if (Left > Parser->Length - Parser->Position) { - Left = Parser->Length - Parser->Position; - } - - CopyMem (Consumed, &Parser->Buffer[Parser->Position], Left); - Consumed[Left] = 0; - - AsciiSPrint (MessageBuffer, 512, "Consuming %u bytes \"%a\"", N, Consumed); - XML_PARSER_INFO (Parser, MessageBuffer); - } - - if (Consumed != NULL) { - FreePool (Consumed); - } - - if (MessageBuffer != NULL) { - FreePool (MessageBuffer); - } -#endif - - // - // Move the position forward. - // - if (OcOverflowAddU32 (Parser->Position, N, &Parser->Position) - || Parser->Position > Parser->Length) { - Parser->Position = Parser->Length; - } -} - -// -// Skips to the next non-whitespace character. -// -STATIC -VOID -XmlSkipWhitespace ( - XML_PARSER *Parser - ) -{ - XML_PARSER_INFO (Parser, "whitespace"); - - while (Parser->Position < Parser->Length - && IsAsciiSpace (Parser->Buffer[Parser->Position])) { - Parser->Position++; - } -} - -// -// Parses the name out of the an XML tag's ending. -// -// ---( Example )--- -// tag_name> -// --- -// -STATIC -CONST CHAR8 * -XmlParseTagEnd ( - XML_PARSER *Parser, - BOOLEAN *SelfClosing, - CONST CHAR8 **Attributes - ) -{ - CHAR8 Current; - UINT32 Start; - UINT32 AttributeStart; - UINT32 Length = 0; - UINT32 NameLength = 0; - - XML_PARSER_INFO (Parser, "tag_end"); - - Current = XmlParserPeek (Parser, CURRENT_CHARACTER); - Start = Parser->Position; - - // - // Parse until `>' or a whitespace is reached. - // - while (Start + Length < Parser->Length) { - if (('/' == Current) || ('>' == Current)) { - break; - } - - if (NameLength == 0 && IsAsciiSpace (Current)) { - NameLength = Length; - - if (NameLength == 0) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseTagEnd::expected tag name"); - return NULL; - } - } - - XmlParserConsume (Parser, 1); - Length++; - - Current = XmlParserPeek (Parser, CURRENT_CHARACTER); - } - - // - // Handle attributes. - // - if (NameLength != 0) { - if (Attributes != NULL && (Current == '/' || Current == '>')) { - *Attributes = &Parser->Buffer[Start + NameLength]; - AttributeStart = NameLength; - while (AttributeStart < Length && IsAsciiSpace (**Attributes)) { - (*Attributes)++; - AttributeStart++; - } - Parser->Buffer[Start + Length] = '\0'; - } - } else { - // - // No attributes besides name. - // - NameLength = Length; - } - - if ('/' == Current) { - if (SelfClosing == NULL) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseTagEnd::unexpected self closing tag"); - return NULL; - } - - *SelfClosing = TRUE; - XmlParserConsume (Parser, 1); - Current = XmlParserPeek (Parser, CURRENT_CHARACTER); - } - - // - // Consume `>'. - // - if ('>' != Current) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseTagEnd::expected tag end"); - return NULL; - } - XmlParserConsume (Parser, 1); - - // - // Return parsed tag name. - // - Parser->Buffer[Start + NameLength] = 0; - XML_PARSER_TAG (Parser, &Parser->Buffer[Start]); - return &Parser->Buffer[Start]; -} - -// -// Parses an opening XML tag without attributes. -// -// ---( Example )--- -// -// --- -// -STATIC -CONST CHAR8 * -XmlParseTagOpen ( - XML_PARSER *Parser, - BOOLEAN *SelfClosing, - CONST CHAR8 **Attributes - ) -{ - CHAR8 Current; - - XML_PARSER_INFO (Parser, "tag_open"); - - do { - XmlSkipWhitespace (Parser); - - // - // Consume `<'. - // - if ('<' != XmlParserPeek (Parser, CURRENT_CHARACTER)) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseTagOpen::expected opening tag"); - return NULL; - } - XmlParserConsume (Parser, 1); - - Current = XmlParserPeek (Parser, CURRENT_CHARACTER); - - // - // This is closing tag, e.g. `', return. - // - if (Current == '/') { - return NULL; - } - - // - // This is not a control sequence, e.g. `', continue parsing tag. - // - if (Current != '?' && Current != '!') { - break; - } - - // - // Skip the control sequence. - // - do { - XmlParserConsume (Parser, 1); - } while (XmlParserPeek (Parser, CURRENT_CHARACTER) != '>' && Parser->Position < Parser->Length); - XmlParserConsume (Parser, 1); - - } while (Parser->Position < Parser->Length); - - // - // Consume tag name. - // - return XmlParseTagEnd (Parser, SelfClosing, Attributes); -} - -// -// Parses an closing XML tag without attributes. -// -// ---( Example )--- -// -// --- -// -STATIC -CONST CHAR8 * -XmlParseTagClose ( - XML_PARSER *Parser, - BOOLEAN Unprefixed - ) -{ - XML_PARSER_INFO (Parser, "tag_close"); - XmlSkipWhitespace (Parser); - - if (Unprefixed) { - // - // Consume `/'. - // - if ('/' != XmlParserPeek (Parser, CURRENT_CHARACTER)) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseTagClose::expected closing tag `/'"); - return NULL; - } - - XmlParserConsume (Parser, 1); - } else { - // - // Consume `Position; - Length = 0; - - // - // Consume until `<' is reached. - // - while (Start + Length < Parser->Length) { - Current = XmlParserPeek (Parser, CURRENT_CHARACTER); - - if ('<' == Current) { - break; - } else { - XmlParserConsume (Parser, 1); - Length++; - } - } - - // - // Next character must be an `<' or we have reached end of file. - // - if ('<' != XmlParserPeek (Parser, CURRENT_CHARACTER)) { - XML_PARSER_ERROR (Parser, CURRENT_CHARACTER, "XmlParseContent::expected <"); - return NULL; - } - - // - // Ignore tailing whitespace. - // - while ((Length > 0) && IsAsciiSpace (Parser->Buffer[Start + Length - 1])) { - Length--; - } - - // - // Return text. - // - Parser->Buffer[Start + Length] = 0; - XmlParserConsume (Parser, 1); - return &Parser->Buffer[Start]; -} - -// -// Prints to growing buffer always preserving one byte extra. -// -STATIC -VOID -XmlBufferAppend ( - CHAR8 **Buffer, - UINT32 *AllocSize, - UINT32 *CurrentSize, - CONST CHAR8 *Data, - UINT32 DataLength - ) -{ - CHAR8 *NewBuffer; - UINT32 NewSize; - - NewSize = *AllocSize; - - if (NewSize - *CurrentSize <= DataLength) { - if (DataLength + 1 <= XML_EXPORT_MIN_ALLOCATION_SIZE) { - NewSize += XML_EXPORT_MIN_ALLOCATION_SIZE; - } else { - NewSize += DataLength + 1; - } - - NewBuffer = AllocatePool (NewSize); - if (NewBuffer == NULL) { - XML_USAGE_ERROR("XmlBufferAppend::failed to allocate"); - return; - } - - CopyMem (NewBuffer, *Buffer, *CurrentSize); - FreePool (*Buffer); - *Buffer = NewBuffer; - *AllocSize = NewSize; - } - - CopyMem (&(*Buffer)[*CurrentSize], Data, DataLength); - *CurrentSize += DataLength; -} - -// -// Prints node to growing buffer always preserving one byte extra. -// -STATIC -VOID -XmlNodeExportRecursive ( - XML_NODE *Node, - CHAR8 **Buffer, - UINT32 *AllocSize, - UINT32 *CurrentSize, - UINT32 Skip - ) -{ - UINT32 Index; - UINT32 NameLength; - - if (Skip != 0) { - if (Node->Children != NULL) { - for (Index = 0; Index < Node->Children->NodeCount; ++Index) { - XmlNodeExportRecursive (Node->Children->NodeList[Index], Buffer, AllocSize, CurrentSize, Skip - 1); - } - } - - return; - } - - NameLength = (UINT32)AsciiStrLen (Node->Name); - - XmlBufferAppend (Buffer, AllocSize, CurrentSize, "<", L_STR_LEN ("<")); - XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Name, NameLength); - - if (Node->Attributes != NULL) { - XmlBufferAppend (Buffer, AllocSize, CurrentSize, " ", L_STR_LEN (" ")); - XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Attributes, (UINT32)AsciiStrLen (Node->Attributes)); - } - - if (Node->Children != NULL || Node->Content != NULL) { - XmlBufferAppend (Buffer, AllocSize, CurrentSize, ">", L_STR_LEN (">")); - - if (Node->Children != NULL) { - for (Index = 0; Index < Node->Children->NodeCount; ++Index) { - XmlNodeExportRecursive (Node->Children->NodeList[Index], Buffer, AllocSize, CurrentSize, 0); - } - } else { - XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Content, (UINT32)AsciiStrLen (Node->Content)); - } - - XmlBufferAppend (Buffer, AllocSize, CurrentSize, "Name, NameLength); - XmlBufferAppend (Buffer, AllocSize, CurrentSize, ">", L_STR_LEN (">")); - } else { - XmlBufferAppend (Buffer, AllocSize, CurrentSize, "/>", L_STR_LEN ("/>")); - } -} - -// -// Parses an XML fragment node. -// -// ---( Example without children )--- -// Text -// --- -// -// ---( Example with children )--- -// -// Text -// Text -// Content -// -// --- -// -STATIC -XML_NODE * -XmlParseNode ( - XML_PARSER *Parser, - XML_REFLIST *References - ) -{ - CONST CHAR8 *TagOpen; - CONST CHAR8 *TagClose; - CONST CHAR8 *Attributes; - XML_NODE *Node; - XML_NODE *Child; - UINT32 ReferenceNumber; - BOOLEAN IsReference; - BOOLEAN SelfClosing; - BOOLEAN Unprefixed; - BOOLEAN HasChildren; - - XML_PARSER_INFO (Parser, "node"); - - Attributes = NULL; - SelfClosing = FALSE; - Unprefixed = FALSE; - IsReference = FALSE; - - // - // Parse open tag. - // - TagOpen = XmlParseTagOpen (Parser, &SelfClosing, &Attributes); - if (TagOpen == NULL) { - if ('/' != XmlParserPeek (Parser, CURRENT_CHARACTER)) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::tag_open"); - } - return NULL; - } - - XmlSkipWhitespace (Parser); - - Node = XmlNodeCreate (TagOpen, Attributes, NULL, XmlNodeReal (References, Attributes), NULL); - if (Node == NULL) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::node alloc fail"); - return NULL; - } - - // - // If tag ends with `/' it's self closing, skip content lookup. - // - if (SelfClosing) { - return Node; - } - - // - // If the content does not start with '<', a text content is assumed. - // - if ('<' != XmlParserPeek (Parser, CURRENT_CHARACTER)) { - Node->Content = XmlParseContent (Parser); - - if (Node->Content == NULL) { - XML_PARSER_ERROR (Parser, 0, "XmlParseNode::content"); - XmlNodeFree (Node); - return NULL; - } - - // - // All references must be defined sequentially. - // - if (References != NULL && Node->Attributes != NULL) { - IsReference = XmlParseAttributeNumber ( - Node->Attributes, - "ID=\"", - L_STR_LEN ("ID=\""), - &ReferenceNumber - ); - } - - Unprefixed = TRUE; - - // - // Otherwise children are to be expected. - // - } else { - Parser->Level++; - - if (Parser->Level > XML_PARSER_NEST_LEVEL) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::level overflow"); - XmlNodeFree (Node); - return NULL; - } - - HasChildren = FALSE; - - while ('/' != XmlParserPeek (Parser, NEXT_CHARACTER)) { - - // - // Parse child node. - // - Child = XmlParseNode (Parser, References); - if (Child == NULL) { - if ('/' == XmlParserPeek (Parser, CURRENT_CHARACTER)) { - XML_PARSER_INFO (Parser, "child_end"); - Unprefixed = TRUE; - break; - } - - XML_PARSER_ERROR (Parser, NEXT_CHARACTER, "XmlParseNode::child"); - XmlNodeFree (Node); - return NULL; - } - - if (!XmlNodeChildPush (Node, Child)) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::node push fail"); - XmlNodeFree (Node); - XmlNodeFree (Child); - return NULL; - } - - HasChildren = TRUE; - } - - Parser->Level--; - - if (!HasChildren && References != NULL && Attributes != NULL) { - IsReference = XmlParseAttributeNumber ( - Node->Attributes, - "ID=\"", - L_STR_LEN ("ID=\""), - &ReferenceNumber - ); - } - } - - // - // Parse close tag. - // - TagClose = XmlParseTagClose (Parser, Unprefixed); - if (TagClose == NULL) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::tag close"); - XmlNodeFree (Node); - return NULL; - } - - // - // Close tag has to match open tag. - // - if (AsciiStrCmp (TagOpen, TagClose) != 0) { - XML_PARSER_ERROR (Parser, NO_CHARACTER, "XmlParseNode::tag missmatch"); - XmlNodeFree (Node); - return NULL; - } - - if (IsReference && !XmlPushReference (References, Node, ReferenceNumber)) { - XML_PARSER_ERROR (Parser, 0, "XmlParseNode::reference"); - XmlNodeFree (Node); - return NULL; - } - - return Node; -} - -XML_DOCUMENT * -XmlDocumentParse ( - CHAR8 *Buffer, - UINT32 Length, - BOOLEAN WithRefs - ) -{ - XML_NODE *Root; - XML_DOCUMENT *Document; - XML_REFLIST References; - - // - // Initialize parser. - // - XML_PARSER Parser; - ZeroMem (&Parser, sizeof (Parser)); - Parser.Buffer = Buffer; - Parser.Length = Length; - ZeroMem (&References, sizeof (References)); - - // - // An empty buffer can never contain a valid document. - // - if (Length == 0 || Length > XML_PARSER_MAX_SIZE) { - XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::length is too small or too large"); - return NULL; - } - - // - // Parse the root node. - // - Root = XmlParseNode (&Parser, WithRefs ? &References : NULL); - if (Root == NULL) { - XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::parsing document failed"); - return NULL; - } - - // - // Return parsed document. - // - Document = AllocatePool (sizeof(XML_DOCUMENT)); - - if (Document == NULL) { - XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::document allocation failed"); - XmlNodeFree (Root); - XmlFreeRefs (&References); - return NULL; - } - - Document->Buffer.Buffer = Buffer; - Document->Buffer.Length = Length; - Document->Root = Root; - CopyMem (&Document->References, &References, sizeof (References)); - - return Document; -} - -CHAR8 * -XmlDocumentExport ( - XML_DOCUMENT *Document, - UINT32 *Length, - UINT32 Skip - ) -{ - CHAR8 *Buffer; - UINT32 AllocSize; - UINT32 CurrentSize; - - AllocSize = Document->Buffer.Length + 1; - Buffer = AllocatePool (AllocSize); - if (Buffer == NULL) { - XML_USAGE_ERROR ("XmlDocumentExport::failed to allocate"); - return NULL; - } - - CurrentSize = 0; - XmlNodeExportRecursive (Document->Root, &Buffer, &AllocSize, &CurrentSize, Skip); - - if (Length != NULL) { - *Length = CurrentSize; - } - - // - // XmlBufferAppend guarantees one more byte. - // - Buffer[CurrentSize] = '\0'; - - return Buffer; -} - -VOID -XmlDocumentFree ( - XML_DOCUMENT *Document - ) -{ - XmlNodeFree (Document->Root); - XmlFreeRefs (&Document->References); - FreePool (Document); -} - -XML_NODE * -XmlDocumentRoot ( - XML_DOCUMENT *Document - ) -{ - return Document->Root; -} - -CONST CHAR8 * -XmlNodeName ( - XML_NODE *Node - ) -{ - return Node->Name; -} - -CONST CHAR8 * -XmlNodeContent ( - XML_NODE *Node - ) -{ - return Node->Real != NULL ? Node->Real->Content : Node->Content; -} - -UINT32 -XmlNodeChildren ( - XML_NODE *Node - ) -{ - return Node->Children ? Node->Children->NodeCount : 0; -} - -XML_NODE * -XmlNodeChild ( - XML_NODE *Node, - UINT32 Child - ) -{ - return Node->Children->NodeList[Child]; -} - -XML_NODE * -EFIAPI -XmlEasyChild ( - XML_NODE *Node, - CONST CHAR8 *ChildName, - ...) -{ - VA_LIST Arguments; - XML_NODE *Next; - XML_NODE *Child; - UINT32 Index; - - VA_START (Arguments, ChildName); - - // - // Descent to current child. - // - while (ChildName != NULL) { - // - // Interate through all children. - // - Next = NULL; - - for (Index = 0; Index < XmlNodeChildren (Node); ++Index) { - Child = XmlNodeChild (Node, Index); - - if (AsciiStrCmp (XmlNodeName (Child), ChildName) != 0) { - if (Next == NULL) { - Next = Child; - } else { - // - // Two children with the same name. - // - VA_END (Arguments); - return NULL; - } - } - } - - // - // No child with that name found. - // - if (Next == NULL) { - VA_END (Arguments); - return NULL; - } - - Node = Next; - - // - // Find name of next child. - // - ChildName = VA_ARG (Arguments, CONST CHAR8*); - } - VA_END (Arguments); - - // - // Return current element. - // - return Node; -} - -XML_NODE * -XmlNodeAppend ( - XML_NODE *Node, - CONST CHAR8 *Name, - CONST CHAR8 *Attributes, - CONST CHAR8 *Content - ) -{ - XML_NODE *NewNode; - - NewNode = XmlNodeCreate (Name, Attributes, Content, NULL, NULL); - if (NewNode == NULL) { - return NULL; - } - - if (!XmlNodeChildPush (Node, NewNode)) { - XmlNodeFree (NewNode); - return NULL; - } - - return NewNode; -} - -XML_NODE * -XmlNodePrepend ( - XML_NODE *Node, - CONST CHAR8 *Name, - CONST CHAR8 *Attributes, - CONST CHAR8 *Content - ) -{ - XML_NODE *NewNode; - - NewNode = XmlNodeAppend (Node, Name, Attributes, Content); - if (NewNode == NULL) { - return NULL; - } - - CopyMem (&Node->Children->NodeList[1], &Node->Children->NodeList[0], (Node->Children->NodeCount - 1) * sizeof (Node->Children->NodeList[0])); - Node->Children->NodeList[0] = NewNode; - - return NewNode; -} - -XML_NODE * -PlistDocumentRoot ( - XML_DOCUMENT *Document - ) -{ - XML_NODE *Node; - - Node = Document->Root; - - if (AsciiStrCmp (XmlNodeName (Node), "plist") != 0) { - XML_USAGE_ERROR ("PlistDocumentRoot::not plist root"); - return NULL; - } - - if (XmlNodeChildren (Node) != 1) { - XML_USAGE_ERROR ("PlistDocumentRoot::no single first node"); - return NULL; - } - - return XmlNodeChild(Node, 0); -} - -XML_NODE * -PlistNodeCast ( - XML_NODE *Node, - PLIST_NODE_TYPE Type - ) -{ - UINT32 ChildrenNum; - - if (Node == NULL || Type == PLIST_NODE_TYPE_ANY) { - return Node; - } - - if (AsciiStrCmp (XmlNodeName (Node), PlistNodeTypes[Type]) != 0) { - // XML_USAGE_ERROR ("PlistNodeType::wrong type"); - return NULL; - } - - ChildrenNum = XmlNodeChildren (Node); - - switch (Type) { - case PLIST_NODE_TYPE_DICT: - if (ChildrenNum % 2 != 0) { - XML_USAGE_ERROR ("PlistNodeType::dict has odd children"); - return NULL; - } - break; - case PLIST_NODE_TYPE_ARRAY: - break; - case PLIST_NODE_TYPE_KEY: - case PLIST_NODE_TYPE_INTEGER: - case PLIST_NODE_TYPE_REAL: - if (XmlNodeContent (Node) == NULL) { - XML_USAGE_ERROR ("PlistNodeType::key or int have no content"); - return NULL; - } - // Fallthrough - default: - // - // Only dictionaries and arrays are allowed to have child nodes. - // - if (ChildrenNum > 0) { - XML_USAGE_ERROR ("PlistNodeType::non dict array has children"); - return NULL; - } - break; - } - - return Node; -} - -UINT32 -PlistDictChildren ( - XML_NODE *Node - ) -{ - return XmlNodeChildren (Node) / 2; -} - -XML_NODE * -PlistDictChild ( - XML_NODE *Node, - UINT32 Child, - XML_NODE **Value OPTIONAL - ) -{ - Child *= 2; - - if (Value != NULL) { - *Value = XmlNodeChild (Node, Child + 1); - } - - return XmlNodeChild (Node, Child); -} - -CONST CHAR8 * -PlistKeyValue ( - XML_NODE *Node - ) -{ - if (PlistNodeCast (Node, PLIST_NODE_TYPE_KEY) == NULL) { - return NULL; - } - - return XmlNodeContent (Node); -} - -BOOLEAN -PlistStringValue ( - XML_NODE *Node, - CHAR8 *Value, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - UINTN Length; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_STRING) == NULL) { - return FALSE; - } - - Content = XmlNodeContent (Node); - if (Content == NULL) { - Value[0] = '\0'; - *Size = 1; - return TRUE; - } - - Length = AsciiStrLen (Content); - if (Length < *Size) { - *Size = (UINT32) (Length + 1); - } - - AsciiStrnCpyS (Value, *Size, Content, Length); - return TRUE; -} - -BOOLEAN -PlistDataValue ( - XML_NODE *Node, - UINT8 *Buffer, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - UINTN Length; - EFI_STATUS Result; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_DATA) == NULL) { - return FALSE; - } - - Content = XmlNodeContent (Node); - if (Content == NULL) { - *Size = 0; - return TRUE; - } - - Length = *Size; - Result = Base64Decode (Content, AsciiStrLen (Content), Buffer, &Length); - - if (!EFI_ERROR (Result) && (UINT32) Length == Length) { - *Size = (UINT32) Length; - return TRUE; - } - - *Size = 0; - return FALSE; -} - -BOOLEAN -PlistBooleanValue ( - XML_NODE *Node, - BOOLEAN *Value - ) -{ - if (PlistNodeCast (Node, PLIST_NODE_TYPE_TRUE) != NULL) { - *Value = TRUE; - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_FALSE) != NULL) { - *Value = FALSE; - return TRUE; - } - - return FALSE; -} - -BOOLEAN -PlistIntegerValue ( - XML_NODE *Node, - VOID *Value, - UINT32 Size, - BOOLEAN Hex - ) -{ - UINT64 Temp; - CONST CHAR8 *TempStr; - BOOLEAN Negate; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_INTEGER) == NULL) { - return FALSE; - } - - TempStr = XmlNodeContent (Node); - - while (*TempStr == ' ' || *TempStr == '\t') { - ++TempStr; - } - - Negate = *TempStr == '-'; - - if (Negate) { - ++TempStr; - } - - if (Hex && TempStr[0] != '0' && TempStr[1] != 'x') { - Hex = FALSE; - } - - if (Hex) { - Temp = AsciiStrHexToUint64 (TempStr); - } else { - Temp = AsciiStrDecimalToUint64 (TempStr); - } - - // - // May produce unexpected results when the value is too large, but just do not care. - // - if (Negate) { - Temp = 0ULL - Temp; - } - - switch (Size) { - case sizeof (UINT64): - *(UINT64 *) Value = Temp; - return TRUE; - case sizeof (UINT32): - *(UINT32 *) Value = (UINT32) Temp; - return TRUE; - case sizeof (UINT16): - *(UINT16 *) Value = (UINT16) Temp; - return TRUE; - case sizeof (UINT8): - *(UINT8 *) Value = (UINT8) Temp; - return TRUE; - default: - return FALSE; - } -} - -BOOLEAN -PlistMetaDataValue ( - XML_NODE *Node, - VOID *Buffer, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - UINTN Length; - EFI_STATUS Result; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_DATA) != NULL) { - Content = XmlNodeContent (Node); - if (Content != NULL) { - - Length = *Size; - Result = Base64Decode (Content, AsciiStrLen (Content), Buffer, &Length); - - if (!EFI_ERROR (Result) && (UINT32) Length == Length) { - *Size = (UINT32) Length; - } else { - return FALSE; - } - } else { - *Size = 0; - } - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_STRING) != NULL) { - Content = XmlNodeContent (Node); - if (Content != NULL) { - Length = AsciiStrLen (Content); - if (Length < *Size) { - *Size = (UINT32) (Length + 1); - } - - AsciiStrnCpyS (Buffer, *Size, Content, Length); - } else { - *(CHAR8 *) Buffer = '\0'; - *Size = 1; - } - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_INTEGER) != NULL) { - *(UINT32 *) Buffer = (UINT32) AsciiStrDecimalToUint64 (XmlNodeContent (Node)); - *Size = sizeof (UINT32); - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_TRUE) != NULL) { - *(UINT8 *) Buffer = 1; - *Size = sizeof (UINT8); - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_FALSE) != NULL) { - *(UINT8 *) Buffer = 0; - *Size = sizeof (UINT8); - return TRUE; - } - - return FALSE; -} - -BOOLEAN -PlistStringSize ( - XML_NODE *Node, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_STRING) == NULL) { - return FALSE; - } - - Content = XmlNodeContent (Node); - if (Content != NULL) { - *Size = (UINT32) AsciiStrLen (Content) + 1; - return TRUE; - } - - *Size = 0; - return TRUE; -} - -BOOLEAN -PlistDataSize ( - XML_NODE *Node, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_DATA) == NULL) { - return FALSE; - } - - Content = XmlNodeContent (Node); - if (Content != NULL) { - *Size = (UINT32) AsciiStrLen (Content); - } else { - *Size = 0; - } - - return TRUE; -} - -BOOLEAN -PlistMetaDataSize ( - XML_NODE *Node, - UINT32 *Size - ) -{ - CONST CHAR8 *Content; - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_DATA) != NULL) { - Content = XmlNodeContent (Node); - if (Content != NULL) { - *Size = (UINT32) AsciiStrLen (Content); - } else { - *Size = 0; - } - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_STRING) != NULL) { - Content = XmlNodeContent (Node); - if (Content != NULL) { - *Size = (UINT32) (AsciiStrLen (Content) + 1); - } else { - *Size = 0; - } - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_INTEGER) != NULL) { - *Size = sizeof (UINT32); - return TRUE; - } - - if (PlistNodeCast (Node, PLIST_NODE_TYPE_TRUE) != NULL - || PlistNodeCast (Node, PLIST_NODE_TYPE_FALSE) != NULL) { - *Size = sizeof (UINT8); - return TRUE; - } - - return FALSE; -} diff --git a/Library/OcXmlLib/OcXmlLib.inf b/Library/OcXmlLib/OcXmlLib.inf deleted file mode 100755 index 51894e183..000000000 --- a/Library/OcXmlLib/OcXmlLib.inf +++ /dev/null @@ -1,46 +0,0 @@ -## @file -# OcXmlLib -# -# Copyright (c) 2018, vit9696 -# -# All rights reserved. -# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcXmlLib - FILE_GUID = 7DDC67E4-0556-4E86-947E-6B484A1B7015 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = OcXmlLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER - - -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - OcXmlLib.c - ../../Include/Library/OcXmlLib.h - -[Packages] - CloverPkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryAllocationLib - OcMiscLib - OcStringLib diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index d642659f9..505afd0b8 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -28,64 +28,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #pragma warning ( disable : 4200 ) #endif -/** - Verifies the storage size of a given data type. - - This macro generates a divide by zero error or a zero size array declaration in - the preprocessor if the size is incorrect. These are declared as "extern" so - the space for these arrays will not be in the modules. - - @param TYPE The date type to determine the size of. - @param Size The expected size for the TYPE. - -**/ -#define VERIFY_SIZE_OF(TYPE, Size) extern UINT8 _VerifySizeof##TYPE[(unsigned char)((sizeof(TYPE) == (Size))) / (unsigned char)((sizeof(TYPE) == (Size)))] - -// -// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with -// Section 2.3.1 of the UEFI 2.3 Specification. -// -VERIFY_SIZE_OF (BOOLEAN, 1); -VERIFY_SIZE_OF (INT8, 1); -VERIFY_SIZE_OF (UINT8, 1); -VERIFY_SIZE_OF (INT16, 2); -VERIFY_SIZE_OF (UINT16, 2); -VERIFY_SIZE_OF (INT32, 4); -VERIFY_SIZE_OF (UINT32, 4); -VERIFY_SIZE_OF (INT64, 8); -VERIFY_SIZE_OF (UINT64, 8); -VERIFY_SIZE_OF (CHAR8, 1); -VERIFY_SIZE_OF (CHAR16, 2); - -// -// The following three enum types are used to verify that the compiler -// configuration for enum types is compliant with Section 2.3.1 of the -// UEFI 2.3 Specification. These enum types and enum values are not -// intended to be used. A prefix of '__' is used avoid conflicts with -// other types. -// -typedef enum { - __VerifyUint8EnumValue = 0xff -} __VERIFY_UINT8_ENUM_SIZE; - -typedef enum { - __VerifyUint16EnumValue = 0xffff -} __VERIFY_UINT16_ENUM_SIZE; - -typedef enum { - __VerifyUint32EnumValue = 0xffffffff -} __VERIFY_UINT32_ENUM_SIZE; - -VERIFY_SIZE_OF (__VERIFY_UINT8_ENUM_SIZE, 4); -VERIFY_SIZE_OF (__VERIFY_UINT16_ENUM_SIZE, 4); -VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4); - // // The Microsoft* C compiler can removed references to unreferenced data items // if the /OPT:REF linker option is used. We defined a macro as this is a // a non standard extension // -#if defined(_MSC_EXTENSIONS) && _MSC_VER < 1800 && !defined (MDE_CPU_EBC) +#if defined(_MSC_VER) && _MSC_VER < 1800 && !defined (MDE_CPU_EBC) /// /// Remove global variable from the linked image if there are no references to /// it after all compiler and linker optimizations have been performed. @@ -247,7 +195,7 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4); /// #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name) -#if __APPLE__ +#ifdef __APPLE__ // // Apple extension that is used by the linker to optimize code size // with assembly functions. Put at the end of your .S files @@ -680,7 +628,7 @@ typedef char* VA_LIST; #define VA_END(Marker) (Marker = (VA_LIST) 0) #define VA_COPY(Dest, Start) ((void)((Dest) = (Start))) -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) #if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) // @@ -840,16 +788,74 @@ typedef UINTN *BASE_LIST; @return Offset, in bytes, of field. **/ -#ifdef __GNUC__ -#if __GNUC__ >= 4 +#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__) #define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field)) #endif -#endif #ifndef OFFSET_OF #define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field)) #endif +/** + Portable definition for compile time assertions. + Equivalent to C11 static_assert macro from assert.h. + + @param Expression Boolean expression. + @param Message Raised compiler diagnostic message when expression is false. + +**/ +#ifdef __cplusplus + #define STATIC_ASSERT(Expression, Message) static_assert(Expression, Message) +#else + #ifdef MDE_CPU_EBC + #define STATIC_ASSERT(Expression, Message) + #elif defined(_MSC_EXTENSIONS) + #define STATIC_ASSERT static_assert + #else + #define STATIC_ASSERT _Static_assert + #endif +#endif + +// +// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with +// Section 2.3.1 of the UEFI 2.3 Specification. +// + +STATIC_ASSERT (sizeof (BOOLEAN) == 1, "sizeof (BOOLEAN) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT8) == 1, "sizeof (INT8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT8) == 1, "sizeof (UINT8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT16) == 2, "sizeof (INT16) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT16) == 2, "sizeof (UINT16) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT32) == 4, "sizeof (INT32) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT32) == 4, "sizeof (UINT32) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT64) == 8, "sizeof (INT64) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT64) == 8, "sizeof (UINT64) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (CHAR8) == 1, "sizeof (CHAR8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (CHAR16) == 2, "sizeof (CHAR16) does not meet UEFI Specification Data Type requirements"); + +// +// The following three enum types are used to verify that the compiler +// configuration for enum types is compliant with Section 2.3.1 of the +// UEFI 2.3 Specification. These enum types and enum values are not +// intended to be used. A prefix of '__' is used avoid conflicts with +// other types. +// +typedef enum { + __VerifyUint8EnumValue = 0xff +} __VERIFY_UINT8_ENUM_SIZE; + +typedef enum { + __VerifyUint16EnumValue = 0xffff +} __VERIFY_UINT16_ENUM_SIZE; + +typedef enum { + __VerifyUint32EnumValue = 0xffffffff +} __VERIFY_UINT32_ENUM_SIZE; + +STATIC_ASSERT (sizeof (__VERIFY_UINT8_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (__VERIFY_UINT16_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (__VERIFY_UINT32_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); + /** Macro that returns a pointer to the data structure that contains a specified field of that data structure. This is a lightweight method to hide information by placing a @@ -1277,7 +1283,7 @@ typedef UINTN RETURN_STATUS; **/ #define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0) -#elif defined(__GNUC__) +#elif defined (__GNUC__) || defined (__clang__) void * __builtin_return_address (unsigned int level); /** Get the return address of the calling function. diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 4df4bf685..98a850a74 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -82,6 +82,26 @@ typedef enum { // If all memory has the same reliability, then this bit is not used. // #define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000ULL + +// +// Note: UEFI spec 2.8 and following: +// +// Specific-purpose memory (SPM). The memory is earmarked for +// specific purposes such as for specific device drivers or applications. +// The SPM attribute serves as a hint to the OS to avoid allocating this +// memory for core OS data or code that can not be relocated. +// +#define EFI_MEMORY_SP 0x0000000000040000ULL +// +// If this flag is set, the memory region is capable of being +// protected with the CPU?s memory cryptographic +// capabilities. If this flag is clear, the memory region is not +// capable of being protected with the CPU?s memory +// cryptographic capabilities or the CPU does not support CPU +// memory cryptographic capabilities. +// +#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000ULL + // // Runtime memory attribute // diff --git a/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf b/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf index 0ce75b2ac..57e2ce6cf 100644 --- a/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +++ b/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf @@ -29,7 +29,7 @@ PcdLib.c [LibraryClasses] - DebugLib +# DebugLib BaseMemoryLib [Packages] diff --git a/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf b/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf index 3a17dc18f..4470bf2f1 100644 --- a/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf +++ b/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf @@ -31,5 +31,5 @@ [LibraryClasses] - DebugLib +# DebugLib diff --git a/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf b/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf index 1d9a8cc1a..2b5df6ecc 100644 --- a/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf +++ b/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf @@ -34,7 +34,7 @@ [LibraryClasses] UefiBootServicesTableLib - DebugLib +# DebugLib BaseLib diff --git a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c index 438c34365..6d9006d9a 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c @@ -14,7 +14,7 @@ #include #include #include -#include +//#include /** Allocates one or more 4KB pages of a certain memory type. diff --git a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf index 4d14a157f..0b8c49b5a 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +++ b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -31,7 +31,7 @@ MdePkg/MdePkg.dec [LibraryClasses] - DebugLib +# DebugLib BaseMemoryLib UefiBootServicesTableLib diff --git a/MemoryFix/AptioMemoryFix/AptioMemoryFix.inf b/MemoryFix/AptioMemoryFix/AptioMemoryFix.inf index 242508eb0..0a744367b 100644 --- a/MemoryFix/AptioMemoryFix/AptioMemoryFix.inf +++ b/MemoryFix/AptioMemoryFix/AptioMemoryFix.inf @@ -23,7 +23,7 @@ MdePkg/MdePkg.dec IntelFrameworkPkg/IntelFrameworkPkg.dec # OcSupportPkg/OcSupportPkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] BaseLib @@ -32,9 +32,9 @@ CpuLib DevicePathLib MemoryAllocationLib - DeviceTreeLib + OcDeviceTreeLib # DevicePathLib - MachoLib + OcMachoLib # OcStringLib UefiBootServicesTableLib UefiDriverEntryPoint diff --git a/MemoryFix/AptioMemoryFix/CustomSlide.c b/MemoryFix/AptioMemoryFix/CustomSlide.c index 2794b1cae..ad012bcc4 100644 --- a/MemoryFix/AptioMemoryFix/CustomSlide.c +++ b/MemoryFix/AptioMemoryFix/CustomSlide.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/MemoryFix/AptioMemoryFix/RtShims.c b/MemoryFix/AptioMemoryFix/RtShims.c index be9ea3b53..86c4d2c33 100644 --- a/MemoryFix/AptioMemoryFix/RtShims.c +++ b/MemoryFix/AptioMemoryFix/RtShims.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include "Config.h" #include "RtShims.h" diff --git a/MemoryFix/OcQuirks/OcQuirks.c b/MemoryFix/OcQuirks/OcQuirks.c deleted file mode 100644 index a0947b2b4..000000000 --- a/MemoryFix/OcQuirks/OcQuirks.c +++ /dev/null @@ -1,212 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define ROOT_PATH L"EFI\\CLOVER" -//#define CONFIG_PATH L"drivers\\UEFI\\OcQuirks.plist" - -#define MAX_DATA_SIZE 10000 -/* -STATIC -OC_SCHEMA -mMmioWhitelistEntry[] = { - OC_SCHEMA_INTEGER_IN ("Address", OC_MMIO_WL_STRUCT, Address), - OC_SCHEMA_STRING_IN ("Comment", OC_MMIO_WL_STRUCT, Comment), - OC_SCHEMA_BOOLEAN_IN ("Enabled", OC_MMIO_WL_STRUCT, Enabled), -}; - -STATIC -OC_SCHEMA -mMmioWhitelist = OC_SCHEMA_DICT (NULL, mMmioWhitelistEntry); - -STATIC -OC_SCHEMA -mConfigNodes[] = { - OC_SCHEMA_BOOLEAN_IN ("AvoidRuntimeDefrag" , OC_QUIRKS, AvoidRuntimeDefrag), - OC_SCHEMA_BOOLEAN_IN ("DevirtualiseMmio" , OC_QUIRKS, DevirtualiseMmio), - OC_SCHEMA_BOOLEAN_IN ("DisableSingleUser" , OC_QUIRKS, DisableSingleUser), - OC_SCHEMA_BOOLEAN_IN ("DisableVariableWrite" , OC_QUIRKS, DisableVariableWrite), - OC_SCHEMA_BOOLEAN_IN ("DiscardHibernateMap" , OC_QUIRKS, DiscardHibernateMap), - OC_SCHEMA_BOOLEAN_IN ("EnableSafeModeSlide" , OC_QUIRKS, EnableSafeModeSlide), - OC_SCHEMA_BOOLEAN_IN ("EnableWriteUnprotector" , OC_QUIRKS, EnableWriteUnprotector), - OC_SCHEMA_BOOLEAN_IN ("ForceExitBootServices" , OC_QUIRKS, ForceExitBootServices), - OC_SCHEMA_ARRAY_IN ("MmioWhitelist" , OC_QUIRKS, MmioWhitelist, &mMmioWhitelist), - OC_SCHEMA_BOOLEAN_IN ("ProtectMemoryRegions" , OC_QUIRKS, ProtectMemoryRegions), - OC_SCHEMA_BOOLEAN_IN ("ProtectSecureBoot" , OC_QUIRKS, ProtectSecureBoot), - OC_SCHEMA_BOOLEAN_IN ("ProtectUefiServices" , OC_QUIRKS, ProtectUefiServices), - OC_SCHEMA_BOOLEAN_IN ("ProvideConsoleGopEnable" , OC_QUIRKS, ProvideConsoleGopEnable), - OC_SCHEMA_BOOLEAN_IN ("ProvideCustomSlide" , OC_QUIRKS, ProvideCustomSlide), - OC_SCHEMA_INTEGER_IN ("ProvideMaxSlide" , OC_QUIRKS, ProvideMaxSlide), - OC_SCHEMA_BOOLEAN_IN ("RebuildAppleMemoryMap" , OC_QUIRKS, RebuildAppleMemoryMap), - OC_SCHEMA_BOOLEAN_IN ("SetupVirtualMap" , OC_QUIRKS, SetupVirtualMap), - OC_SCHEMA_BOOLEAN_IN ("SignalAppleOS" , OC_QUIRKS, SignalAppleOS), - OC_SCHEMA_BOOLEAN_IN ("SyncRuntimePermissions" , OC_QUIRKS, SyncRuntimePermissions) -}; - -STATIC -OC_SCHEMA_INFO -mConfigInfo = { - .Dict = {mConfigNodes, ARRAY_SIZE (mConfigNodes)} -}; - -STATIC -BOOLEAN -QuirksProvideConfig ( - OUT OC_QUIRKS *Config, - IN EFI_HANDLE Handle - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; - OC_STORAGE_CONTEXT Storage; - CHAR8 *ConfigData; - UINT32 ConfigDataSize; - - // Load SimpleFileSystem Protocol - Status = gBS->HandleProtocol ( - Handle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &LoadedImage - ); - - if (EFI_ERROR(Status)) { - return FALSE; - } - - FileSystem = LocateFileSystem ( - LoadedImage->DeviceHandle, - LoadedImage->FilePath - ); - - if (FileSystem == NULL) { - return FALSE; - } - - // Init OcStorage as it already handles - // reading Unicode files - Status = OcStorageInitFromFs ( - &Storage, - FileSystem, - ROOT_PATH, - NULL - ); - - if (EFI_ERROR(Status)) { - return FALSE; - } - - ConfigData = OcStorageReadFileUnicode ( - &Storage, - CONFIG_PATH, - &ConfigDataSize - ); - - // If no config data or greater than max size, fail and use defaults - if (ConfigDataSize == 0 || ConfigDataSize > MAX_DATA_SIZE) { - if (ConfigData != NULL) { - FreePool(ConfigData); - } - - return FALSE; - } - //ConfigData is still XML file content. Now parsing - BOOLEAN Success = ParseSerialized (Config, &mConfigInfo, ConfigData, ConfigDataSize); - - FreePool(ConfigData); - - return Success; -} -*/ -OCQUIRKS_PROTOCOL *mQuirks = NULL; - -EFI_STATUS -EFIAPI -QuirksEntryPoint ( - IN EFI_HANDLE Handle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - OC_ABC_SETTINGS AbcSettings = { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, - FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, NULL, 0, NULL, NULL, NULL, NULL }; - BOOLEAN ProvideConsoleGopEnable = TRUE; - - Status = gBS->LocateProtocol(&gOcQuirksProtocolGuid, NULL, (VOID **)&mQuirks); - -// if not found then use default values -// if (EFI_ERROR(Status)) { -// return Status; -// } -// OC_QUIRKS Config; - -// OC_QUIRKS_CONSTRUCT (&Config, sizeof (Config)); -// QuirksProvideConfig(&Config, Handle); - - if (mQuirks) { - Status = mQuirks->GetConfig(mQuirks, &AbcSettings, &ProvideConsoleGopEnable); - } - if (EFI_ERROR(Status)) { -// OC_QUIRKS_DESTRUCT (&Config, sizeof(Config)); -// return Status; - DEBUG ((DEBUG_INFO, L"config not found, use default")); - } -/* - OC_ABC_SETTINGS AbcSettings = { - - .AvoidRuntimeDefrag = Config.AvoidRuntimeDefrag, - .DevirtualiseMmio = Config.DevirtualiseMmio, - .DisableSingleUser = Config.DisableSingleUser, - .DisableVariableWrite = Config.DisableVariableWrite, - .DiscardHibernateMap = Config.DiscardHibernateMap, - .EnableSafeModeSlide = Config.EnableSafeModeSlide, - .EnableWriteUnprotector = Config.EnableWriteUnprotector, - .ForceExitBootServices = Config.ForceExitBootServices, - .ProtectMemoryRegions = Config.ProtectMemoryRegions, - .ProtectSecureBoot = Config.ProtectSecureBoot, - .ProtectUefiServices = Config.ProtectUefiServices, - .ProvideCustomSlide = Config.ProvideCustomSlide, - .ProvideMaxSlide = Config.ProvideMaxSlide, - .RebuildAppleMemoryMap = Config.RebuildAppleMemoryMap, - .SetupVirtualMap = Config.SetupVirtualMap, - .SignalAppleOS = Config.SignalAppleOS, - .SyncRuntimePermissions = Config.SyncRuntimePermissions - }; - - if (Config.DevirtualiseMmio && Config.MmioWhitelist.Count > 0) { - AbcSettings.MmioWhitelist = AllocatePool ( - Config.MmioWhitelist.Count * sizeof (AbcSettings.MmioWhitelist[0]) - ); - - if (AbcSettings.MmioWhitelist != NULL) { - UINT32 abcIndex = 0; - UINT32 configIndex = 0; - - for (configIndex = 0; configIndex < Config.MmioWhitelist.Count; configIndex++) { - if (Config.MmioWhitelist.Values[configIndex]->Enabled) { - AbcSettings.MmioWhitelist[abcIndex] = Config.MmioWhitelist.Values[configIndex]->Address; - abcIndex++; - } - } - - AbcSettings.MmioWhitelistSize = abcIndex; - } // Else couldn't allocate slots for mmio addresses - } -*/ - if (ProvideConsoleGopEnable) { - OcProvideConsoleGop(TRUE); - } - -// OC_QUIRKS_DESTRUCT (&Config, sizeof (Config)); - - return OcAbcInitialize(&AbcSettings); -} diff --git a/MemoryFix/OcQuirks/OcQuirks.inf b/MemoryFix/OcQuirks/OcQuirks.inf deleted file mode 100644 index 48655d9fd..000000000 --- a/MemoryFix/OcQuirks/OcQuirks.inf +++ /dev/null @@ -1,36 +0,0 @@ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OcQuirks - FILE_GUID = 43C8CFCA-03C0-4AA8-8BEB-5AF6AB3570A2 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = QuirksEntryPoint - -[Packages] - CloverPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec -# OpenCorePkg/OpenCorePkg.dec - -[LibraryClasses] - MemoryAllocationLib - DebugLib - OcAfterBootCompatLib - OcBootManagementLib - MachoLib - OcOSInfoLib -# OcStorageLib - OcConsoleLib -# OcSerializeLib -# OcTemplateLib - UefiBootServicesTableLib - UefiDriverEntryPoint - -[Protocols] - gEfiSimpleFileSystemProtocolGuid - gEfiLoadedImageProtocolGuid - gOcQuirksProtocolGuid - -[Sources] - OcQuirks.c - diff --git a/MemoryFix/OpenRuntime/OpenRuntime.c b/MemoryFix/OpenRuntime/OpenRuntime.c deleted file mode 100644 index fa5f6d29e..000000000 --- a/MemoryFix/OpenRuntime/OpenRuntime.c +++ /dev/null @@ -1,130 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OpenRuntimePrivate.h" - -#include -#include -#include -#include -#include - -#include -#include - -STATIC -VOID -EFIAPI -FwGetCurrent ( - OUT OC_FWRT_CONFIG *Config - ) -{ - CopyMem (Config, gCurrentConfig, sizeof (*Config)); -} - -STATIC -VOID -EFIAPI -FwSetMain ( - IN CONST OC_FWRT_CONFIG *Config - ) -{ - CopyMem (&gMainConfig, Config, sizeof (gMainConfig)); -} - -STATIC -VOID -EFIAPI -FwSetOverride ( - IN CONST OC_FWRT_CONFIG *Config - ) -{ - if (Config != NULL) { - CopyMem (&gOverrideConfig, Config, sizeof (gOverrideConfig)); - gCurrentConfig = &gOverrideConfig; - } else { - gCurrentConfig = &gMainConfig; - } -} - -STATIC -EFI_STATUS -EFIAPI -FwGetExecArea ( - OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - OUT UINTN *Pages - ) -{ - // - // FIXME: This is not accurate, but it does not need to be for now. - // - *BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) FwGetCurrent; - *Pages = 1; - return EFI_SUCCESS; -} - -STATIC -OC_FIRMWARE_RUNTIME_PROTOCOL -mOcFirmwareRuntimeProtocol = { - OC_FIRMWARE_RUNTIME_REVISION, - FwGetCurrent, - FwSetMain, - FwSetOverride, - FwOnGetVariable, - FwGetExecArea -}; - -EFI_STATUS -EFIAPI -UefiEntrypoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - VOID *Interface; - EFI_HANDLE Handle; - - Status = gBS->LocateProtocol ( - &gOcFirmwareRuntimeProtocolGuid, - NULL, - &Interface - ); - - if (!EFI_ERROR(Status)) { - // - // In case for whatever reason one tried to reload the driver. - // - return EFI_ALREADY_STARTED; - } - - // - // Activate main configuration. - // - gCurrentConfig = &gMainConfig; - - RedirectRuntimeServices (); - - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gOcFirmwareRuntimeProtocolGuid, - &mOcFirmwareRuntimeProtocol, - NULL - ); - - ASSERT_EFI_ERROR(Status); - - return EFI_SUCCESS; -} diff --git a/MemoryFix/OpenRuntime/OpenRuntime.inf b/MemoryFix/OpenRuntime/OpenRuntime.inf deleted file mode 100755 index 1e8bb5a9a..000000000 --- a/MemoryFix/OpenRuntime/OpenRuntime.inf +++ /dev/null @@ -1,63 +0,0 @@ -## @file -# UEFI runtime services driver support for OpenCore and others. -# -# Copyright (c) 2019, vit9696. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = OpenRuntime - FILE_GUID = E0BA9DEF-0478-462E-BF46-908EB0EFC7E0 - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = UefiEntrypoint - -[Packages] - CloverPkg.dec -# OpenCorePkg/OpenCorePkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - UefiBootServicesTableLib - UefiDriverEntryPoint - UefiRuntimeServicesTableLib - -[Sources] - UefiRuntimeServices.c - OpenRuntime.c - OpenRuntimePrivate.h - -[Guids] - gEfiGlobalVariableGuid ## CONSUMES - gEfiImageSecurityDatabaseGuid ## CONSUMES - gOcReadOnlyVariableGuid ## CONSUMES - gOcWriteOnlyVariableGuid ## CONSUMES - gOcVendorVariableGuid ## CONSUMES - gEfiAppleBootGuid ## SOMETIMES_CONSUMES - gMicrosoftVariableGuid ## SOMETIMES_CONSUMES - -[Protocols] - gOcFirmwareRuntimeProtocolGuid ## SOMETIMES_PRODUCES - -#[BuildOptions] -# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -# XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 -# XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 -# CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - - -[Depex] - TRUE diff --git a/MemoryFix/OpenRuntime/OpenRuntimePrivate.h b/MemoryFix/OpenRuntime/OpenRuntimePrivate.h deleted file mode 100644 index 0b0a8842b..000000000 --- a/MemoryFix/OpenRuntime/OpenRuntimePrivate.h +++ /dev/null @@ -1,51 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#ifndef OPEN_RUNTIME_PRIVATE_H -#define OPEN_RUNTIME_PRIVATE_H - -#include -#include - -/** - Main runtime services configuration. -**/ -extern OC_FWRT_CONFIG gMainConfig; - -/** - Override runtime services configuration. -**/ -extern OC_FWRT_CONFIG gOverrideConfig; - -/** - Current active runtime services configuration (main or override). -**/ -extern OC_FWRT_CONFIG *gCurrentConfig; - -#define OC_GL_BOOT_OPTION_START 0xF000 - -VOID -RedirectRuntimeServices ( - VOID - ); - -EFI_STATUS -EFIAPI -FwOnGetVariable ( - IN EFI_GET_VARIABLE GetVariable, - OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL - ); - - -#endif // FIRMWARE_RUNTIME_SERVICES_PRIVATE_H diff --git a/MemoryFix/OpenRuntime/UefiRuntimeServices.c b/MemoryFix/OpenRuntime/UefiRuntimeServices.c deleted file mode 100644 index d63db0ab9..000000000 --- a/MemoryFix/OpenRuntime/UefiRuntimeServices.c +++ /dev/null @@ -1,724 +0,0 @@ -/** @file - Copyright (C) 2019, vit9696. All rights reserved. - - All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include "OpenRuntimePrivate.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Runtime accessible variables (all read only). -**/ -STATIC EFI_GET_TIME mStoredGetTime; -STATIC EFI_SET_TIME mStoredSetTime; -STATIC EFI_GET_WAKEUP_TIME mStoredGetWakeupTime; -STATIC EFI_SET_WAKEUP_TIME mStoredSetWakeupTime; -STATIC EFI_GET_VARIABLE mStoredGetVariable; -STATIC EFI_GET_NEXT_VARIABLE_NAME mStoredGetNextVariableName; -STATIC EFI_SET_VARIABLE mStoredSetVariable; -STATIC EFI_GET_NEXT_HIGH_MONO_COUNT mStoredGetNextHighMonotonicCount; -STATIC EFI_RESET_SYSTEM mStoredResetSystem; - -/** - Configurations to use. -**/ -OC_FWRT_CONFIG gMainConfig; -OC_FWRT_CONFIG gOverrideConfig; -OC_FWRT_CONFIG *gCurrentConfig; - -/** - Boot phase accessible variables. -**/ -STATIC EFI_EVENT mTranslateEvent; -STATIC EFI_GET_VARIABLE mCustomGetVariable; -STATIC BOOLEAN mKernelStarted; - -STATIC -VOID -WriteUnprotectorPrologue ( - OUT BOOLEAN *Ints, - OUT BOOLEAN *Wp - ) -{ - IA32_CR0 Cr0; - - if (gCurrentConfig->WriteUnprotector) { - *Ints = SaveAndDisableInterrupts (); - Cr0.UintN = AsmReadCr0 (); - if (Cr0.Bits.WP == 1) { - *Wp = TRUE; - Cr0.Bits.WP = 0; - AsmWriteCr0 (Cr0.UintN); - } else { - *Wp = FALSE; - } - } else { - *Ints = FALSE; - *Wp = FALSE; - } -} - -STATIC -VOID -WriteUnprotectorEpilogue ( - IN BOOLEAN Ints, - IN BOOLEAN Wp - ) -{ - IA32_CR0 Cr0; - - if (gCurrentConfig->WriteUnprotector) { - if (Wp) { - Cr0.UintN = AsmReadCr0 (); - Cr0.Bits.WP = 1; - AsmWriteCr0 (Cr0.UintN); - } - - if (Ints) { - EnableInterrupts (); - } - } -} - -STATIC -BOOLEAN -IsEfiBootVar ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid - ) -{ - if (!CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { - return FALSE; - } - - if (StrnCmp (L"Boot", VariableName, L_STR_LEN (L"Boot")) != 0) { - return FALSE; - } - - return TRUE; -} - -STATIC -BOOLEAN -IsOcBootVar ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid - ) -{ - if (!CompareGuid (VendorGuid, &gOcVendorVariableGuid)) { - return FALSE; - } - - if (StrnCmp (L"Boot", VariableName, L_STR_LEN (L"Boot")) != 0) { - return FALSE; - } - - return TRUE; -} - -STATIC -EFI_STATUS -EFIAPI -WrapGetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredGetTime ( - Time, - Capabilities - ); - - if (!EFI_ERROR(Status)) { - // - // On old AMI firmwares (like the one found in GA-Z87X-UD4H) there is a chance - // of getting 2047 (EFI_UNSPECIFIED_TIMEZONE) from GetTime. This is valid, - // yet is disliked by some software including but not limited to UEFI Shell. - // See the patch: https://lists.01.org/pipermail/edk2-devel/2018-May/024534.html - // As a workaround we make sure this does not happen at all. - // - if (Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) { - Time->TimeZone = 0; - } - } - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapSetTime ( - IN EFI_TIME *Time - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredSetTime ( - Time - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapGetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredGetWakeupTime ( - Enabled, - Pending, - Time - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapSetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredSetWakeupTime ( - Enable, - Time - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapGetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - // - // Perform early checks for speedup. - // - if (VariableName == NULL - || VendorGuid == NULL - || DataSize == NULL - || (Data == NULL && *DataSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // Abort access to write-only variables. - // - if (gCurrentConfig->RestrictedVariables - && mKernelStarted - && CompareGuid (VendorGuid, &gOcWriteOnlyVariableGuid)) { - return EFI_SECURITY_VIOLATION; - } - - // - // Redirect Boot-prefixed variables to our own GUID. - // - if (gCurrentConfig->BootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) { - VendorGuid = &gOcVendorVariableGuid; - } - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = (mCustomGetVariable != NULL ? mCustomGetVariable : mStoredGetVariable) ( - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapGetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN Size; - CHAR16 TempName[256]; - EFI_GUID TempGuid; - BOOLEAN StartBootVar; - BOOLEAN Ints; - BOOLEAN Wp; - - // - // Perform initial checks as per spec. Last check is part of: - // Null-terminator is not found in the first VariableNameSize - // bytes of the input VariableName buffer. - // - if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Checking that VariableName never exceeds *VariableNameSize and is always null-terminated. - // - Size = 0; - for (Index = 0; Index < *VariableNameSize; ++Index) { - if (VariableName[Index] == L'\0') { - Size = (Index + 1) * sizeof (CHAR16); - break; - } - } - - // - // Also assume that too large variables do not exist, as we cannot work with them anyway. - // - if (Size == 0 || Size > sizeof (TempName)) { - return EFI_INVALID_PARAMETER; - } - - WriteUnprotectorPrologue (&Ints, &Wp); - - // - // In case we do not redirect, simply do nothing. - // - if (!gCurrentConfig->BootVariableRedirect) { - Status = mStoredGetNextVariableName (VariableNameSize, VariableName, VendorGuid); - WriteUnprotectorEpilogue (Ints, Wp); - return Status; - } - - // - // Copy vendor and variable name to internal buffer. - // - CopyGuid (&TempGuid, VendorGuid); - StrnCpyS (TempName, ARRAY_SIZE (TempName), VariableName, StrLen (VariableName)); - - StartBootVar = FALSE; - - // - // In case we are not yet iterating EfiBoot variables, - // then go through the whole variable list and return - // variables except EfiBoot. - // - if (!IsEfiBootVar (TempName, &TempGuid)) { - while (TRUE) { - // - // Request for variables. - // - Size = sizeof (TempName); - Status = mStoredGetNextVariableName (&Size, TempName, &TempGuid); - - if (!EFI_ERROR(Status)) { - if (!IsEfiBootVar (TempName, &TempGuid)) { - Size = StrSize (TempName); ///< Not guaranteed to be updated with EFI_SUCCESS. - - if (*VariableNameSize >= Size) { - // - // Return this variable. - // - CopyGuid (VendorGuid, &TempGuid); - StrnCpyS ( - VariableName, - *VariableNameSize / sizeof (CHAR16), - TempName, - StrLen (TempName) - ); - *VariableNameSize = Size; ///< This is NOT explicitly required by the spec. - Status = EFI_SUCCESS; - } else { - // - // Request more space. - // - *VariableNameSize = Size; - Status = EFI_BUFFER_TOO_SMALL; - } - - WriteUnprotectorEpilogue (Ints, Wp); - return Status; - } else { - // - // EfiBoot variables are handled outside of this loop. - // - } - } else if (Status == EFI_BUFFER_TOO_SMALL) { - // - // This means sizeof (TempName) is too small for this system. - // At this step we cannot do anything, but let's replace error - // with something sensible. - // - WriteUnprotectorEpilogue (Ints, Wp); - return EFI_DEVICE_ERROR; - } else if (Status == EFI_NOT_FOUND) { - // - // End of normal variable list. - // This means it is the time for boot variables to be searched - // from the beginning. - // - StartBootVar = TRUE; - break; - } else { - // - // We got EFI_UNSUPPORTED, EFI_DEVICE_ERROR or EFI_INVALID_PARAMETER. - // Return as is. - // - WriteUnprotectorEpilogue (Ints, Wp); - return Status; - } - } - } - - // - // Handle EfiBoot variables now. - // When StartBootVar is TRUE we start from the beginning. - // Otherwise we have boot variable in TempGuid/TempName. - // - - if (StartBootVar) { - // - // It is not required to zero guid, but let's do it just in case. - // - TempName[0] = L'\0'; - ZeroMem (&TempGuid, sizeof (TempGuid)); - } else { - // - // Switch to real GUID as stored in variable storage. - // - CopyGuid (&TempGuid, &gOcVendorVariableGuid); - } - - // - // Find next EfiBoot variable. - // - while (TRUE) { - Size = sizeof (TempName); - Status = mStoredGetNextVariableName (&Size, TempName, &TempGuid); - - if (!EFI_ERROR(Status)) { - if (IsOcBootVar (TempName, &TempGuid)) { - Size = StrSize (TempName); ///< Not guaranteed to be updated with EFI_SUCCESS. - - if (*VariableNameSize >= Size) { - // - // Return this variable. - // - CopyGuid (VendorGuid, &gEfiGlobalVariableGuid); - StrnCpyS ( - VariableName, - *VariableNameSize / sizeof (CHAR16), - TempName, - StrLen (TempName) - ); - *VariableNameSize = Size; ///< This is NOT explicitly required by the spec. - Status = EFI_SUCCESS; - } else { - // - // Request more space. - // - *VariableNameSize = Size; - Status = EFI_BUFFER_TOO_SMALL; - } - - WriteUnprotectorEpilogue (Ints, Wp); - return Status; - } - } else { - // - // This is some error, but let us not care which and just exit cleanly. - // - break; - } - } - - // - // Report this is the end. - // - WriteUnprotectorEpilogue (Ints, Wp); - return EFI_NOT_FOUND; -} - -STATIC -EFI_STATUS -EFIAPI -WrapSetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - // - // Abort access when running with read-only NVRAM. - // - if (gCurrentConfig->WriteProtection && (Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { - return EFI_SECURITY_VIOLATION; - } - - // - // Abort access to read-only variables. - // - if (gCurrentConfig->RestrictedVariables - && mKernelStarted - && CompareGuid (VendorGuid, &gOcReadOnlyVariableGuid)) { - return EFI_SECURITY_VIOLATION; - } - - // - // Abort access to SecureBoot variables. - // - if (gCurrentConfig->ProtectSecureBoot) { - if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { - if (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0 - || StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0) { - return EFI_SECURITY_VIOLATION; - } - } else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) { - if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0 - || StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0 - || StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0 - || StrCmp (VariableName, L"dbr" /* EFI_IMAGE_SECURITY_DATABASE3 */) == 0) { - return EFI_SECURITY_VIOLATION; - } - } else if (CompareGuid (VendorGuid, &gMicrosoftVariableGuid)) { - // - // CurrentActivePolicy, CurrentPolicy, RevocationList, WindowsBootChainSvn, whatever. - // - return EFI_SECURITY_VIOLATION; - } - } - - // - // Redirect Boot-prefixed variables to our own GUID. - // - if (gCurrentConfig->BootVariableRedirect - && IsEfiBootVar (VariableName, VendorGuid)) { - VendorGuid = &gOcVendorVariableGuid; - } - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredSetVariable ( - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -WrapGetNextHighMonotonicCount ( - OUT UINT32 *Count - ) -{ - EFI_STATUS Status; - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - Status = mStoredGetNextHighMonotonicCount ( - Count - ); - - WriteUnprotectorEpilogue (Ints, Wp); - - return Status; -} - -STATIC -VOID -EFIAPI -WrapResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - BOOLEAN Ints; - BOOLEAN Wp; - - WriteUnprotectorPrologue (&Ints, &Wp); - - mStoredResetSystem ( - ResetType, - ResetStatus, - DataSize, - ResetData - ); - - WriteUnprotectorEpilogue (Ints, Wp); -} - -EFI_STATUS -EFIAPI -FwOnGetVariable ( - IN EFI_GET_VARIABLE GetVariable, - OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL - ) -{ - if (mCustomGetVariable != NULL) { - return EFI_ALREADY_STARTED; - } - - mCustomGetVariable = GetVariable; - - if (OrgGetVariable != NULL) { - *OrgGetVariable = mStoredGetVariable; - } - - return EFI_SUCCESS; -} - -STATIC -VOID -EFIAPI -TranslateAddressesHandler ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - gRT->ConvertPointer (0, (VOID **) &mStoredGetTime); - gRT->ConvertPointer (0, (VOID **) &mStoredSetTime); - gRT->ConvertPointer (0, (VOID **) &mStoredGetWakeupTime); - gRT->ConvertPointer (0, (VOID **) &mStoredSetWakeupTime); - gRT->ConvertPointer (0, (VOID **) &mStoredGetVariable); - gRT->ConvertPointer (0, (VOID **) &mStoredGetNextVariableName); - gRT->ConvertPointer (0, (VOID **) &mStoredSetVariable); - gRT->ConvertPointer (0, (VOID **) &mStoredGetNextHighMonotonicCount); - gRT->ConvertPointer (0, (VOID **) &mStoredResetSystem); - - gRT->ConvertPointer (0, (VOID **) &gCurrentConfig); - mCustomGetVariable = NULL; - - // - // Ideally we do that from ExitBootServices, but VirtualAddressChange is fine as well. - // - mKernelStarted = TRUE; -} - -VOID -RedirectRuntimeServices ( - VOID - ) -{ - EFI_STATUS Status; - - mStoredGetTime = gRT->GetTime; - mStoredSetTime = gRT->SetTime; - mStoredGetWakeupTime = gRT->GetWakeupTime; - mStoredSetWakeupTime = gRT->SetWakeupTime; - mStoredGetVariable = gRT->GetVariable; - mStoredGetNextVariableName = gRT->GetNextVariableName; - mStoredSetVariable = gRT->SetVariable; - mStoredGetNextHighMonotonicCount = gRT->GetNextHighMonotonicCount; - mStoredResetSystem = gRT->ResetSystem; - - gRT->GetTime = WrapGetTime; - gRT->SetTime = WrapSetTime; - gRT->GetWakeupTime = WrapGetWakeupTime; - gRT->SetWakeupTime = WrapSetWakeupTime; - gRT->GetVariable = WrapGetVariable; - gRT->GetNextVariableName = WrapGetNextVariableName; - gRT->SetVariable = WrapSetVariable; - gRT->GetNextHighMonotonicCount = WrapGetNextHighMonotonicCount; - gRT->ResetSystem = WrapResetSystem; - - gRT->Hdr.CRC32 = 0; - gBS->CalculateCrc32 (gRT, gRT->Hdr.HeaderSize, &gRT->Hdr.CRC32); - - Status = gBS->CreateEvent ( - EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, - TPL_CALLBACK, - TranslateAddressesHandler, - NULL, - &mTranslateEvent - ); - - ASSERT_EFI_ERROR(Status); -} diff --git a/MemoryFix/OsxAptioFixDrv/BootFixes.c b/MemoryFix/OsxAptioFixDrv/BootFixes.c index 03b7ed6c1..0b87d406b 100644 --- a/MemoryFix/OsxAptioFixDrv/BootFixes.c +++ b/MemoryFix/OsxAptioFixDrv/BootFixes.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "BootFixes.h" #include "AsmFuncs.h" @@ -629,7 +629,7 @@ DevTreeFix(BootArgs *BA) } // get value (Address and Length) - PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DeviceTreeNodeProperty)); + PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DTProperty)); DBG("MM Addr = %x, Len = %x ", PropValue->Address, PropValue->Length); // second check - Address is in our reloc block diff --git a/MemoryFix/OsxAptioFixDrv/BootFixes3.c b/MemoryFix/OsxAptioFixDrv/BootFixes3.c index ec62e875f..32ca8f9e1 100644 --- a/MemoryFix/OsxAptioFixDrv/BootFixes3.c +++ b/MemoryFix/OsxAptioFixDrv/BootFixes3.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "BootFixes3.h" #include "AsmFuncs.h" @@ -798,7 +798,7 @@ DevTreeFix(BootArgs *BA) } // get value (Address and Length) - PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DeviceTreeNodeProperty)); + PropValue = (DTMemMapEntry*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DTProperty)); DBG("MM Addr = %x, Len = %x ", PropValue->Address, PropValue->Length); // second check - Address is in our reloc block diff --git a/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.c b/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.c index 0cc160617..341e495d3 100644 --- a/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.c +++ b/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.c @@ -31,7 +31,7 @@ #include "device_tree.h" #define round_long(x) (((x) + 3UL) & ~(3UL)) -#define next_prop(x) ((DeviceTreeNodeProperty *) (((UINT8*)x) + sizeof(DeviceTreeNodeProperty) + round_long(x->length))) +#define next_prop(x) ((DTProperty *) (((UINT8*)x) + sizeof(DTProperty) + round_long(x->length))) /* Entry*/ @@ -44,13 +44,13 @@ RealDTEntry DTRootNode; RealDTEntry skipProperties(RealDTEntry entry) { - DeviceTreeNodeProperty *prop; + DTProperty *prop; UINTN k; if (entry == NULL || entry->nProperties == 0) { return NULL; } else { - prop = (DeviceTreeNodeProperty *) (entry + 1); + prop = (DTProperty *) (entry + 1); for (k = 0; k < entry->nProperties; k++) { prop = next_prop(prop); } @@ -170,7 +170,7 @@ INTN find_entry(CONST CHAR8 *propName, CONST CHAR8 *propValue, DTEntry *entryH) // Search current entry for (k = 0; k < nodeP->nProperties; ++k) { - DeviceTreeNodeProperty *propP = (DeviceTreeNodeProperty *) (VOID *) startingP; + DTProperty *propP = (DTProperty *) (VOID *) startingP; startingP += sizeof (*propP) + ((propP->length + 3) & -4); @@ -368,17 +368,17 @@ DTRestartEntryIteration(DTEntryIterator iterator) INTN DTGetProperty(CONST DTEntry entry, CONST char *propertyName, VOID **propertyValue, UINTN *propertySize) { - DeviceTreeNodeProperty *prop; + DTProperty *prop; UINTN k; if (entry == NULL || entry->nProperties == 0) { return kError; } else { - prop = (DeviceTreeNodeProperty *) (entry + 1); + prop = (DTProperty *) (entry + 1); for (k = 0; k < entry->nProperties; k++) { if (AsciiStrCmp((CHAR8*)prop->name, (CHAR8*)propertyName) == 0) { *propertyValue = (VOID *) (((UINT8*)prop) - + sizeof(DeviceTreeNodeProperty)); + + sizeof(DTProperty)); *propertySize = prop->length; return kSuccess; } @@ -435,7 +435,7 @@ DTIterateProperties(DTPropertyIterator iterator, CHAR8 **foundProperty) } else { iter->currentIndex++; if (iter->currentIndex == 1) { - iter->currentProperty = (DeviceTreeNodeProperty *) (iter->entry + 1); + iter->currentProperty = (DTProperty *) (iter->entry + 1); } else { iter->currentProperty = next_prop(iter->currentProperty); } diff --git a/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.h b/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.h index 0a3be706f..8c8fb53c2 100644 --- a/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.h +++ b/MemoryFix/OsxAptioFixDrv/FlatDevTree/device_tree.h @@ -83,17 +83,17 @@ Structures for a Flattened Device Tree #define kPropNameLength 32 -typedef struct DeviceTreeNodeProperty { +typedef struct DTProperty { char name[kPropNameLength]; // NUL terminated property name UINT32 length; // Length (bytes) of following prop value // unsigned long value[1]; // Variable length value of property // Padded to a multiple of a longword? -} DeviceTreeNodeProperty; +} DTProperty; typedef struct OpaqueDTEntry { UINT32 nProperties; // Number of props[] elements (0 => end) UINT32 nChildren; // Number of children[] elements -// DeviceTreeNodeProperty props[];// array size == nProperties +// DTProperty props[];// array size == nProperties // DeviceTreeNode children[]; // array size == nChildren } DeviceTreeNode; @@ -118,7 +118,7 @@ typedef struct OpaqueDTEntryIterator { /* Property Iterator*/ typedef struct OpaqueDTPropertyIterator { RealDTEntry entry; - DeviceTreeNodeProperty *currentProperty; + DTProperty *currentProperty; UINT32 currentIndex; } *RealDTPropertyIterator; diff --git a/MemoryFix/OsxAptioFixDrv/Lib.c b/MemoryFix/OsxAptioFixDrv/Lib.c index e0ad4d2b7..affe92143 100644 --- a/MemoryFix/OsxAptioFixDrv/Lib.c +++ b/MemoryFix/OsxAptioFixDrv/Lib.c @@ -14,7 +14,7 @@ #include #include #include -#include +//#include #include #include @@ -94,10 +94,10 @@ EFI_GUID gEfiAppleVendorGuid = {0xAC39C713, 0x7E50, 0x423D, {0x88, 0x9D, 0x2 EFI_GUID gAppleEFINVRAMTRBSecureGuid = {0xF68DA75E, 0x1B55, 0x4E70, {0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA}}; EFI_GUID gDataHubOptionsGuid = {0x0021001C, 0x3CE3, 0x41F8, {0x99, 0xC6, 0xEC, 0xF5, 0xDA, 0x75, 0x47, 0x31}}; EFI_GUID gNotifyMouseActivity = {0xF913C2C2, 0x5351, 0x4FDB, {0x93, 0x44, 0x70, 0xFF, 0xED, 0xB8, 0x42, 0x25}}; -EFI_GUID gEfiDataHubProtocolGuid = {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}; -EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; -EFI_GUID gEfiProcessorSubClassGuid = {0x26fdeb7e, 0xb8af, 0x4ccf, {0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7}}; -EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; +//EFI_GUID gEfiDataHubProtocolGuid = {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}; +//EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; +//EFI_GUID gEfiProcessorSubClassGuid = {0x26fdeb7e, 0xb8af, 0x4ccf, {0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7}}; +//EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; EFI_GUID gMsgLogProtocolGuid = {0x511CE018, 0x0018, 0x4002, {0x20, 0x12, 0x17, 0x38, 0x05, 0x01, 0x02, 0x03}}; EFI_GUID gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}; diff --git a/MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf b/MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf index b5ffc2b6b..ca312ae9c 100644 --- a/MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf +++ b/MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf @@ -30,7 +30,7 @@ BaseLib CpuLib DevicePathLib - DeviceTreeLib + OcDeviceTreeLib [Sources] OsxAptioFix3Drv.c diff --git a/MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf b/MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf index c7c9172fa..8adac772e 100644 --- a/MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf +++ b/MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf @@ -30,7 +30,7 @@ BaseLib CpuLib DevicePathLib - DeviceTreeLib + OcDeviceTreeLib [Sources] OsxAptioFixDrv.c @@ -66,6 +66,7 @@ gEfiFileSystemInfoGuid ## CONSUMES gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES gEfiGlobalVariableGuid + gEfiMiscSubClassGuid [Protocols] gEfiLoadedImageProtocolGuid diff --git a/MemoryFix/OsxLowMemFixDrv/Lib.c b/MemoryFix/OsxLowMemFixDrv/Lib.c index 432dbb4ee..5cc26335d 100644 --- a/MemoryFix/OsxLowMemFixDrv/Lib.c +++ b/MemoryFix/OsxLowMemFixDrv/Lib.c @@ -14,7 +14,7 @@ #include #include #include -#include +//#include #include #include @@ -94,10 +94,10 @@ EFI_GUID gEfiAppleVendorGuid = {0xAC39C713, 0x7E50, 0x423D, {0x88, 0x9D, 0x2 EFI_GUID gAppleEFINVRAMTRBSecureGuid = {0xF68DA75E, 0x1B55, 0x4E70, {0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA}}; EFI_GUID gDataHubOptionsGuid = {0x0021001C, 0x3CE3, 0x41F8, {0x99, 0xC6, 0xEC, 0xF5, 0xDA, 0x75, 0x47, 0x31}}; EFI_GUID gNotifyMouseActivity = {0xF913C2C2, 0x5351, 0x4FDB, {0x93, 0x44, 0x70, 0xFF, 0xED, 0xB8, 0x42, 0x25}}; -EFI_GUID gEfiDataHubProtocolGuid = {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}; -EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; -EFI_GUID gEfiProcessorSubClassGuid = {0x26fdeb7e, 0xb8af, 0x4ccf, {0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7}}; -EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; +//EFI_GUID gEfiDataHubProtocolGuid = {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}; +//EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; +//EFI_GUID gEfiProcessorSubClassGuid = {0x26fdeb7e, 0xb8af, 0x4ccf, {0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7}}; +//EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; EFI_GUID gMsgLogProtocolGuid = {0x511CE018, 0x0018, 0x4002, {0x20, 0x12, 0x17, 0x38, 0x05, 0x01, 0x02, 0x03}}; EFI_GUID gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}; diff --git a/MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf b/MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf index a911b42c4..f1ce7fc48 100644 --- a/MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf +++ b/MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf @@ -46,7 +46,9 @@ gEfiFileInfoGuid ## CONSUMES gEfiFileSystemInfoGuid ## CONSUMES gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES - + gEfiMemorySubClassGuid + gEfiMiscSubClassGuid + [Protocols] gEfiLoadedImageProtocolGuid gEfiDevicePathProtocolGuid diff --git a/OpenCorePkg b/OpenCorePkg new file mode 160000 index 000000000..7c5ebb9e0 --- /dev/null +++ b/OpenCorePkg @@ -0,0 +1 @@ +Subproject commit 7c5ebb9e0118a4fa8b4b60b764078577ef72feb9 diff --git a/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf b/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf index 125e2d93c..ba2e07511 100644 --- a/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf +++ b/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf @@ -27,7 +27,7 @@ [Packages] MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec PcAtChipsetPkg/PcAtChipsetPkg.dec [LibraryClasses] diff --git a/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf b/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf index 2740572cb..b66d7b9df 100644 --- a/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf +++ b/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf @@ -17,7 +17,7 @@ [Packages] MdePkg/MdePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec PcAtChipsetPkg/PcAtChipsetPkg.dec [LibraryClasses] diff --git a/PcAtChipsetPkg/PcAtChipsetPkg.dsc b/PcAtChipsetPkg/PcAtChipsetPkg.dsc index 6f9278add..01a3ee716 100644 --- a/PcAtChipsetPkg/PcAtChipsetPkg.dsc +++ b/PcAtChipsetPkg/PcAtChipsetPkg.dsc @@ -38,7 +38,7 @@ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf - LocalApicLib|CloverEFI/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf diff --git a/Protocols/AppleKeyAggregator/AppleKeyAggregator.c b/Protocols/AppleKeyAggregator/AppleKeyAggregator.c index 016f6acf3..4051c5507 100644 --- a/Protocols/AppleKeyAggregator/AppleKeyAggregator.c +++ b/Protocols/AppleKeyAggregator/AppleKeyAggregator.c @@ -114,7 +114,7 @@ KeyMapCreateKeyStrokesBuffer ( APPLE_KEY_MAP_AGGREGATOR *Aggregator; UINTN BufferSize; - APPLE_KEY *Memory; + APPLE_KEY_CODE *Memory; APPLE_KEY_STROKES_INFO *KeyStrokesInfo; if (!This || !Index) { @@ -135,7 +135,7 @@ KeyMapCreateKeyStrokesBuffer ( if (Memory != NULL) { KeyStrokesInfo = AllocateZeroPool(sizeof (APPLE_KEY_STROKES_INFO) - + (KeyBufferSize * sizeof (APPLE_KEY))); + + (KeyBufferSize * sizeof (APPLE_KEY_CODE))); Status = EFI_OUT_OF_RESOURCES; if (KeyStrokesInfo != NULL) { @@ -194,7 +194,7 @@ KeyMapSetKeyStrokeBufferKeys ( IN UINTN Index, IN APPLE_MODIFIER_MAP Modifiers, IN UINTN NumberOfKeys, - IN APPLE_KEY *Keys + IN APPLE_KEY_CODE *Keys ) { EFI_STATUS Status; @@ -217,7 +217,7 @@ KeyMapSetKeyStrokeBufferKeys ( KeyStrokesInfo->Hdr.NumberOfKeys = NumberOfKeys; KeyStrokesInfo->Hdr.Modifiers = Modifiers; - CopyMem((VOID *)&KeyStrokesInfo->Keys, (VOID *)Keys, (NumberOfKeys * sizeof(APPLE_KEY))); + CopyMem((VOID *)&KeyStrokesInfo->Keys, (VOID *)Keys, (NumberOfKeys * sizeof(APPLE_KEY_CODE))); Status = EFI_SUCCESS; } @@ -232,7 +232,7 @@ EFIAPI ReadKeyState (APPLE_KEY_STATE_PROTOCOL* This, OUT UINT16 *ModifyFlags, OUT UINTN *PressedKeyCount, - OUT APPLE_KEY *Keys) + OUT APPLE_KEY_CODE *Keys) { EFI_STATUS Status; @@ -243,7 +243,7 @@ ReadKeyState (APPLE_KEY_STATE_PROTOCOL* This, UINTN DbNoKeyStrokes; UINTN Index; UINTN Index2; - APPLE_KEY Key; + APPLE_KEY_CODE Key; if (!This || !ModifyFlags || !PressedKeyCount) { return EFI_INVALID_PARAMETER; @@ -301,7 +301,7 @@ ReadKeyState (APPLE_KEY_STATE_PROTOCOL* This, Status = EFI_SUCCESS; if (Keys != NULL) { - CopyMem((VOID *)Keys, (VOID *)Aggregator->KeyBuffer, (DbNoKeyStrokes * sizeof(APPLE_KEY))); + CopyMem((VOID *)Keys, (VOID *)Aggregator->KeyBuffer, (DbNoKeyStrokes * sizeof(APPLE_KEY_CODE))); } return Status; @@ -314,13 +314,13 @@ EFIAPI SearchKeyStroke (APPLE_KEY_STATE_PROTOCOL* This, IN UINT16 ModifyFlags, IN UINTN PressedKeyCount, - IN OUT APPLE_KEY *Keys, + IN OUT APPLE_KEY_CODE *Keys, IN BOOLEAN ExactMatch) { EFI_STATUS Status; UINTN DbNoKeys; - APPLE_KEY DbKeys[DB_KEYS_NUM]; + APPLE_KEY_CODE DbKeys[DB_KEYS_NUM]; APPLE_MODIFIER_MAP DbModifiers; INTN Result; UINTN Index; @@ -344,7 +344,7 @@ SearchKeyStroke (APPLE_KEY_STATE_PROTOCOL* This, KeyMapBubbleSort ((UINT16 *)Keys, PressedKeyCount); KeyMapBubbleSort ((UINT16 *)DbKeys, DbNoKeys); - Result = CompareMem ((VOID *)Keys, (VOID *)DbKeys, (PressedKeyCount * sizeof (APPLE_KEY))); + Result = CompareMem ((VOID *)Keys, (VOID *)DbKeys, (PressedKeyCount * sizeof (APPLE_KEY_CODE))); if (Result == 0) { Status = EFI_SUCCESS; diff --git a/Protocols/AppleKeyAggregator/AppleKeyAggregator.h b/Protocols/AppleKeyAggregator/AppleKeyAggregator.h index a33ce6e67..46e004f45 100644 --- a/Protocols/AppleKeyAggregator/AppleKeyAggregator.h +++ b/Protocols/AppleKeyAggregator/AppleKeyAggregator.h @@ -61,7 +61,7 @@ typedef struct { // APPLE_KEY_STROKES_INFO typedef struct { APPLE_KEY_STROKES_INFO_HDR Hdr; ///< - APPLE_KEY Keys; ///< + APPLE_KEY_CODE Keys; ///< } APPLE_KEY_STROKES_INFO; @@ -69,7 +69,7 @@ typedef struct { typedef struct { UINTN Signature; ///<0 UINTN NextKeyStrokeIndex; ///<0x08 - APPLE_KEY *KeyBuffer; ///<0x10 + APPLE_KEY_CODE *KeyBuffer; ///<0x10 UINTN KeyBuffersSize; ///<0x18 LIST_ENTRY KeyStrokesInfoList; ///<0x20 APPLE_KEY_MAP_DATABASE_PROTOCOL DatabaseProtocol; ///<0x30 size=8*4 diff --git a/Protocols/AppleKeyFeeder/AppleKeyMapUtils.c b/Protocols/AppleKeyFeeder/AppleKeyMapUtils.c index 805607493..3bc747125 100644 --- a/Protocols/AppleKeyFeeder/AppleKeyMapUtils.c +++ b/Protocols/AppleKeyFeeder/AppleKeyMapUtils.c @@ -84,7 +84,7 @@ SendKeyRelease ( EFI_STATUS Status; //DBG("SendKeyRelease\n"); - APPLE_KEY appleKey; // APPLE_KEY is UINT16 + APPLE_KEY_CODE appleKey; // APPLE_KEY_CODE is UINT16 Status = AppleKeyMapDb->SetKeyStrokeBufferKeys ( AppleKeyMapDb, AppleKeyMapDbIndex, @@ -108,7 +108,7 @@ SendKeyRelease ( -static int MapKeyData2AppleKey(EFI_KEY_DATA* KeyData, APPLE_KEY* pKey, UINT8* pCurModifierMap) +static int MapKeyData2AppleKey(EFI_KEY_DATA* KeyData, APPLE_KEY_CODE* pKey, UINT8* pCurModifierMap) { if ( KeyData->Key.UnicodeChar == 0 ) { @@ -306,7 +306,7 @@ SendDataToAppleMap(IN EFI_KEY_DATA *KeyData) EFI_STATUS Status; UINT8 CurModifierMap = 0; UINTN NumberOfKeys = 1; - APPLE_KEY appleKey; // APPLE_KEY is UINT16 + APPLE_KEY_CODE appleKey; // APPLE_KEY_CODE is UINT16 if ( !AppleKeyMapDb ) { Status = getAppleKeyMapDb(); diff --git a/Protocols/AptioInputFix/Keycode/AIKTarget.c b/Protocols/AptioInputFix/Keycode/AIKTarget.c index d4f481590..d4c28c804 100644 --- a/Protocols/AptioInputFix/Keycode/AIKTarget.c +++ b/Protocols/AptioInputFix/Keycode/AIKTarget.c @@ -114,7 +114,7 @@ AIKTargetWriteEntry ( ) { APPLE_MODIFIER_MAP Modifiers; - APPLE_KEY Key; + APPLE_KEY_CODE Key; UINTN Index; UINTN InsertIndex; UINT64 OldestCounter; diff --git a/Protocols/AptioInputFix/Keycode/AIKTarget.h b/Protocols/AptioInputFix/Keycode/AIKTarget.h index 0f8572c25..d83e6dfba 100644 --- a/Protocols/AptioInputFix/Keycode/AIKTarget.h +++ b/Protocols/AptioInputFix/Keycode/AIKTarget.h @@ -68,7 +68,7 @@ typedef struct { // // Previously reported Apple active keys // - APPLE_KEY Keys[AIK_TARGET_BUFFER_SIZE]; + APPLE_KEY_CODE Keys[AIK_TARGET_BUFFER_SIZE]; // // Previously reported Apple key timestamps diff --git a/Protocols/AptioInputFix/Keycode/AIKTranslate.c b/Protocols/AptioInputFix/Keycode/AIKTranslate.c index 735892b5a..1c7a6e16f 100644 --- a/Protocols/AptioInputFix/Keycode/AIKTranslate.c +++ b/Protocols/AptioInputFix/Keycode/AIKTranslate.c @@ -157,7 +157,7 @@ VOID AIKTranslate ( IN AMI_EFI_KEY_DATA *KeyData, OUT APPLE_MODIFIER_MAP *Modifiers, - OUT APPLE_KEY *Key + OUT APPLE_KEY_CODE *Key ) { AIK_PS2KEY_TO_USB Ps2Key; diff --git a/Protocols/AptioInputFix/Keycode/AIKTranslate.h b/Protocols/AptioInputFix/Keycode/AIKTranslate.h index b75aa5ca7..7c7424aef 100644 --- a/Protocols/AptioInputFix/Keycode/AIKTranslate.h +++ b/Protocols/AptioInputFix/Keycode/AIKTranslate.h @@ -127,7 +127,7 @@ VOID AIKTranslate ( IN AMI_EFI_KEY_DATA *KeyData, OUT APPLE_MODIFIER_MAP *Modifiers, - OUT APPLE_KEY *Key + OUT APPLE_KEY_CODE *Key ); #endif diff --git a/Protocols/DataHubDxe/DataHub.c b/Protocols/DataHubDxe/DataHub.c index ac47707d2..1a97f4fa7 100644 --- a/Protocols/DataHubDxe/DataHub.c +++ b/Protocols/DataHubDxe/DataHub.c @@ -14,574 +14,596 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "DataHub.h" +#include + +// now using OpenCore library to avoid multiple definition of functions + + // -// Since this driver will only ever produce one instance of the Logging Hub -// protocol you are not required to dynamically allocate the PrivateData. +//// +//// Since this driver will only ever produce one instance of the Logging Hub +//// protocol you are not required to dynamically allocate the PrivateData. +//// +//DATA_HUB_INSTANCE mPrivateData; // -DATA_HUB_INSTANCE mPrivateData; - -/** - Log data record into the data logging hub - - @param This Protocol instance structure - @param DataRecordGuid GUID that defines record contents - @param ProducerName GUID that defines the name of the producer of the data - @param DataRecordClass Class that defines generic record type - @param RawData Data Log record as defined by DataRecordGuid - @param RawDataSize Size of Data Log data in bytes - - @retval EFI_SUCCESS If data was logged - @retval EFI_OUT_OF_RESOURCES If data was not logged due to lack of system - resources. -**/ -EFI_STATUS -EFIAPI -DataHubLogData ( - IN EFI_DATA_HUB_PROTOCOL *This, - IN EFI_GUID *DataRecordGuid, - IN EFI_GUID *ProducerName, - IN UINT64 DataRecordClass, - IN VOID *RawData, - IN UINT32 RawDataSize - ) -{ - EFI_STATUS Status; - DATA_HUB_INSTANCE *Private; - EFI_DATA_ENTRY *LogEntry; - UINT32 TotalSize; - UINT32 RecordSize; - EFI_DATA_RECORD_HEADER *Record; - VOID *Raw; - DATA_HUB_FILTER_DRIVER *FilterEntry; - LIST_ENTRY *Link; - LIST_ENTRY *Head; - EFI_TIME LogTime; - - Private = DATA_HUB_INSTANCE_FROM_THIS (This); - - // - // Combine the storage for the internal structs and a copy of the log record. - // Record follows PrivateLogEntry. The consumer will be returned a pointer - // to Record so we don't what it to be the thing that was allocated from - // pool, so the consumer can't free an data record by mistake. - // - RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize; - TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize; - - // - // First try to get log time at TPL level <= TPL_CALLBACK. - // - ZeroMem (&LogTime, sizeof (LogTime)); - if (EfiGetCurrentTpl() <= TPL_CALLBACK) { - gRT->GetTime (&LogTime, NULL); - } - - // - // The Logging action is the critical section, so it is locked. - // The MTC asignment & update and logging must be an - // atomic operation, so use the lock. - // - Status = EfiAcquireLockOrFail (&Private->DataLock); - if (EFI_ERROR(Status)) { - // - // Reentrancy detected so exit! - // - return Status; - } - - LogEntry = AllocatePool (TotalSize); - - if (LogEntry == NULL) { - EfiReleaseLock (&Private->DataLock); - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem (LogEntry, TotalSize); - - Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1); - Raw = (VOID *) (Record + 1); - - // - // Build Standard Log Header - // - Record->Version = EFI_DATA_RECORD_HEADER_VERSION; - Record->HeaderSize = (UINT16) sizeof (EFI_DATA_RECORD_HEADER); - Record->RecordSize = RecordSize; - CopyMem(&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID)); - CopyMem(&Record->ProducerName, ProducerName, sizeof (EFI_GUID)); - Record->DataRecordClass = DataRecordClass; - - // - // Ensure LogMonotonicCount is not zero - // - Record->LogMonotonicCount = ++Private->GlobalMonotonicCount; - - CopyMem(&Record->LogTime, &LogTime, sizeof (LogTime)); - - // - // Insert log into the internal linked list. - // - LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE; - LogEntry->Record = Record; - LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize; - InsertTailList (&Private->DataListHead, &LogEntry->Link); - - CopyMem(Raw, RawData, RawDataSize); - - EfiReleaseLock (&Private->DataLock); - - // - // Send Signal to all the filter drivers which are interested - // in the record's class and guid. - // - Head = &Private->FilterDriverListHead; - for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { - FilterEntry = FILTER_ENTRY_FROM_LINK (Link); - if (((FilterEntry->ClassFilter & DataRecordClass) != 0) && - (IsZeroGuid (&FilterEntry->FilterDataRecordGuid) || - CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) { - gBS->SignalEvent (FilterEntry->Event); - } - } - - return EFI_SUCCESS; -} - -/** - Search the Head doubly linked list for the passed in MTC. Return the - matching element in Head and the MTC on the next entry. - - @param Head Head of Data Log linked list. - @param ClassFilter Only match the MTC if it is in the same Class as the - ClassFilter. - @param PtrCurrentMTC On IN contians MTC to search for. On OUT contians next - MTC in the data log list or zero if at end of the list. - - @retval EFI_DATA_LOG_ENTRY Return pointer to data log data from Head list. - @retval NULL If no data record exists. - -**/ -EFI_DATA_RECORD_HEADER * -GetNextDataRecord ( - IN LIST_ENTRY *Head, - IN UINT64 ClassFilter, - IN OUT UINT64 *PtrCurrentMTC - ) - -{ - EFI_DATA_ENTRY *LogEntry; - LIST_ENTRY *Link; - BOOLEAN ReturnFirstEntry; - EFI_DATA_RECORD_HEADER *Record; - EFI_DATA_ENTRY *NextLogEntry; - - // - // If MonotonicCount == 0 just return the first one - // - ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0); - - Record = NULL; - for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { - LogEntry = DATA_ENTRY_FROM_LINK (Link); - if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) { - // - // Skip any entry that does not have the correct ClassFilter - // - continue; - } - - if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) { - // - // Return record to the user - // - Record = LogEntry->Record; - - // - // Calculate the next MTC value. If there is no next entry set - // MTC to zero. - // - *PtrCurrentMTC = 0; - for (Link = GetNextNode(Head, Link); Link != Head; Link = GetNextNode(Head, Link)) { - NextLogEntry = DATA_ENTRY_FROM_LINK (Link); - if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) { - // - // Return the MTC of the next thing to search for if found - // - *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount; - break; - } - } - // - // Record found exit loop and return - // - break; - } - } - - return Record; -} - -/** - Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that - represents Event and return it. - - @param Head Pointer to head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER structures. - @param Event Event to be search for in the Head list. - - @retval EFI_DATA_HUB_FILTER_DRIVER Returned if Event stored in the Head doubly linked list. - @retval NULL If Event is not in the list - -**/ -DATA_HUB_FILTER_DRIVER * -FindFilterDriverByEvent ( - IN LIST_ENTRY *Head, - IN EFI_EVENT Event - ) -{ - DATA_HUB_FILTER_DRIVER *FilterEntry; - LIST_ENTRY *Link; - - for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { - FilterEntry = FILTER_ENTRY_FROM_LINK (Link); - if (FilterEntry->Event == Event) { - return FilterEntry; - } - } - - return NULL; -} - -/** - - Get a previously logged data record and the MonotonicCount for the next - available Record. This allows all records or all records later - than a give MonotonicCount to be returned. If an optional FilterDriverEvent - is passed in with a MonotonicCout of zero return the first record - not yet read by the filter driver. If FilterDriverEvent is NULL and - MonotonicCount is zero return the first data record. - - @param This Pointer to the EFI_DATA_HUB_PROTOCOL instance. - @param MonotonicCount Specifies the Record to return. On input, zero means - return the first record. On output, contains the next - record to available. Zero indicates no more records. - @param FilterDriverEvent If FilterDriverEvent is not passed in a MonotonicCount - of zero, it means to return the first data record. - If FilterDriverEvent is passed in, then a MonotonicCount - of zero means to return the first data not yet read by - FilterDriverEvent. - @param Record Returns a dynamically allocated memory buffer with a data - record that matches MonotonicCount. - - @retval EFI_SUCCESS Data was returned in Record. - @retval EFI_INVALID_PARAMETER FilterDriverEvent was passed in but does not exist. - @retval EFI_NOT_FOUND MonotonicCount does not match any data record in the - system. If a MonotonicCount of zero was passed in, then - no data records exist in the system. - @retval EFI_OUT_OF_RESOURCES Record was not returned due to lack of system resources. - -**/ -EFI_STATUS -EFIAPI -DataHubGetNextRecord ( - IN EFI_DATA_HUB_PROTOCOL *This, - IN OUT UINT64 *MonotonicCount, - IN EFI_EVENT *FilterDriverEvent, OPTIONAL - OUT EFI_DATA_RECORD_HEADER **Record - ) -{ - DATA_HUB_INSTANCE *Private; - DATA_HUB_FILTER_DRIVER *FilterDriver; - UINT64 ClassFilter; - - Private = DATA_HUB_INSTANCE_FROM_THIS (This); - - FilterDriver = NULL; - ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | - EFI_DATA_RECORD_CLASS_ERROR | - EFI_DATA_RECORD_CLASS_DATA | - EFI_DATA_RECORD_CLASS_PROGRESS_CODE; - - // - // If FilterDriverEvent is NULL, then return the next record - // - if (FilterDriverEvent == NULL) { - *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); - if (*Record == NULL) { - return EFI_NOT_FOUND; - } - return EFI_SUCCESS; - } - - // - // For events the beginning is the last unread record. This info is - // stored in the instance structure, so we must look up the event - // to get the data. - // - FilterDriver = FindFilterDriverByEvent ( - &Private->FilterDriverListHead, - *FilterDriverEvent - ); - if (FilterDriver == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Use the Class filter the event was created with. - // - ClassFilter = FilterDriver->ClassFilter; - - // - // Retrieve the next record or the first record. - // - if (*MonotonicCount != 0 || FilterDriver->GetNextMonotonicCount == 0) { - *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); - if (*Record == NULL) { - return EFI_NOT_FOUND; - } - - if (*MonotonicCount != 0) { - // - // If this was not the last record then update the count associated with the filter - // - FilterDriver->GetNextMonotonicCount = *MonotonicCount; - } else { - // - // Save the MonotonicCount of the last record which has been read - // - FilterDriver->GetNextMonotonicCount = (*Record)->LogMonotonicCount; - } - return EFI_SUCCESS; - } - - // - // This is a request to read the first record that has not been read yet. - // Set MonotoicCount to the last record successfuly read - // - *MonotonicCount = FilterDriver->GetNextMonotonicCount; - - // - // Retrieve the last record successfuly read again, but do not return it since - // it has already been returned before. - // - *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); - if (*Record == NULL) { - return EFI_NOT_FOUND; - } - - if (*MonotonicCount != 0) { - // - // Update the count associated with the filter - // - FilterDriver->GetNextMonotonicCount = *MonotonicCount; - - // - // Retrieve the record after the last record successfuly read - // - *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); - if (*Record == NULL) { - return EFI_NOT_FOUND; - } - } - - return EFI_SUCCESS; -} - -/** - This function registers the data hub filter driver that is represented - by FilterEvent. Only one instance of each FilterEvent can be registered. - After the FilterEvent is registered, it will be signaled so it can sync - with data records that have been recorded prior to the FilterEvent being - registered. - - @param This Pointer to The EFI_DATA_HUB_PROTOCOL instance. - @param FilterEvent The EFI_EVENT to signal whenever data that matches - FilterClass is logged in the system. - @param FilterTpl The maximum EFI_TPL at which FilterEvent can be - signaled. It is strongly recommended that you use the - lowest EFI_TPL possible. - @param FilterClass FilterEvent will be signaled whenever a bit in - EFI_DATA_RECORD_HEADER.DataRecordClass is also set in - FilterClass. If FilterClass is zero, no class-based - filtering will be performed. - @param FilterDataRecordGuid FilterEvent will be signaled whenever FilterDataRecordGuid - matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If - FilterDataRecordGuid is NULL, then no GUID-based filtering - will be performed. - - @retval EFI_SUCCESS The filter driver event was registered. - @retval EFI_ALREADY_STARTED FilterEvent was previously registered and cannot be - registered again. - @retval EFI_OUT_OF_RESOURCES The filter driver event was not registered due to lack of - system resources. - -**/ -EFI_STATUS -EFIAPI -DataHubRegisterFilterDriver ( - IN EFI_DATA_HUB_PROTOCOL * This, - IN EFI_EVENT FilterEvent, - IN EFI_TPL FilterTpl, - IN UINT64 FilterClass, - IN EFI_GUID * FilterDataRecordGuid OPTIONAL - ) - -{ - DATA_HUB_INSTANCE *Private; - DATA_HUB_FILTER_DRIVER *FilterDriver; - - Private = DATA_HUB_INSTANCE_FROM_THIS (This); - - FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool(sizeof (DATA_HUB_FILTER_DRIVER)); - if (FilterDriver == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Initialize filter driver info - // - FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE; - FilterDriver->Event = FilterEvent; - FilterDriver->Tpl = FilterTpl; - FilterDriver->GetNextMonotonicCount = 0; - if (FilterClass == 0) { - FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | - EFI_DATA_RECORD_CLASS_ERROR | - EFI_DATA_RECORD_CLASS_DATA | - EFI_DATA_RECORD_CLASS_PROGRESS_CODE; - } else { - FilterDriver->ClassFilter = FilterClass; - } - - if (FilterDataRecordGuid != NULL) { - CopyMem(&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID)); - } - // - // Search for duplicate entries - // - if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) { - FreePool(FilterDriver); - return EFI_ALREADY_STARTED; - } - // - // Make insertion an atomic operation with the lock. - // - EfiAcquireLock (&Private->DataLock); - InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link); - EfiReleaseLock (&Private->DataLock); - - // - // Signal the Filter driver we just loaded so they will recieve all the - // previous history. If we did not signal here we would have to wait until - // the next data was logged to get the history. In a case where no next - // data was logged we would never get synced up. - // - gBS->SignalEvent (FilterEvent); - - return EFI_SUCCESS; -} - -/** - Remove a Filter Driver, so it no longer gets called when data - information is logged. - - @param This Protocol instance structure - - @param FilterEvent Event that represents a filter driver that is to be - Unregistered. - - @retval EFI_SUCCESS If FilterEvent was unregistered - @retval EFI_NOT_FOUND If FilterEvent does not exist -**/ -EFI_STATUS -EFIAPI -DataHubUnregisterFilterDriver ( - IN EFI_DATA_HUB_PROTOCOL *This, - IN EFI_EVENT FilterEvent - ) -{ - DATA_HUB_INSTANCE *Private; - DATA_HUB_FILTER_DRIVER *FilterDriver; - - Private = DATA_HUB_INSTANCE_FROM_THIS (This); - - // - // Search for duplicate entries - // - FilterDriver = FindFilterDriverByEvent ( - &Private->FilterDriverListHead, - FilterEvent - ); - if (FilterDriver == NULL) { - return EFI_NOT_FOUND; - } - // - // Make removal an atomic operation with the lock - // - EfiAcquireLock (&Private->DataLock); - RemoveEntryList (&FilterDriver->Link); - EfiReleaseLock (&Private->DataLock); - - return EFI_SUCCESS; -} - - - -/** - Driver's Entry point routine that install Driver to produce Data Hub protocol. - - @param ImageHandle Module's image handle - @param SystemTable Pointer of EFI_SYSTEM_TABLE - - @retval EFI_SUCCESS Logging Hub protocol installed - @retval Other No protocol installed, unload driver. - -**/ -EFI_STATUS -EFIAPI +///** +// Log data record into the data logging hub +// +// @param This Protocol instance structure +// @param DataRecordGuid GUID that defines record contents +// @param ProducerName GUID that defines the name of the producer of the data +// @param DataRecordClass Class that defines generic record type +// @param RawData Data Log record as defined by DataRecordGuid +// @param RawDataSize Size of Data Log data in bytes +// +// @retval EFI_SUCCESS If data was logged +// @retval EFI_OUT_OF_RESOURCES If data was not logged due to lack of system +// resources. +//**/ +//EFI_STATUS +//EFIAPI +//DataHubLogData ( +// IN EFI_DATA_HUB_PROTOCOL *This, +// IN EFI_GUID *DataRecordGuid, +// IN EFI_GUID *ProducerName, +// IN UINT64 DataRecordClass, +// IN VOID *RawData, +// IN UINT32 RawDataSize +// ) +//{ +// EFI_STATUS Status; +// DATA_HUB_INSTANCE *Private; +// EFI_DATA_ENTRY *LogEntry; +// UINT32 TotalSize; +// UINT32 RecordSize; +// EFI_DATA_RECORD_HEADER *Record; +// VOID *Raw; +// DATA_HUB_FILTER_DRIVER *FilterEntry; +// LIST_ENTRY *Link; +// LIST_ENTRY *Head; +// EFI_TIME LogTime; +// +// Private = DATA_HUB_INSTANCE_FROM_THIS (This); +// +// // +// // Combine the storage for the internal structs and a copy of the log record. +// // Record follows PrivateLogEntry. The consumer will be returned a pointer +// // to Record so we don't what it to be the thing that was allocated from +// // pool, so the consumer can't free an data record by mistake. +// // +// RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize; +// TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize; +// +// // +// // First try to get log time at TPL level <= TPL_CALLBACK. +// // +// ZeroMem (&LogTime, sizeof (LogTime)); +// if (EfiGetCurrentTpl() <= TPL_CALLBACK) { +// gRT->GetTime (&LogTime, NULL); +// } +// +// // +// // The Logging action is the critical section, so it is locked. +// // The MTC asignment & update and logging must be an +// // atomic operation, so use the lock. +// // +// Status = EfiAcquireLockOrFail (&Private->DataLock); +// if (EFI_ERROR(Status)) { +// // +// // Reentrancy detected so exit! +// // +// return Status; +// } +// +// LogEntry = AllocatePool (TotalSize); +// +// if (LogEntry == NULL) { +// EfiReleaseLock (&Private->DataLock); +// return EFI_OUT_OF_RESOURCES; +// } +// +// ZeroMem (LogEntry, TotalSize); +// +// Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1); +// Raw = (VOID *) (Record + 1); +// +// // +// // Build Standard Log Header +// // +// Record->Version = EFI_DATA_RECORD_HEADER_VERSION; +// Record->HeaderSize = (UINT16) sizeof (EFI_DATA_RECORD_HEADER); +// Record->RecordSize = RecordSize; +// CopyMem(&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID)); +// CopyMem(&Record->ProducerName, ProducerName, sizeof (EFI_GUID)); +// Record->DataRecordClass = DataRecordClass; +// +// // +// // Ensure LogMonotonicCount is not zero +// // +// Record->LogMonotonicCount = ++Private->GlobalMonotonicCount; +// +// CopyMem(&Record->LogTime, &LogTime, sizeof (LogTime)); +// +// // +// // Insert log into the internal linked list. +// // +// LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE; +// LogEntry->Record = Record; +// LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize; +// InsertTailList (&Private->DataListHead, &LogEntry->Link); +// +// CopyMem(Raw, RawData, RawDataSize); +// +// EfiReleaseLock (&Private->DataLock); +// +// // +// // Send Signal to all the filter drivers which are interested +// // in the record's class and guid. +// // +// Head = &Private->FilterDriverListHead; +// for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { +// FilterEntry = FILTER_ENTRY_FROM_LINK (Link); +// if (((FilterEntry->ClassFilter & DataRecordClass) != 0) && +// (IsZeroGuid (&FilterEntry->FilterDataRecordGuid) || +// CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) { +// gBS->SignalEvent (FilterEntry->Event); +// } +// } +// +// return EFI_SUCCESS; +//} +// +///** +// Search the Head doubly linked list for the passed in MTC. Return the +// matching element in Head and the MTC on the next entry. +// +// @param Head Head of Data Log linked list. +// @param ClassFilter Only match the MTC if it is in the same Class as the +// ClassFilter. +// @param PtrCurrentMTC On IN contians MTC to search for. On OUT contians next +// MTC in the data log list or zero if at end of the list. +// +// @retval EFI_DATA_LOG_ENTRY Return pointer to data log data from Head list. +// @retval NULL If no data record exists. +// +//**/ +//EFI_DATA_RECORD_HEADER * +//GetNextDataRecord ( +// IN LIST_ENTRY *Head, +// IN UINT64 ClassFilter, +// IN OUT UINT64 *PtrCurrentMTC +// ) +// +//{ +// EFI_DATA_ENTRY *LogEntry; +// LIST_ENTRY *Link; +// BOOLEAN ReturnFirstEntry; +// EFI_DATA_RECORD_HEADER *Record; +// EFI_DATA_ENTRY *NextLogEntry; +// +// // +// // If MonotonicCount == 0 just return the first one +// // +// ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0); +// +// Record = NULL; +// for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { +// LogEntry = DATA_ENTRY_FROM_LINK (Link); +// if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) { +// // +// // Skip any entry that does not have the correct ClassFilter +// // +// continue; +// } +// +// if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) { +// // +// // Return record to the user +// // +// Record = LogEntry->Record; +// +// // +// // Calculate the next MTC value. If there is no next entry set +// // MTC to zero. +// // +// *PtrCurrentMTC = 0; +// for (Link = GetNextNode(Head, Link); Link != Head; Link = GetNextNode(Head, Link)) { +// NextLogEntry = DATA_ENTRY_FROM_LINK (Link); +// if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) { +// // +// // Return the MTC of the next thing to search for if found +// // +// *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount; +// break; +// } +// } +// // +// // Record found exit loop and return +// // +// break; +// } +// } +// +// return Record; +//} +// +///** +// Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that +// represents Event and return it. +// +// @param Head Pointer to head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER structures. +// @param Event Event to be search for in the Head list. +// +// @retval EFI_DATA_HUB_FILTER_DRIVER Returned if Event stored in the Head doubly linked list. +// @retval NULL If Event is not in the list +// +//**/ +//DATA_HUB_FILTER_DRIVER * +//FindFilterDriverByEvent ( +// IN LIST_ENTRY *Head, +// IN EFI_EVENT Event +// ) +//{ +// DATA_HUB_FILTER_DRIVER *FilterEntry; +// LIST_ENTRY *Link; +// +// for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { +// FilterEntry = FILTER_ENTRY_FROM_LINK (Link); +// if (FilterEntry->Event == Event) { +// return FilterEntry; +// } +// } +// +// return NULL; +//} +// +///** +// +// Get a previously logged data record and the MonotonicCount for the next +// available Record. This allows all records or all records later +// than a give MonotonicCount to be returned. If an optional FilterDriverEvent +// is passed in with a MonotonicCout of zero return the first record +// not yet read by the filter driver. If FilterDriverEvent is NULL and +// MonotonicCount is zero return the first data record. +// +// @param This Pointer to the EFI_DATA_HUB_PROTOCOL instance. +// @param MonotonicCount Specifies the Record to return. On input, zero means +// return the first record. On output, contains the next +// record to available. Zero indicates no more records. +// @param FilterDriverEvent If FilterDriverEvent is not passed in a MonotonicCount +// of zero, it means to return the first data record. +// If FilterDriverEvent is passed in, then a MonotonicCount +// of zero means to return the first data not yet read by +// FilterDriverEvent. +// @param Record Returns a dynamically allocated memory buffer with a data +// record that matches MonotonicCount. +// +// @retval EFI_SUCCESS Data was returned in Record. +// @retval EFI_INVALID_PARAMETER FilterDriverEvent was passed in but does not exist. +// @retval EFI_NOT_FOUND MonotonicCount does not match any data record in the +// system. If a MonotonicCount of zero was passed in, then +// no data records exist in the system. +// @retval EFI_OUT_OF_RESOURCES Record was not returned due to lack of system resources. +// +//**/ +//EFI_STATUS +//EFIAPI +//DataHubGetNextRecord ( +// IN EFI_DATA_HUB_PROTOCOL *This, +// IN OUT UINT64 *MonotonicCount, +// IN EFI_EVENT *FilterDriverEvent, OPTIONAL +// OUT EFI_DATA_RECORD_HEADER **Record +// ) +//{ +// DATA_HUB_INSTANCE *Private; +// DATA_HUB_FILTER_DRIVER *FilterDriver; +// UINT64 ClassFilter; +// +// Private = DATA_HUB_INSTANCE_FROM_THIS (This); +// +// FilterDriver = NULL; +// ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | +// EFI_DATA_RECORD_CLASS_ERROR | +// EFI_DATA_RECORD_CLASS_DATA | +// EFI_DATA_RECORD_CLASS_PROGRESS_CODE; +// +// // +// // If FilterDriverEvent is NULL, then return the next record +// // +// if (FilterDriverEvent == NULL) { +// *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); +// if (*Record == NULL) { +// return EFI_NOT_FOUND; +// } +// return EFI_SUCCESS; +// } +// +// // +// // For events the beginning is the last unread record. This info is +// // stored in the instance structure, so we must look up the event +// // to get the data. +// // +// FilterDriver = FindFilterDriverByEvent ( +// &Private->FilterDriverListHead, +// *FilterDriverEvent +// ); +// if (FilterDriver == NULL) { +// return EFI_INVALID_PARAMETER; +// } +// // +// // Use the Class filter the event was created with. +// // +// ClassFilter = FilterDriver->ClassFilter; +// +// // +// // Retrieve the next record or the first record. +// // +// if (*MonotonicCount != 0 || FilterDriver->GetNextMonotonicCount == 0) { +// *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); +// if (*Record == NULL) { +// return EFI_NOT_FOUND; +// } +// +// if (*MonotonicCount != 0) { +// // +// // If this was not the last record then update the count associated with the filter +// // +// FilterDriver->GetNextMonotonicCount = *MonotonicCount; +// } else { +// // +// // Save the MonotonicCount of the last record which has been read +// // +// FilterDriver->GetNextMonotonicCount = (*Record)->LogMonotonicCount; +// } +// return EFI_SUCCESS; +// } +// +// // +// // This is a request to read the first record that has not been read yet. +// // Set MonotoicCount to the last record successfuly read +// // +// *MonotonicCount = FilterDriver->GetNextMonotonicCount; +// +// // +// // Retrieve the last record successfuly read again, but do not return it since +// // it has already been returned before. +// // +// *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); +// if (*Record == NULL) { +// return EFI_NOT_FOUND; +// } +// +// if (*MonotonicCount != 0) { +// // +// // Update the count associated with the filter +// // +// FilterDriver->GetNextMonotonicCount = *MonotonicCount; +// +// // +// // Retrieve the record after the last record successfuly read +// // +// *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); +// if (*Record == NULL) { +// return EFI_NOT_FOUND; +// } +// } +// +// return EFI_SUCCESS; +//} +// +///** +// This function registers the data hub filter driver that is represented +// by FilterEvent. Only one instance of each FilterEvent can be registered. +// After the FilterEvent is registered, it will be signaled so it can sync +// with data records that have been recorded prior to the FilterEvent being +// registered. +// +// @param This Pointer to The EFI_DATA_HUB_PROTOCOL instance. +// @param FilterEvent The EFI_EVENT to signal whenever data that matches +// FilterClass is logged in the system. +// @param FilterTpl The maximum EFI_TPL at which FilterEvent can be +// signaled. It is strongly recommended that you use the +// lowest EFI_TPL possible. +// @param FilterClass FilterEvent will be signaled whenever a bit in +// EFI_DATA_RECORD_HEADER.DataRecordClass is also set in +// FilterClass. If FilterClass is zero, no class-based +// filtering will be performed. +// @param FilterDataRecordGuid FilterEvent will be signaled whenever FilterDataRecordGuid +// matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If +// FilterDataRecordGuid is NULL, then no GUID-based filtering +// will be performed. +// +// @retval EFI_SUCCESS The filter driver event was registered. +// @retval EFI_ALREADY_STARTED FilterEvent was previously registered and cannot be +// registered again. +// @retval EFI_OUT_OF_RESOURCES The filter driver event was not registered due to lack of +// system resources. +// +//**/ +//EFI_STATUS +//EFIAPI +//DataHubRegisterFilterDriver ( +// IN EFI_DATA_HUB_PROTOCOL * This, +// IN EFI_EVENT FilterEvent, +// IN EFI_TPL FilterTpl, +// IN UINT64 FilterClass, +// IN EFI_GUID * FilterDataRecordGuid OPTIONAL +// ) +// +//{ +// DATA_HUB_INSTANCE *Private; +// DATA_HUB_FILTER_DRIVER *FilterDriver; +// +// Private = DATA_HUB_INSTANCE_FROM_THIS (This); +// +// FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool(sizeof (DATA_HUB_FILTER_DRIVER)); +// if (FilterDriver == NULL) { +// return EFI_OUT_OF_RESOURCES; +// } +// // +// // Initialize filter driver info +// // +// FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE; +// FilterDriver->Event = FilterEvent; +// FilterDriver->Tpl = FilterTpl; +// FilterDriver->GetNextMonotonicCount = 0; +// if (FilterClass == 0) { +// FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | +// EFI_DATA_RECORD_CLASS_ERROR | +// EFI_DATA_RECORD_CLASS_DATA | +// EFI_DATA_RECORD_CLASS_PROGRESS_CODE; +// } else { +// FilterDriver->ClassFilter = FilterClass; +// } +// +// if (FilterDataRecordGuid != NULL) { +// CopyMem(&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID)); +// } +// // +// // Search for duplicate entries +// // +// if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) { +// FreePool(FilterDriver); +// return EFI_ALREADY_STARTED; +// } +// // +// // Make insertion an atomic operation with the lock. +// // +// EfiAcquireLock (&Private->DataLock); +// InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link); +// EfiReleaseLock (&Private->DataLock); +// +// // +// // Signal the Filter driver we just loaded so they will recieve all the +// // previous history. If we did not signal here we would have to wait until +// // the next data was logged to get the history. In a case where no next +// // data was logged we would never get synced up. +// // +// gBS->SignalEvent (FilterEvent); +// +// return EFI_SUCCESS; +//} +// +///** +// Remove a Filter Driver, so it no longer gets called when data +// information is logged. +// +// @param This Protocol instance structure +// +// @param FilterEvent Event that represents a filter driver that is to be +// Unregistered. +// +// @retval EFI_SUCCESS If FilterEvent was unregistered +// @retval EFI_NOT_FOUND If FilterEvent does not exist +//**/ +//EFI_STATUS +//EFIAPI +//DataHubUnregisterFilterDriver ( +// IN EFI_DATA_HUB_PROTOCOL *This, +// IN EFI_EVENT FilterEvent +// ) +//{ +// DATA_HUB_INSTANCE *Private; +// DATA_HUB_FILTER_DRIVER *FilterDriver; +// +// Private = DATA_HUB_INSTANCE_FROM_THIS (This); +// +// // +// // Search for duplicate entries +// // +// FilterDriver = FindFilterDriverByEvent ( +// &Private->FilterDriverListHead, +// FilterEvent +// ); +// if (FilterDriver == NULL) { +// return EFI_NOT_FOUND; +// } +// // +// // Make removal an atomic operation with the lock +// // +// EfiAcquireLock (&Private->DataLock); +// RemoveEntryList (&FilterDriver->Link); +// EfiReleaseLock (&Private->DataLock); +// +// return EFI_SUCCESS; +//} +// +// +// +///** +// Driver's Entry point routine that install Driver to produce Data Hub protocol. +// +// @param ImageHandle Module's image handle +// @param SystemTable Pointer of EFI_SYSTEM_TABLE +// +// @retval EFI_SUCCESS Logging Hub protocol installed +// @retval Other No protocol installed, unload driver. +// +//**/ +//EFI_STATUS +//EFIAPI +//DataHubInstall ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +//{ +// EFI_STATUS Status; +// UINT32 HighMontonicCount; +// +// mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE; +// mPrivateData.DataHub.LogData = DataHubLogData; +// mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord; +// mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver; +// mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver; +// +// // +// // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is +// // required by this protocol +// // +// InitializeListHead (&mPrivateData.DataListHead); +// InitializeListHead (&mPrivateData.FilterDriverListHead); +// +// EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY); +// +// // +// // Make sure we get a bigger MTC number on every boot! +// // +// Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount); +// if (EFI_ERROR(Status)) { +// // +// // if system service fails pick a sane value. +// // +// mPrivateData.GlobalMonotonicCount = 0; +// } else { +// mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32); +// } +// // +// // Make a new handle and install the protocol +// // +// mPrivateData.Handle = NULL; +// Status = gBS->InstallProtocolInterface ( +// &mPrivateData.Handle, +// &gEfiDataHubProtocolGuid, +// EFI_NATIVE_INTERFACE, +// &mPrivateData.DataHub +// ); +// return Status; +//} + +EFI_DATA_HUB_PROTOCOL * DataHubInstall ( + VOID + ); + +EFI_STATUS +EFIAPI +CloverDataHubInstall ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - UINT32 HighMontonicCount; - - mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE; - mPrivateData.DataHub.LogData = DataHubLogData; - mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord; - mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver; - mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver; - - // - // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is - // required by this protocol - // - InitializeListHead (&mPrivateData.DataListHead); - InitializeListHead (&mPrivateData.FilterDriverListHead); - - EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY); - - // - // Make sure we get a bigger MTC number on every boot! - // - Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount); - if (EFI_ERROR(Status)) { - // - // if system service fails pick a sane value. - // - mPrivateData.GlobalMonotonicCount = 0; - } else { - mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32); - } - // - // Make a new handle and install the protocol - // - mPrivateData.Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &mPrivateData.Handle, - &gEfiDataHubProtocolGuid, - EFI_NATIVE_INTERFACE, - &mPrivateData.DataHub - ); - return Status; + if ( DataHubInstall() != EFI_SUCCESS) return EFI_NOT_FOUND; + return EFI_SUCCESS; } diff --git a/Protocols/DataHubDxe/DataHub.h b/Protocols/DataHubDxe/DataHub.h index 7770c438d..11c98ac46 100644 --- a/Protocols/DataHubDxe/DataHub.h +++ b/Protocols/DataHubDxe/DataHub.h @@ -13,117 +13,121 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#ifndef _DATA_HUB_H_ -#define _DATA_HUB_H_ +#ifndef _CLOVER_DATA_HUB_H_ +#define _CLOVER_DATA_HUB_H_ +// now using OpenCore library to avoid multiple definition of functions -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DATA_HUB_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', 'u', 'b') -typedef struct { - UINT32 Signature; - - EFI_HANDLE Handle; - - // - // Produced protocol(s) - // - EFI_DATA_HUB_PROTOCOL DataHub; - - // - // Private Data - // - // - // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead - // must be locked. - // - EFI_LOCK DataLock; - - // - // Runing Monotonic Count to use for each error record. - // Increment AFTER use in an error record. - // - UINT64 GlobalMonotonicCount; - - // - // List of EFI_DATA_ENTRY structures. This is the data log! The list - // must be in assending order of LogMonotonicCount. - // - LIST_ENTRY DataListHead; - - // - // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all - // the registered filter drivers. - // - LIST_ENTRY FilterDriverListHead; - -} DATA_HUB_INSTANCE; - -#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE) +#include "../../OpenCorePkg/Library/OcDataHubLib/DataHub.h" // -// Private data structure to contain the data log. One record per -// structure. Head pointer to the list is the Log member of -// EFI_DATA_ENTRY. Record is a copy of the data passed in. +//#include // -#define EFI_DATA_ENTRY_SIGNATURE SIGNATURE_32 ('D', 'r', 'e', 'c') -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - EFI_DATA_RECORD_HEADER *Record; - - UINTN RecordSize; - -} EFI_DATA_ENTRY; - -#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE) - +//#include // -// Private data to contain the filter driver Event and it's -// associated EFI_TPL. +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include // -#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE SIGNATURE_32 ('D', 'h', 'F', 'd') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - // - // Store Filter Driver Event and Tpl level it can be Signaled at. - // - EFI_EVENT Event; - EFI_TPL Tpl; - - // - // Monotonic count on the get next operation for Event. - // Zero indicates get next has not been called for this event yet. - // - UINT64 GetNextMonotonicCount; - - // - // Filter driver will register what class filter should be used. - // - UINT64 ClassFilter; - - // - // Filter driver will register what record guid filter should be used. - // - EFI_GUID FilterDataRecordGuid; - -} DATA_HUB_FILTER_DRIVER; - -#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE) +//#define DATA_HUB_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', 'u', 'b') +//typedef struct { +// UINT32 Signature; +// +// EFI_HANDLE Handle; +// +// // +// // Produced protocol(s) +// // +// EFI_DATA_HUB_PROTOCOL DataHub; +// +// // +// // Private Data +// // +// // +// // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead +// // must be locked. +// // +// EFI_LOCK DataLock; +// +// // +// // Runing Monotonic Count to use for each error record. +// // Increment AFTER use in an error record. +// // +// UINT64 GlobalMonotonicCount; +// +// // +// // List of EFI_DATA_ENTRY structures. This is the data log! The list +// // must be in assending order of LogMonotonicCount. +// // +// LIST_ENTRY DataListHead; +// +// // +// // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all +// // the registered filter drivers. +// // +// LIST_ENTRY FilterDriverListHead; +// +//} DATA_HUB_INSTANCE; +// +//#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE) +// +//// +//// Private data structure to contain the data log. One record per +//// structure. Head pointer to the list is the Log member of +//// EFI_DATA_ENTRY. Record is a copy of the data passed in. +//// +//#define EFI_DATA_ENTRY_SIGNATURE SIGNATURE_32 ('D', 'r', 'e', 'c') +//typedef struct { +// UINT32 Signature; +// LIST_ENTRY Link; +// +// EFI_DATA_RECORD_HEADER *Record; +// +// UINTN RecordSize; +// +//} EFI_DATA_ENTRY; +// +//#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE) +// +//// +//// Private data to contain the filter driver Event and it's +//// associated EFI_TPL. +//// +//#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE SIGNATURE_32 ('D', 'h', 'F', 'd') +// +//typedef struct { +// UINT32 Signature; +// LIST_ENTRY Link; +// +// // +// // Store Filter Driver Event and Tpl level it can be Signaled at. +// // +// EFI_EVENT Event; +// EFI_TPL Tpl; +// +// // +// // Monotonic count on the get next operation for Event. +// // Zero indicates get next has not been called for this event yet. +// // +// UINT64 GetNextMonotonicCount; +// +// // +// // Filter driver will register what class filter should be used. +// // +// UINT64 ClassFilter; +// +// // +// // Filter driver will register what record guid filter should be used. +// // +// EFI_GUID FilterDataRecordGuid; +// +//} DATA_HUB_FILTER_DRIVER; +// +//#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE) #endif diff --git a/Protocols/DataHubDxe/DataHubDxe.inf b/Protocols/DataHubDxe/DataHubDxe.inf index d2c6b04f2..67d7ea759 100644 --- a/Protocols/DataHubDxe/DataHubDxe.inf +++ b/Protocols/DataHubDxe/DataHubDxe.inf @@ -40,7 +40,7 @@ FILE_GUID = 53BCC14F-C24F-434C-B294-8ED2D4CC1860 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - ENTRY_POINT = DataHubInstall + ENTRY_POINT = CloverDataHubInstall # # The following information is for reference only and not required by the build tools. @@ -67,7 +67,7 @@ BaseLib UefiLib UefiDriverEntryPoint - DebugLib + #OcDataHubLib [Protocols] diff --git a/Protocols/DumpUefiCalls/AppleProtocols.c b/Protocols/DumpUefiCalls/AppleProtocols.c index 0b214e7cd..df07a22f7 100644 --- a/Protocols/DumpUefiCalls/AppleProtocols.c +++ b/Protocols/DumpUefiCalls/AppleProtocols.c @@ -396,7 +396,7 @@ EFIAPI OvrReadKeyState (IN APPLE_KEY_STATE_PROTOCOL *This, OUT UINT16 *ModifyFlags, OUT UINTN *PressedKeyStatesCount, - OUT APPLE_KEY *PressedKeyStates) + OUT APPLE_KEY_CODE *PressedKeyStates) { EFI_STATUS Status; @@ -417,7 +417,7 @@ EFIAPI OvrSearchKeyStroke (APPLE_KEY_STATE_PROTOCOL* This, IN UINT16 ModifyFlags, IN UINTN PressedKeyStatesCount, - IN OUT APPLE_KEY *PressedKeyStates, + IN OUT APPLE_KEY_CODE *PressedKeyStates, IN BOOLEAN ExactMatch) { EFI_STATUS Status; @@ -745,7 +745,7 @@ OvrSetKeyStrokeBufferKeys ( IN UINTN Index, IN APPLE_MODIFIER_MAP Modifiers, IN UINTN NumberOfKeys, - IN APPLE_KEY *Keys + IN APPLE_KEY_CODE *Keys ) { EFI_STATUS Status; diff --git a/Protocols/DumpUefiCalls/Lib.c b/Protocols/DumpUefiCalls/Lib.c index 8d682fd03..34fb0be9f 100644 --- a/Protocols/DumpUefiCalls/Lib.c +++ b/Protocols/DumpUefiCalls/Lib.c @@ -14,7 +14,7 @@ #include #include #include -#include +//#include #include #include diff --git a/UefiCpuPkg/Application/Cpuid/Cpuid.c b/UefiCpuPkg/Application/Cpuid/Cpuid.c new file mode 100644 index 000000000..cee64f2fb --- /dev/null +++ b/UefiCpuPkg/Application/Cpuid/Cpuid.c @@ -0,0 +1,1612 @@ +/** @file + UEFI Application to display CPUID leaf information. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +/// +/// Macro used to display the value of a bit field in a register returned by CPUID. +/// +#define PRINT_BIT_FIELD(Variable, FieldName) \ + Print (L"%5a%42a: %x\n", #Variable, #FieldName, Variable.Bits.FieldName); + +/// +/// Macro used to display the value of a register returned by CPUID. +/// +#define PRINT_VALUE(Variable, Description) \ + Print (L"%5a%42a: %x\n", #Variable, #Description, Variable); + +/// +/// Structure for cache description lookup table +/// +typedef struct { + UINT8 CacheDescriptor; + CHAR8 *Type; + CHAR8 *Description; +} CPUID_CACHE_INFO_DESCRIPTION; + +/// +/// Cache description lookup table +/// +CPUID_CACHE_INFO_DESCRIPTION mCpuidCacheInfoDescription[] = { + { 0x00 , "General" , "Null descriptor, this byte contains no information" }, + { 0x01 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries" }, + { 0x02 , "TLB" , "Instruction TLB: 4 MByte pages, fully associative, 2 entries" }, + { 0x03 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 64 entries" }, + { 0x04 , "TLB" , "Data TLB: 4 MByte pages, 4-way set associative, 8 entries" }, + { 0x05 , "TLB" , "Data TLB1: 4 MByte pages, 4-way set associative, 32 entries" }, + { 0x06 , "Cache" , "1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size" }, + { 0x08 , "Cache" , "1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size" }, + { 0x09 , "Cache" , "1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size" }, + { 0x0A , "Cache" , "1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size" }, + { 0x0B , "TLB" , "Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries" }, + { 0x0C , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size" }, + { 0x0D , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size" }, + { 0x0E , "Cache" , "1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size" }, + { 0x1D , "Cache" , "2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size" }, + { 0x21 , "Cache" , "2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size" }, + { 0x22 , "Cache" , "3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x23 , "Cache" , "3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x24 , "Cache" , "2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size" }, + { 0x25 , "Cache" , "3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x29 , "Cache" , "3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x2C , "Cache" , "1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size" }, + { 0x30 , "Cache" , "1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size" }, + { 0x40 , "Cache" , "No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" }, + { 0x41 , "Cache" , "2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size" }, + { 0x42 , "Cache" , "2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size" }, + { 0x43 , "Cache" , "2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size" }, + { 0x44 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size" }, + { 0x45 , "Cache" , "2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size" }, + { 0x46 , "Cache" , "3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size" }, + { 0x47 , "Cache" , "3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size" }, + { 0x48 , "Cache" , "2nd-level cache: 3MByte, 12-way set associative, 64 byte line size" }, + { 0x49 , "Cache" , "3rd-level cache: 4MB, 16-way set associative, 64-byte line size (Intel Xeon processor MP, Family 0FH, Model 06H). 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size" }, + { 0x4A , "Cache" , "3rd-level cache: 6MByte, 12-way set associative, 64 byte line size" }, + { 0x4B , "Cache" , "3rd-level cache: 8MByte, 16-way set associative, 64 byte line size" }, + { 0x4C , "Cache" , "3rd-level cache: 12MByte, 12-way set associative, 64 byte line size" }, + { 0x4D , "Cache" , "3rd-level cache: 16MByte, 16-way set associative, 64 byte line size" }, + { 0x4E , "Cache" , "2nd-level cache: 6MByte, 24-way set associative, 64 byte line size" }, + { 0x4F , "TLB" , "Instruction TLB: 4 KByte pages, 32 entries" }, + { 0x50 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries" }, + { 0x51 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries" }, + { 0x52 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries" }, + { 0x55 , "TLB" , "Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries" }, + { 0x56 , "TLB" , "Data TLB0: 4 MByte pages, 4-way set associative, 16 entries" }, + { 0x57 , "TLB" , "Data TLB0: 4 KByte pages, 4-way associative, 16 entries" }, + { 0x59 , "TLB" , "Data TLB0: 4 KByte pages, fully associative, 16 entries" }, + { 0x5A , "TLB" , "Data TLB0: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries" }, + { 0x5B , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 64 entries" }, + { 0x5C , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,128 entries" }, + { 0x5D , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,256 entries" }, + { 0x60 , "Cache" , "1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size" }, + { 0x61 , "TLB" , "Instruction TLB: 4 KByte pages, fully associative, 48 entries" }, + { 0x63 , "TLB" , "Data TLB: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries and a separate array with 1 GByte pages, 4-way set associative, 4 entries" }, + { 0x64 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 512 entries" }, + { 0x66 , "Cache" , "1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size" }, + { 0x67 , "Cache" , "1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size" }, + { 0x68 , "Cache" , "1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size" }, + { 0x6A , "Cache" , "uTLB: 4 KByte pages, 8-way set associative, 64 entries" }, + { 0x6B , "Cache" , "DTLB: 4 KByte pages, 8-way set associative, 256 entries" }, + { 0x6C , "Cache" , "DTLB: 2M/4M pages, 8-way set associative, 128 entries" }, + { 0x6D , "Cache" , "DTLB: 1 GByte pages, fully associative, 16 entries" }, + { 0x70 , "Cache" , "Trace cache: 12 K-uop, 8-way set associative" }, + { 0x71 , "Cache" , "Trace cache: 16 K-uop, 8-way set associative" }, + { 0x72 , "Cache" , "Trace cache: 32 K-uop, 8-way set associative" }, + { 0x76 , "TLB" , "Instruction TLB: 2M/4M pages, fully associative, 8 entries" }, + { 0x78 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 64byte line size" }, + { 0x79 , "Cache" , "2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x7A , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x7B , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x7C , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, + { 0x7D , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 64byte line size" }, + { 0x7F , "Cache" , "2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size" }, + { 0x80 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size" }, + { 0x82 , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size" }, + { 0x83 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size" }, + { 0x84 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size" }, + { 0x85 , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size" }, + { 0x86 , "Cache" , "2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, + { 0x87 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, + { 0xA0 , "DTLB" , "DTLB: 4k pages, fully associative, 32 entries" }, + { 0xB0 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries" }, + { 0xB1 , "TLB" , "Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries" }, + { 0xB2 , "TLB" , "Instruction TLB: 4KByte pages, 4-way set associative, 64 entries" }, + { 0xB3 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 128 entries" }, + { 0xB4 , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 256 entries" }, + { 0xB5 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 64 entries" }, + { 0xB6 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 128 entries" }, + { 0xBA , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 64 entries" }, + { 0xC0 , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries" }, + { 0xC1 , "STLB" , "Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries" }, + { 0xC2 , "DTLB" , "DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries" }, + { 0xC3 , "STLB" , "Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, 1536 entries. Also 1GBbyte pages, 4-way, 16 entries." }, + { 0xC4 , "DTLB" , "DTLB: 2M/4M Byte pages, 4-way associative, 32 entries" }, + { 0xCA , "STLB" , "Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries" }, + { 0xD0 , "Cache" , "3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, + { 0xD1 , "Cache" , "3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size" }, + { 0xD2 , "Cache" , "3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size" }, + { 0xD6 , "Cache" , "3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, + { 0xD7 , "Cache" , "3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size" }, + { 0xD8 , "Cache" , "3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size" }, + { 0xDC , "Cache" , "3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size" }, + { 0xDD , "Cache" , "3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size" }, + { 0xDE , "Cache" , "3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size" }, + { 0xE2 , "Cache" , "3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size" }, + { 0xE3 , "Cache" , "3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size" }, + { 0xE4 , "Cache" , "3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size" }, + { 0xEA , "Cache" , "3rd-level cache: 12MByte, 24-way set associative, 64 byte line size" }, + { 0xEB , "Cache" , "3rd-level cache: 18MByte, 24-way set associative, 64 byte line size" }, + { 0xEC , "Cache" , "3rd-level cache: 24MByte, 24-way set associative, 64 byte line size" }, + { 0xF0 , "Prefetch" , "64-Byte prefetching" }, + { 0xF1 , "Prefetch" , "128-Byte prefetching" }, + { 0xFE , "General" , "CPUID leaf 2 does not report TLB descriptor information; use CPUID leaf 18H to query TLB and other address translation parameters." }, + { 0xFF , "General" , "CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters" } +}; + +/// +/// The maximum supported CPUID leaf index starting from leaf 0x00000000. +/// +UINT32 gMaximumBasicFunction = CPUID_SIGNATURE; + +/// +/// The maximum supported CPUID leaf index starting from leaf 0x80000000. +/// +UINT32 gMaximumExtendedFunction = CPUID_EXTENDED_FUNCTION; + +/** + Display CPUID_SIGNATURE leaf. + +**/ +VOID +CpuidSignature ( + VOID + ) +{ + UINT32 Eax; + UINT32 Ebx; + UINT32 Ecx; + UINT32 Edx; + CHAR8 Signature[13]; + + AsmCpuid (CPUID_SIGNATURE, &Eax, &Ebx, &Ecx, &Edx); + + Print (L"CPUID_SIGNATURE (Leaf %08x)\n", CPUID_SIGNATURE); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); + PRINT_VALUE (Eax, MaximumLeaf); + *(UINT32 *)(Signature + 0) = Ebx; + *(UINT32 *)(Signature + 4) = Edx; + *(UINT32 *)(Signature + 8) = Ecx; + Signature [12] = 0; + Print (L" Signature = %a\n", Signature); + + gMaximumBasicFunction = Eax; +} + +/** + Display CPUID_VERSION_INFO leaf. + +**/ +VOID +CpuidVersionInfo ( + VOID + ) +{ + CPUID_VERSION_INFO_EAX Eax; + CPUID_VERSION_INFO_EBX Ebx; + CPUID_VERSION_INFO_ECX Ecx; + CPUID_VERSION_INFO_EDX Edx; + UINT32 DisplayFamily; + UINT32 DisplayModel; + + if (CPUID_VERSION_INFO > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + + Print (L"CPUID_VERSION_INFO (Leaf %08x)\n", CPUID_VERSION_INFO); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + + DisplayFamily = Eax.Bits.FamilyId; + if (Eax.Bits.FamilyId == 0x0F) { + DisplayFamily |= (Eax.Bits.ExtendedFamilyId << 4); + } + + DisplayModel = Eax.Bits.Model; + if (Eax.Bits.FamilyId == 0x06 || Eax.Bits.FamilyId == 0x0f) { + DisplayModel |= (Eax.Bits.ExtendedModelId << 4); + } + + Print (L" Family = %x Model = %x Stepping = %x\n", DisplayFamily, DisplayModel, Eax.Bits.SteppingId); + + PRINT_BIT_FIELD (Eax, SteppingId); + PRINT_BIT_FIELD (Eax, Model); + PRINT_BIT_FIELD (Eax, FamilyId); + PRINT_BIT_FIELD (Eax, ProcessorType); + PRINT_BIT_FIELD (Eax, ExtendedModelId); + PRINT_BIT_FIELD (Eax, ExtendedFamilyId); + PRINT_BIT_FIELD (Ebx, BrandIndex); + PRINT_BIT_FIELD (Ebx, CacheLineSize); + PRINT_BIT_FIELD (Ebx, MaximumAddressableIdsForLogicalProcessors); + PRINT_BIT_FIELD (Ebx, InitialLocalApicId); + PRINT_BIT_FIELD (Ecx, SSE3); + PRINT_BIT_FIELD (Ecx, PCLMULQDQ); + PRINT_BIT_FIELD (Ecx, DTES64); + PRINT_BIT_FIELD (Ecx, MONITOR); + PRINT_BIT_FIELD (Ecx, DS_CPL); + PRINT_BIT_FIELD (Ecx, VMX); + PRINT_BIT_FIELD (Ecx, SMX); + PRINT_BIT_FIELD (Ecx, TM2); + PRINT_BIT_FIELD (Ecx, SSSE3); + PRINT_BIT_FIELD (Ecx, CNXT_ID); + PRINT_BIT_FIELD (Ecx, SDBG); + PRINT_BIT_FIELD (Ecx, FMA); + PRINT_BIT_FIELD (Ecx, CMPXCHG16B); + PRINT_BIT_FIELD (Ecx, xTPR_Update_Control); + PRINT_BIT_FIELD (Ecx, PDCM); + PRINT_BIT_FIELD (Ecx, PCID); + PRINT_BIT_FIELD (Ecx, DCA); + PRINT_BIT_FIELD (Ecx, SSE4_1); + PRINT_BIT_FIELD (Ecx, SSE4_2); + PRINT_BIT_FIELD (Ecx, x2APIC); + PRINT_BIT_FIELD (Ecx, MOVBE); + PRINT_BIT_FIELD (Ecx, POPCNT); + PRINT_BIT_FIELD (Ecx, TSC_Deadline); + PRINT_BIT_FIELD (Ecx, AESNI); + PRINT_BIT_FIELD (Ecx, XSAVE); + PRINT_BIT_FIELD (Ecx, OSXSAVE); + PRINT_BIT_FIELD (Ecx, AVX); + PRINT_BIT_FIELD (Ecx, F16C); + PRINT_BIT_FIELD (Ecx, RDRAND); + PRINT_BIT_FIELD (Edx, FPU); + PRINT_BIT_FIELD (Edx, VME); + PRINT_BIT_FIELD (Edx, DE); + PRINT_BIT_FIELD (Edx, PSE); + PRINT_BIT_FIELD (Edx, TSC); + PRINT_BIT_FIELD (Edx, MSR); + PRINT_BIT_FIELD (Edx, PAE); + PRINT_BIT_FIELD (Edx, MCE); + PRINT_BIT_FIELD (Edx, CX8); + PRINT_BIT_FIELD (Edx, APIC); + PRINT_BIT_FIELD (Edx, SEP); + PRINT_BIT_FIELD (Edx, MTRR); + PRINT_BIT_FIELD (Edx, PGE); + PRINT_BIT_FIELD (Edx, MCA); + PRINT_BIT_FIELD (Edx, CMOV); + PRINT_BIT_FIELD (Edx, PAT); + PRINT_BIT_FIELD (Edx, PSE_36); + PRINT_BIT_FIELD (Edx, PSN); + PRINT_BIT_FIELD (Edx, CLFSH); + PRINT_BIT_FIELD (Edx, DS); + PRINT_BIT_FIELD (Edx, ACPI); + PRINT_BIT_FIELD (Edx, MMX); + PRINT_BIT_FIELD (Edx, FXSR); + PRINT_BIT_FIELD (Edx, SSE); + PRINT_BIT_FIELD (Edx, SSE2); + PRINT_BIT_FIELD (Edx, SS); + PRINT_BIT_FIELD (Edx, HTT); + PRINT_BIT_FIELD (Edx, TM); + PRINT_BIT_FIELD (Edx, PBE); +} + +/** + Lookup a cache description string from the mCpuidCacheInfoDescription table. + + @param[in] CacheDescriptor Cache descriptor value from CPUID_CACHE_INFO. + +**/ +CPUID_CACHE_INFO_DESCRIPTION * +LookupCacheDescription ( + UINT8 CacheDescriptor + ) +{ + UINTN NumDescriptors; + UINTN Descriptor; + + if (CacheDescriptor == 0x00) { + return NULL; + } + NumDescriptors = sizeof (mCpuidCacheInfoDescription)/sizeof (mCpuidCacheInfoDescription[0]); + for (Descriptor = 0; Descriptor < NumDescriptors; Descriptor++) { + if (CacheDescriptor == mCpuidCacheInfoDescription[Descriptor].CacheDescriptor) { + return &mCpuidCacheInfoDescription[Descriptor]; + } + } + return NULL; +} + +/** + Display CPUID_CACHE_INFO leaf for each supported cache descriptor. + +**/ +VOID +CpuidCacheInfo ( + VOID + ) +{ + CPUID_CACHE_INFO_CACHE_TLB Eax; + CPUID_CACHE_INFO_CACHE_TLB Ebx; + CPUID_CACHE_INFO_CACHE_TLB Ecx; + CPUID_CACHE_INFO_CACHE_TLB Edx; + UINTN Index; + CPUID_CACHE_INFO_DESCRIPTION *CacheDescription; + + if (CPUID_CACHE_INFO > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_CACHE_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + + Print (L"CPUID_CACHE_INFO (Leaf %08x)\n", CPUID_CACHE_INFO); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + if (Eax.Bits.NotValid == 0) { + // + // Process Eax.CacheDescriptor[1..3]. Ignore Eax.CacheDescriptor[0] + // + for (Index = 1; Index < 4; Index++) { + CacheDescription = LookupCacheDescription (Eax.CacheDescriptor[Index]); + if (CacheDescription != NULL) { + Print (L" %-8a %a\n", + CacheDescription->Type, + CacheDescription->Description + ); + } + } + } + if (Ebx.Bits.NotValid == 0) { + // + // Process Ebx.CacheDescriptor[0..3] + // + for (Index = 0; Index < 4; Index++) { + CacheDescription = LookupCacheDescription (Ebx.CacheDescriptor[Index]); + if (CacheDescription != NULL) { + Print (L" %-8a %a\n", + CacheDescription->Type, + CacheDescription->Description + ); + } + } + } + if (Ecx.Bits.NotValid == 0) { + // + // Process Ecx.CacheDescriptor[0..3] + // + for (Index = 0; Index < 4; Index++) { + CacheDescription = LookupCacheDescription (Ecx.CacheDescriptor[Index]); + if (CacheDescription != NULL) { + Print (L" %-8a %a\n", + CacheDescription->Type, + CacheDescription->Description + ); + } + } + } + if (Edx.Bits.NotValid == 0) { + // + // Process Edx.CacheDescriptor[0..3] + // + for (Index = 0; Index < 4; Index++) { + CacheDescription = LookupCacheDescription (Edx.CacheDescriptor[Index]); + if (CacheDescription != NULL) { + Print (L" %-8a %a\n", + CacheDescription->Type, + CacheDescription->Description + ); + } + } + } +} + +/** + Display CPUID_SERIAL_NUMBER leaf if it is supported. + +**/ +VOID +CpuidSerialNumber ( + VOID + ) +{ + CPUID_VERSION_INFO_EDX VersionInfoEdx; + UINT32 Ecx; + UINT32 Edx; + + Print (L"CPUID_SERIAL_NUMBER (Leaf %08x)\n", CPUID_SERIAL_NUMBER); + + if (CPUID_SERIAL_NUMBER > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.PSN == 0) { + Print (L" Not Supported\n"); + return; + } + + AsmCpuid (CPUID_SERIAL_NUMBER, NULL, NULL, &Ecx, &Edx); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx, Edx); + Print (L" Processor Serial Number = %08x%08x%08x\n", 0, Edx, Ecx); +} + +/** + Display CPUID_CACHE_PARAMS for all supported sub-leafs. + +**/ +VOID +CpuidCacheParams ( + VOID + ) +{ + UINT32 CacheLevel; + CPUID_CACHE_PARAMS_EAX Eax; + CPUID_CACHE_PARAMS_EBX Ebx; + UINT32 Ecx; + CPUID_CACHE_PARAMS_EDX Edx; + + if (CPUID_CACHE_PARAMS > gMaximumBasicFunction) { + return; + } + + CacheLevel = 0; + do { + AsmCpuidEx ( + CPUID_CACHE_PARAMS, CacheLevel, + &Eax.Uint32, &Ebx.Uint32, &Ecx, &Edx.Uint32 + ); + if (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) { + Print (L"CPUID_CACHE_PARAMS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_CACHE_PARAMS, CacheLevel); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx, Edx.Uint32); + PRINT_BIT_FIELD (Eax, CacheType); + PRINT_BIT_FIELD (Eax, CacheLevel); + PRINT_BIT_FIELD (Eax, SelfInitializingCache); + PRINT_BIT_FIELD (Eax, FullyAssociativeCache); + PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForLogicalProcessors); + PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForProcessorCores); + PRINT_BIT_FIELD (Ebx, LineSize); + PRINT_BIT_FIELD (Ebx, LinePartitions); + PRINT_BIT_FIELD (Ebx, Ways); + PRINT_VALUE (Ecx, NumberOfSets); + PRINT_BIT_FIELD (Edx, Invalidate); + PRINT_BIT_FIELD (Edx, CacheInclusiveness); + PRINT_BIT_FIELD (Edx, ComplexCacheIndexing); + } + CacheLevel++; + } while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL); +} + +/** + Display CPUID_MONITOR_MWAIT leaf. + +**/ +VOID +CpuidMonitorMwait ( + VOID + ) +{ + CPUID_MONITOR_MWAIT_EAX Eax; + CPUID_MONITOR_MWAIT_EBX Ebx; + CPUID_MONITOR_MWAIT_ECX Ecx; + CPUID_MONITOR_MWAIT_EDX Edx; + + if (CPUID_MONITOR_MWAIT > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_MONITOR_MWAIT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + + Print (L"CPUID_MONITOR_MWAIT (Leaf %08x)\n", CPUID_MONITOR_MWAIT); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + + PRINT_BIT_FIELD (Eax, SmallestMonitorLineSize); + PRINT_BIT_FIELD (Ebx, LargestMonitorLineSize); + PRINT_BIT_FIELD (Ecx, ExtensionsSupported); + PRINT_BIT_FIELD (Ecx, InterruptAsBreak); + PRINT_BIT_FIELD (Edx, C0States); + PRINT_BIT_FIELD (Edx, C1States); + PRINT_BIT_FIELD (Edx, C2States); + PRINT_BIT_FIELD (Edx, C3States); + PRINT_BIT_FIELD (Edx, C4States); + PRINT_BIT_FIELD (Edx, C5States); + PRINT_BIT_FIELD (Edx, C6States); + PRINT_BIT_FIELD (Edx, C7States); +} + +/** + Display CPUID_THERMAL_POWER_MANAGEMENT leaf. + +**/ +VOID +CpuidThermalPowerManagement ( + VOID + ) +{ + CPUID_THERMAL_POWER_MANAGEMENT_EAX Eax; + CPUID_THERMAL_POWER_MANAGEMENT_EBX Ebx; + CPUID_THERMAL_POWER_MANAGEMENT_ECX Ecx; + + if (CPUID_THERMAL_POWER_MANAGEMENT > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); + + Print (L"CPUID_THERMAL_POWER_MANAGEMENT (Leaf %08x)\n", CPUID_THERMAL_POWER_MANAGEMENT); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); + + PRINT_BIT_FIELD (Eax, DigitalTemperatureSensor); + PRINT_BIT_FIELD (Eax, TurboBoostTechnology); + PRINT_BIT_FIELD (Eax, ARAT); + PRINT_BIT_FIELD (Eax, PLN); + PRINT_BIT_FIELD (Eax, ECMD); + PRINT_BIT_FIELD (Eax, PTM); + PRINT_BIT_FIELD (Eax, HWP); + PRINT_BIT_FIELD (Eax, HWP_Notification); + PRINT_BIT_FIELD (Eax, HWP_Activity_Window); + PRINT_BIT_FIELD (Eax, HWP_Energy_Performance_Preference); + PRINT_BIT_FIELD (Eax, HWP_Package_Level_Request); + PRINT_BIT_FIELD (Eax, HDC); + PRINT_BIT_FIELD (Eax, TurboBoostMaxTechnology30); + PRINT_BIT_FIELD (Eax, HWPCapabilities); + PRINT_BIT_FIELD (Eax, HWPPECIOverride); + PRINT_BIT_FIELD (Eax, FlexibleHWP); + PRINT_BIT_FIELD (Eax, FastAccessMode); + PRINT_BIT_FIELD (Eax, IgnoringIdleLogicalProcessorHWPRequest); + PRINT_BIT_FIELD (Ebx, InterruptThresholds); + PRINT_BIT_FIELD (Ecx, HardwareCoordinationFeedback); + PRINT_BIT_FIELD (Ecx, PerformanceEnergyBias); +} + +/** + Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs. + +**/ +VOID +CpuidStructuredExtendedFeatureFlags ( + VOID + ) +{ + UINT32 Eax; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EDX Edx; + UINT32 SubLeaf; + + if (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + &Eax, NULL, NULL, NULL + ); + for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) { + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + SubLeaf, + NULL, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 + ); + if (Ebx.Uint32 != 0 || Ecx.Uint32 != 0 || Edx.Uint32 != 0) { + Print (L"CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + PRINT_BIT_FIELD (Ebx, FSGSBASE); + PRINT_BIT_FIELD (Ebx, IA32_TSC_ADJUST); + PRINT_BIT_FIELD (Ebx, SGX); + PRINT_BIT_FIELD (Ebx, BMI1); + PRINT_BIT_FIELD (Ebx, HLE); + PRINT_BIT_FIELD (Ebx, AVX2); + PRINT_BIT_FIELD (Ebx, FDP_EXCPTN_ONLY); + PRINT_BIT_FIELD (Ebx, SMEP); + PRINT_BIT_FIELD (Ebx, BMI2); + PRINT_BIT_FIELD (Ebx, EnhancedRepMovsbStosb); + PRINT_BIT_FIELD (Ebx, INVPCID); + PRINT_BIT_FIELD (Ebx, RTM); + PRINT_BIT_FIELD (Ebx, RDT_M); + PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs); + PRINT_BIT_FIELD (Ebx, MPX); + PRINT_BIT_FIELD (Ebx, RDT_A); + PRINT_BIT_FIELD (Ebx, AVX512F); + PRINT_BIT_FIELD (Ebx, AVX512DQ); + PRINT_BIT_FIELD (Ebx, RDSEED); + PRINT_BIT_FIELD (Ebx, ADX); + PRINT_BIT_FIELD (Ebx, SMAP); + PRINT_BIT_FIELD (Ebx, AVX512_IFMA); + PRINT_BIT_FIELD (Ebx, CLFLUSHOPT); + PRINT_BIT_FIELD (Ebx, CLWB); + PRINT_BIT_FIELD (Ebx, IntelProcessorTrace); + PRINT_BIT_FIELD (Ebx, AVX512PF); + PRINT_BIT_FIELD (Ebx, AVX512ER); + PRINT_BIT_FIELD (Ebx, AVX512CD); + PRINT_BIT_FIELD (Ebx, SHA); + PRINT_BIT_FIELD (Ebx, AVX512BW); + PRINT_BIT_FIELD (Ebx, AVX512VL); + + PRINT_BIT_FIELD (Ecx, PREFETCHWT1); + PRINT_BIT_FIELD (Ecx, AVX512_VBMI); + PRINT_BIT_FIELD (Ecx, UMIP); + PRINT_BIT_FIELD (Ecx, PKU); + PRINT_BIT_FIELD (Ecx, OSPKE); + PRINT_BIT_FIELD (Ecx, AVX512_VPOPCNTDQ); + PRINT_BIT_FIELD (Ecx, MAWAU); + PRINT_BIT_FIELD (Ecx, RDPID); + PRINT_BIT_FIELD (Ecx, SGX_LC); + + PRINT_BIT_FIELD (Edx, AVX512_4VNNIW); + PRINT_BIT_FIELD (Edx, AVX512_4FMAPS); + PRINT_BIT_FIELD (Edx, EnumeratesSupportForIBRSAndIBPB); + PRINT_BIT_FIELD (Edx, EnumeratesSupportForSTIBP); + PRINT_BIT_FIELD (Edx, EnumeratesSupportForL1D_FLUSH); + PRINT_BIT_FIELD (Edx, EnumeratesSupportForCapability); + PRINT_BIT_FIELD (Edx, EnumeratesSupportForSSBD); + } + } +} + +/** + Display CPUID_DIRECT_CACHE_ACCESS_INFO leaf. + +**/ +VOID +CpuidDirectCacheAccessInfo ( + VOID + ) +{ + UINT32 Eax; + + if (CPUID_DIRECT_CACHE_ACCESS_INFO > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_DIRECT_CACHE_ACCESS_INFO, &Eax, NULL, NULL, NULL); + Print (L"CPUID_DIRECT_CACHE_ACCESS_INFO (Leaf %08x)\n", CPUID_DIRECT_CACHE_ACCESS_INFO); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); +} + +/** + Display CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING leaf. + +**/ +VOID +CpuidArchitecturalPerformanceMonitoring ( + VOID + ) +{ + CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX Eax; + CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX Ebx; + CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX Edx; + + if (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING, &Eax.Uint32, &Ebx.Uint32, NULL, &Edx.Uint32); + Print (L"CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING (Leaf %08x)\n", CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, Edx.Uint32); + PRINT_BIT_FIELD (Eax, ArchPerfMonVerID); + PRINT_BIT_FIELD (Eax, PerformanceMonitorCounters); + PRINT_BIT_FIELD (Eax, PerformanceMonitorCounterWidth); + PRINT_BIT_FIELD (Eax, EbxBitVectorLength); + PRINT_BIT_FIELD (Ebx, UnhaltedCoreCycles); + PRINT_BIT_FIELD (Ebx, InstructionsRetired); + PRINT_BIT_FIELD (Ebx, UnhaltedReferenceCycles); + PRINT_BIT_FIELD (Ebx, LastLevelCacheReferences); + PRINT_BIT_FIELD (Ebx, LastLevelCacheMisses); + PRINT_BIT_FIELD (Ebx, BranchInstructionsRetired); + PRINT_BIT_FIELD (Ebx, AllBranchMispredictRetired); + PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounters); + PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounterWidth); + PRINT_BIT_FIELD (Edx, AnyThreadDeprecation); +} + +/** + Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels. + + @param[in] LeafFunction Leaf function index for CPUID_EXTENDED_TOPOLOGY. + +**/ +VOID +CpuidExtendedTopology ( + UINT32 LeafFunction + ) +{ + CPUID_EXTENDED_TOPOLOGY_EAX Eax; + CPUID_EXTENDED_TOPOLOGY_EBX Ebx; + CPUID_EXTENDED_TOPOLOGY_ECX Ecx; + UINT32 Edx; + UINT32 LevelNumber; + + if (LeafFunction > gMaximumBasicFunction) { + return; + } + if ((LeafFunction != CPUID_EXTENDED_TOPOLOGY) && (LeafFunction != CPUID_V2_EXTENDED_TOPOLOGY)) { + return; + } + + LevelNumber = 0; + for (LevelNumber = 0; ; LevelNumber++) { + AsmCpuidEx ( + LeafFunction, LevelNumber, + &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx + ); + if (Ecx.Bits.LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + break; + } + Print ( + L"%a (Leaf %08x, Sub-Leaf %08x)\n", + LeafFunction == CPUID_EXTENDED_TOPOLOGY ? "CPUID_EXTENDED_TOPOLOGY" : "CPUID_V2_EXTENDED_TOPOLOGY", + LeafFunction, LevelNumber + ); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx); + PRINT_BIT_FIELD (Eax, ApicIdShift); + PRINT_BIT_FIELD (Ebx, LogicalProcessors); + PRINT_BIT_FIELD (Ecx, LevelNumber); + PRINT_BIT_FIELD (Ecx, LevelType); + PRINT_VALUE (Edx, x2APIC_ID); + } +} + +/** + Display CPUID_EXTENDED_STATE sub-leaf. + +**/ +VOID +CpuidExtendedStateSubLeaf ( + VOID + ) +{ + CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax; + UINT32 Ebx; + CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; + UINT32 Edx; + + AsmCpuidEx ( + CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, + &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx + ); + Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx); + PRINT_BIT_FIELD (Eax, XSAVEOPT); + PRINT_BIT_FIELD (Eax, XSAVEC); + PRINT_BIT_FIELD (Eax, XGETBV); + PRINT_BIT_FIELD (Eax, XSAVES); + PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS); + PRINT_BIT_FIELD (Ecx, XCR0); + PRINT_BIT_FIELD (Ecx, HWPState); + PRINT_BIT_FIELD (Ecx, PT); + PRINT_BIT_FIELD (Ecx, XCR0_1); + PRINT_VALUE (Edx, IA32_XSS_Supported_32_63); +} + +/** + Display CPUID_EXTENDED_STATE size and offset information sub-leaf. + +**/ +VOID +CpuidExtendedStateSizeOffset ( + VOID + ) +{ + UINT32 Eax; + UINT32 Ebx; + CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx; + UINT32 Edx; + UINT32 SubLeaf; + + for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) { + AsmCpuidEx ( + CPUID_EXTENDED_STATE, SubLeaf, + &Eax, &Ebx, &Ecx.Uint32, &Edx + ); + if (Edx != 0) { + Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx); + PRINT_VALUE (Eax, FeatureSaveStateSize); + PRINT_VALUE (Ebx, FeatureSaveStateOffset); + PRINT_BIT_FIELD (Ecx, XSS); + PRINT_BIT_FIELD (Ecx, Compacted); + } + } +} + +/** + Display CPUID_EXTENDED_STATE main leaf and sub-leafs. + +**/ +VOID +CpuidExtendedStateMainLeaf ( + VOID + ) +{ + CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax; + UINT32 Ebx; + UINT32 Ecx; + UINT32 Edx; + + if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF, + &Eax.Uint32, &Ebx, &Ecx, &Edx + ); + Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx); + PRINT_BIT_FIELD (Eax, x87); + PRINT_BIT_FIELD (Eax, SSE); + PRINT_BIT_FIELD (Eax, AVX); + PRINT_BIT_FIELD (Eax, MPX); + PRINT_BIT_FIELD (Eax, AVX_512); + PRINT_BIT_FIELD (Eax, IA32_XSS); + PRINT_BIT_FIELD (Eax, PKRU); + PRINT_BIT_FIELD (Eax, IA32_XSS_2); + PRINT_VALUE (Ebx, EnabledSaveStateSize); + PRINT_VALUE (Ecx, SupportedSaveStateSize); + PRINT_VALUE (Edx, XCR0_Supported_32_63); + + CpuidExtendedStateSubLeaf (); + CpuidExtendedStateSizeOffset (); +} + +/** + Display CPUID_INTEL_RDT_MONITORING enumeration sub-leaf. + +**/ +VOID +CpuidIntelRdtMonitoringEnumerationSubLeaf ( + VOID + ) +{ + UINT32 Ebx; + CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx; + + if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF, + NULL, &Ebx, NULL, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32); + PRINT_VALUE (Ebx, Maximum_RMID_Range); + PRINT_BIT_FIELD (Edx, L3CacheRDT_M); +} + +/** + Display CPUID_INTEL_RDT_MONITORING L3 cache capability sub-leaf. + +**/ +VOID +CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf ( + VOID + ) +{ + UINT32 Ebx; + UINT32 Ecx; + CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX Edx; + + if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF, + NULL, &Ebx, &Ecx, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32); + PRINT_VALUE (Ebx, OccupancyConversionFactor); + PRINT_VALUE (Ecx, Maximum_RMID_Range); + PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring); + PRINT_BIT_FIELD (Edx, L3CacheTotalBandwidthMonitoring); + PRINT_BIT_FIELD (Edx, L3CacheLocalBandwidthMonitoring); +} + +/** + Display CPUID_INTEL_RDT_ALLOCATION memory bandwidth allocation technology enumeration + sub-leaf. + +**/ +VOID +CpuidIntelRdtAllocationMemoryBandwidthSubLeaf ( + VOID + ) +{ + CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EAX Eax; + UINT32 Ebx; + CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_ECX Ecx; + CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EDX Edx; + + AsmCpuidEx ( + CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF, + &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); + PRINT_BIT_FIELD (Eax, MaximumMBAThrottling); + PRINT_VALUE (Ebx, AllocationUnitBitMap); + PRINT_BIT_FIELD (Ecx, Liner); + PRINT_BIT_FIELD (Edx, HighestCosNumber); +} + +/** + Display CPUID_INTEL_RDT_ALLOCATION L3 cache allocation technology enumeration + sub-leaf. + +**/ +VOID +CpuidIntelRdtAllocationL3CacheSubLeaf ( + VOID + ) +{ + CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX Eax; + UINT32 Ebx; + CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX Ecx; + CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX Edx; + + AsmCpuidEx ( + CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF, + &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); + PRINT_BIT_FIELD (Eax, CapacityLength); + PRINT_VALUE (Ebx, AllocationUnitBitMap); + PRINT_BIT_FIELD (Ecx, CodeDataPrioritization); + PRINT_BIT_FIELD (Edx, HighestCosNumber); +} + +/** + Display CPUID_INTEL_RDT_ALLOCATION L2 cache allocation technology enumeration + sub-leaf. + +**/ +VOID +CpuidIntelRdtAllocationL2CacheSubLeaf ( + VOID + ) +{ + CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX Eax; + UINT32 Ebx; + CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX Edx; + + AsmCpuidEx ( + CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF, + &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); + PRINT_BIT_FIELD (Eax, CapacityLength); + PRINT_VALUE (Ebx, AllocationUnitBitMap); + PRINT_BIT_FIELD (Edx, HighestCosNumber); +} + +/** + Display CPUID_INTEL_RDT_ALLOCATION main leaf and sub-leaves. + +**/ +VOID +CpuidIntelRdtAllocationMainLeaf ( + VOID + ) +{ + CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX Ebx; + + if (CPUID_INTEL_RDT_ALLOCATION > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF, + NULL, &Ebx.Uint32, NULL, NULL + ); + Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0); + PRINT_BIT_FIELD (Ebx, L3CacheAllocation); + PRINT_BIT_FIELD (Ebx, L2CacheAllocation); + PRINT_BIT_FIELD (Ebx, MemoryBandwidth); + CpuidIntelRdtAllocationMemoryBandwidthSubLeaf (); + CpuidIntelRdtAllocationL3CacheSubLeaf (); + CpuidIntelRdtAllocationL2CacheSubLeaf (); +} + +/** + Display Sub-Leaf 0 Enumeration of Intel SGX Capabilities. + +**/ +VOID +CpuidEnumerationOfIntelSgxCapabilities0SubLeaf ( + VOID + ) +{ + CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX Eax; + UINT32 Ebx; + CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX Edx; + + AsmCpuidEx ( + CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF, + &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 + ); + Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); + PRINT_BIT_FIELD (Eax, SGX1); + PRINT_BIT_FIELD (Eax, SGX2); + PRINT_BIT_FIELD (Eax, ENCLV); + PRINT_BIT_FIELD (Eax, ENCLS); + PRINT_BIT_FIELD (Edx, MaxEnclaveSize_Not64); + PRINT_BIT_FIELD (Edx, MaxEnclaveSize_64); +} + +/** + Display Sub-Leaf 1 Enumeration of Intel SGX Capabilities. + +**/ +VOID +CpuidEnumerationOfIntelSgxCapabilities1SubLeaf ( + VOID + ) +{ + UINT32 Eax; + UINT32 Ebx; + UINT32 Ecx; + UINT32 Edx; + + AsmCpuidEx ( + CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF, + &Eax, &Ebx, &Ecx, &Edx + ); + Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); +} + +/** + Display Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources. + +**/ +VOID +CpuidEnumerationOfIntelSgxResourcesSubLeaf ( + VOID + ) +{ + CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX Eax; + CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX Ebx; + CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX Ecx; + CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX Edx; + UINT32 SubLeaf; + + SubLeaf = CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF; + do { + AsmCpuidEx ( + CPUID_INTEL_SGX, SubLeaf, + &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 + ); + if (Eax.Bits.SubLeafType == 0x1) { + Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, SubLeaf); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + PRINT_BIT_FIELD (Eax, SubLeafType); + PRINT_BIT_FIELD (Eax, LowAddressOfEpcSection); + PRINT_BIT_FIELD (Ebx, HighAddressOfEpcSection); + PRINT_BIT_FIELD (Ecx, EpcSection); + PRINT_BIT_FIELD (Ecx, LowSizeOfEpcSection); + PRINT_BIT_FIELD (Edx, HighSizeOfEpcSection); + } + SubLeaf++; + } while (Eax.Bits.SubLeafType == 0x1); +} + +/** + Display Intel SGX Resource Enumeration. + +**/ +VOID +CpuidEnumerationOfIntelSgx ( + VOID + ) +{ + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; + + if (CPUID_INTEL_SGX > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + NULL, &Ebx.Uint32, NULL, NULL + ); + if (Ebx.Bits.SGX != 1) { + // + // Only if CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, the processor has support + // for Intel SGX. + // + return; + } + + CpuidEnumerationOfIntelSgxCapabilities0SubLeaf (); + CpuidEnumerationOfIntelSgxCapabilities1SubLeaf (); + CpuidEnumerationOfIntelSgxResourcesSubLeaf (); +} + +/** + Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs. + + @param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE. + +**/ +VOID +CpuidIntelProcessorTraceSubLeaf ( + UINT32 MaximumSubLeaf + ) +{ + UINT32 SubLeaf; + CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax; + CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx; + + for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) { + AsmCpuidEx ( + CPUID_INTEL_PROCESSOR_TRACE, SubLeaf, + &Eax.Uint32, &Ebx.Uint32, NULL, NULL + ); + Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0); + PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges); + PRINT_BIT_FIELD (Eax, MtcPeriodEncodings); + PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings); + PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings); + } +} + +/** + Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs. + +**/ +VOID +CpuidIntelProcessorTraceMainLeaf ( + VOID + ) +{ + UINT32 Eax; + CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx; + CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; + + if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, + &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL + ); + Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); + PRINT_VALUE (Eax, MaximumSubLeaf); + PRINT_BIT_FIELD (Ebx, Cr3Filter); + PRINT_BIT_FIELD (Ebx, ConfigurablePsb); + PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering); + PRINT_BIT_FIELD (Ebx, Mtc); + PRINT_BIT_FIELD (Ebx, PTWrite); + PRINT_BIT_FIELD (Ebx, PowerEventTrace); + PRINT_BIT_FIELD (Ecx, RTIT); + PRINT_BIT_FIELD (Ecx, ToPA); + PRINT_BIT_FIELD (Ecx, SingleRangeOutput); + PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem); + PRINT_BIT_FIELD (Ecx, LIP); + + CpuidIntelProcessorTraceSubLeaf (Eax); +} + +/** + Display CPUID_TIME_STAMP_COUNTER leaf. + +**/ +VOID +CpuidTimeStampCounter ( + VOID + ) +{ + UINT32 Eax; + UINT32 Ebx; + UINT32 Ecx; + + if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, &Ecx, NULL); + Print (L"CPUID_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_TIME_STAMP_COUNTER); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, 0); +} + +/** + Display CPUID_PROCESSOR_FREQUENCY leaf. + +**/ +VOID +CpuidProcessorFrequency ( + VOID + ) +{ + CPUID_PROCESSOR_FREQUENCY_EAX Eax; + CPUID_PROCESSOR_FREQUENCY_EBX Ebx; + CPUID_PROCESSOR_FREQUENCY_ECX Ecx; + + if (CPUID_PROCESSOR_FREQUENCY > gMaximumBasicFunction) { + return; + } + + AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); + Print (L"CPUID_PROCESSOR_FREQUENCY (Leaf %08x)\n", CPUID_PROCESSOR_FREQUENCY); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); + PRINT_BIT_FIELD (Eax, ProcessorBaseFrequency); + PRINT_BIT_FIELD (Ebx, MaximumFrequency); + PRINT_BIT_FIELD (Ecx, BusFrequency); +} + +/** + Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String. + Also display these sub-leafs as a single SoC Vendor Brand String. + +**/ +VOID +CpuidSocVendorBrandString ( + VOID + ) +{ + CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; + CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; + CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; + CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; + // + // Array to store brand string from 3 brand string leafs with + // 4 32-bit brand string values per leaf and an extra value to + // null terminate the string. + // + UINT32 BrandString[3 * 4 + 1]; + + AsmCpuidEx ( + CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1, + &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 + ); + Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[0] = Eax.Uint32; + BrandString[1] = Ebx.Uint32; + BrandString[2] = Ecx.Uint32; + BrandString[3] = Edx.Uint32; + + AsmCpuidEx ( + CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2, + &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 + ); + Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[4] = Eax.Uint32; + BrandString[5] = Ebx.Uint32; + BrandString[6] = Ecx.Uint32; + BrandString[7] = Edx.Uint32; + + AsmCpuidEx ( + CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3, + &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 + ); + Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[8] = Eax.Uint32; + BrandString[9] = Ebx.Uint32; + BrandString[10] = Ecx.Uint32; + BrandString[11] = Edx.Uint32; + + BrandString[12] = 0; + + Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString); +} + +/** + Display CPUID_SOC_VENDOR main leaf and sub-leafs. + +**/ +VOID +CpuidSocVendor ( + VOID + ) +{ + UINT32 Eax; + CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx; + UINT32 Ecx; + UINT32 Edx; + + if (CPUID_SOC_VENDOR > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF, + &Eax, &Ebx.Uint32, &Ecx, &Edx + ); + Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx); + if (Eax < 3) { + Print (L" Not Supported\n"); + return; + } + PRINT_VALUE (Eax, MaxSOCID_Index); + PRINT_BIT_FIELD (Ebx, SocVendorId); + PRINT_BIT_FIELD (Ebx, IsVendorScheme); + PRINT_VALUE (Ecx, ProjectID); + PRINT_VALUE (Edx, SteppingID); + CpuidSocVendorBrandString (); +} + +/** + Display CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS main leaf and sub-leafs. + +**/ +VOID +CpuidDeterministicAddressTranslationParameters ( + VOID + ) +{ + UINT32 Eax; + CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EBX Ebx; + UINT32 Ecx; + CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EDX Edx; + + if (CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS > gMaximumBasicFunction) { + return; + } + + AsmCpuidEx ( + CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS, + CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_MAIN_LEAF, + &Eax, &Ebx.Uint32, &Ecx, &Edx.Uint32 + ); + Print (L"CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS, CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_MAIN_LEAF); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx.Uint32); + + PRINT_VALUE (Eax, MaxID_Index); + PRINT_BIT_FIELD (Ebx, Page4K); + PRINT_BIT_FIELD (Ebx, Page2M); + PRINT_BIT_FIELD (Ebx, Page4M); + PRINT_BIT_FIELD (Ebx, Page1G); + PRINT_BIT_FIELD (Ebx, Partitioning); + PRINT_BIT_FIELD (Ebx, Way); + + PRINT_VALUE (Ecx, NumberOfSets); + + PRINT_BIT_FIELD (Edx, TranslationCacheType); + PRINT_BIT_FIELD (Edx, TranslationCacheLevel); + PRINT_BIT_FIELD (Edx, FullyAssociative); + PRINT_BIT_FIELD (Edx, MaximumNum); +} + +/** + Display CPUID_EXTENDED_FUNCTION leaf. + +**/ +VOID +CpuidExtendedFunction ( + VOID + ) +{ + UINT32 Eax; + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL); + Print (L"CPUID_EXTENDED_FUNCTION (Leaf %08x)\n", CPUID_EXTENDED_FUNCTION); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); + PRINT_VALUE (Eax, MaximumExtendedFunction); + + gMaximumExtendedFunction = Eax; +} + +/** + Display CPUID_EXTENDED_CPU_SIG leaf. + +**/ +VOID +CpuidExtendedCpuSig ( + VOID + ) +{ + UINT32 Eax; + CPUID_EXTENDED_CPU_SIG_ECX Ecx; + CPUID_EXTENDED_CPU_SIG_EDX Edx; + + if (CPUID_EXTENDED_CPU_SIG > gMaximumExtendedFunction) { + return; + } + + AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32); + Print (L"CPUID_EXTENDED_CPU_SIG (Leaf %08x)\n", CPUID_EXTENDED_CPU_SIG); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, Ecx.Uint32, Edx.Uint32); + PRINT_BIT_FIELD (Ecx, LAHF_SAHF); + PRINT_BIT_FIELD (Ecx, LZCNT); + PRINT_BIT_FIELD (Ecx, PREFETCHW); + PRINT_BIT_FIELD (Edx, SYSCALL_SYSRET); + PRINT_BIT_FIELD (Edx, NX); + PRINT_BIT_FIELD (Edx, Page1GB); + PRINT_BIT_FIELD (Edx, RDTSCP); + PRINT_BIT_FIELD (Edx, LM); +} + +/** + Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3 + leafs. Also display these three leafs as a single brand string. + +**/ +VOID +CpuidProcessorBrandString ( + VOID + ) +{ + CPUID_BRAND_STRING_DATA Eax; + CPUID_BRAND_STRING_DATA Ebx; + CPUID_BRAND_STRING_DATA Ecx; + CPUID_BRAND_STRING_DATA Edx; + // + // Array to store brand string from 3 brand string leafs with + // 4 32-bit brand string values per leaf and an extra value to + // null terminate the string. + // + UINT32 BrandString[3 * 4 + 1]; + + if (CPUID_BRAND_STRING1 <= gMaximumExtendedFunction) { + AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + Print (L"CPUID_BRAND_STRING1 (Leaf %08x)\n", CPUID_BRAND_STRING1); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[0] = Eax.Uint32; + BrandString[1] = Ebx.Uint32; + BrandString[2] = Ecx.Uint32; + BrandString[3] = Edx.Uint32; + } + + if (CPUID_BRAND_STRING2 <= gMaximumExtendedFunction) { + AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + Print (L"CPUID_BRAND_STRING2 (Leaf %08x)\n", CPUID_BRAND_STRING2); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[4] = Eax.Uint32; + BrandString[5] = Ebx.Uint32; + BrandString[6] = Ecx.Uint32; + BrandString[7] = Edx.Uint32; + } + + if (CPUID_BRAND_STRING3 <= gMaximumExtendedFunction) { + AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); + Print (L"CPUID_BRAND_STRING3 (Leaf %08x)\n", CPUID_BRAND_STRING3); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); + BrandString[8] = Eax.Uint32; + BrandString[9] = Ebx.Uint32; + BrandString[10] = Ecx.Uint32; + BrandString[11] = Edx.Uint32; + } + + BrandString[12] = 0; + + Print (L"Brand String = %a\n", (CHAR8 *)BrandString); +} + +/** + Display CPUID_EXTENDED_CACHE_INFO leaf. + +**/ +VOID +CpuidExtendedCacheInfo ( + VOID + ) +{ + CPUID_EXTENDED_CACHE_INFO_ECX Ecx; + + if (CPUID_EXTENDED_CACHE_INFO > gMaximumExtendedFunction) { + return; + } + + AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL); + Print (L"CPUID_EXTENDED_CACHE_INFO (Leaf %08x)\n", CPUID_EXTENDED_CACHE_INFO); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx.Uint32, 0); + PRINT_BIT_FIELD (Ecx, CacheLineSize); + PRINT_BIT_FIELD (Ecx, L2Associativity); + PRINT_BIT_FIELD (Ecx, CacheSize); +} + +/** + Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf. + +**/ +VOID +CpuidExtendedTimeStampCounter ( + VOID + ) +{ + CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx; + + if (CPUID_EXTENDED_TIME_STAMP_COUNTER > gMaximumExtendedFunction) { + return; + } + + AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32); + Print (L"CPUID_EXTENDED_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_EXTENDED_TIME_STAMP_COUNTER); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, 0, Edx.Uint32); + PRINT_BIT_FIELD (Edx, InvariantTsc); +} + +/** + Display CPUID_VIR_PHY_ADDRESS_SIZE leaf. + +**/ +VOID +CpuidVirPhyAddressSize ( + VOID + ) +{ + CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax; + + if (CPUID_VIR_PHY_ADDRESS_SIZE > gMaximumExtendedFunction) { + return; + } + + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL); + Print (L"CPUID_VIR_PHY_ADDRESS_SIZE (Leaf %08x)\n", CPUID_VIR_PHY_ADDRESS_SIZE); + Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, 0, 0, 0); + PRINT_BIT_FIELD (Eax, PhysicalAddressBits); + PRINT_BIT_FIELD (Eax, LinearAddressBits); +} + +/** + The user Entry Point for Application. The user code starts with this function + as the real entry point for the application. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + Print (L"UEFI CPUID Version 0.5\n"); + + CpuidSignature (); + CpuidVersionInfo (); + CpuidCacheInfo (); + CpuidSerialNumber (); + CpuidCacheParams(); + CpuidMonitorMwait (); + CpuidThermalPowerManagement (); + CpuidStructuredExtendedFeatureFlags (); + CpuidDirectCacheAccessInfo(); + CpuidArchitecturalPerformanceMonitoring (); + CpuidExtendedTopology (CPUID_EXTENDED_TOPOLOGY); + CpuidExtendedStateMainLeaf (); + CpuidIntelRdtMonitoringEnumerationSubLeaf (); + CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf (); + CpuidIntelRdtAllocationMainLeaf (); + CpuidEnumerationOfIntelSgx (); + CpuidIntelProcessorTraceMainLeaf (); + CpuidTimeStampCounter (); + CpuidProcessorFrequency (); + CpuidSocVendor (); + CpuidDeterministicAddressTranslationParameters (); + CpuidExtendedTopology (CPUID_V2_EXTENDED_TOPOLOGY); + CpuidExtendedFunction (); + CpuidExtendedCpuSig (); + CpuidProcessorBrandString (); + CpuidExtendedCacheInfo (); + CpuidExtendedTimeStampCounter (); + CpuidVirPhyAddressSize (); + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Application/Cpuid/Cpuid.inf b/UefiCpuPkg/Application/Cpuid/Cpuid.inf new file mode 100644 index 000000000..24f24bfdf --- /dev/null +++ b/UefiCpuPkg/Application/Cpuid/Cpuid.inf @@ -0,0 +1,43 @@ +## @file +# UEFI Application to display CPUID leaf information. +# +# This UEFI application displays the registers values returned by CPUID for +# all the CPUID leafs and sub-leafs that a CPU supports. It also displays +# the values of all the bit fields in the registers returned by each CPUID +# leaf and sub-leaf. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Cpuid + MODULE_UNI_FILE = Cpuid.uni + FILE_GUID = 4AE7E1E8-9DFE-4e3e-85B4-A5F6ABD470FB + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 0.5 + ENTRY_POINT = UefiMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Cpuid.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + UefiLib + +[UserExtensions.TianoCore."ExtraFiles"] + CpuidExtra.uni diff --git a/UefiCpuPkg/Application/Cpuid/Cpuid.uni b/UefiCpuPkg/Application/Cpuid/Cpuid.uni new file mode 100644 index 000000000..b22b59841 --- /dev/null +++ b/UefiCpuPkg/Application/Cpuid/Cpuid.uni @@ -0,0 +1,17 @@ +// /** @file +// UEFI Application to display CPUID leaf information. +// +// This UEFI application displays the registers values returned by CPUID for +// all the CPUID leafs and sub-leafs that a CPU supports. It also displays +// the values of all the bit fields in the registers returned by each CPUID +// leaf and sub-leaf. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "UEFI Application to display CPUID leaf information" + +#string STR_MODULE_DESCRIPTION #language en-US "This UEFI application displays the registers values returned by CPUID for all the CPUID leafs and sub-leafs that a CPU supports. It also displays the values of all the bit fields in the registers returned by each CPUID leaf and sub-leaf." diff --git a/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni b/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni new file mode 100644 index 000000000..1b3e56271 --- /dev/null +++ b/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni @@ -0,0 +1,17 @@ +// /** @file +// UEFI Application to display CPUID leaf information. +// +// This UEFI application displays the registers values returned by CPUID for +// all the CPUID leafs and sub-leafs that a CPU supports. It also displays +// the values of all the bit fields in the registers returned by each CPUID +// leaf and sub-leaf. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPUID Application" diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c similarity index 58% rename from CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.c rename to UefiCpuPkg/CpuDxe/CpuDxe.c index 3c872fac3..a571fc3b1 100644 --- a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.c +++ b/UefiCpuPkg/CpuDxe/CpuDxe.c @@ -1,95 +1,87 @@ /** @file - CPU DXE Module. + CPU DXE Module to produce CPU ARCH Protocol. - Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "CpuDxe.h" +#include "CpuMp.h" +#include "CpuPageTable.h" -#define USE_MTRR 0 +#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) +#define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO) // // Global Variables // -IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { { { 0 } } }; - -EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100]; BOOLEAN InterruptState = FALSE; EFI_HANDLE mCpuHandle = NULL; BOOLEAN mIsFlushingGCD; -#if USE_MTRR -UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS; -UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK; -#endif -IA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL; -UINT16 mOrigIdtEntryCount = 0; -#if USE_MTRR +BOOLEAN mIsAllocatingPageTable = FALSE; +UINT64 mValidMtrrAddressMask; +UINT64 mValidMtrrBitsMask; +UINT64 mTimerPeriod = 0; + FIXED_MTRR mFixedMtrrTable[] = { { - MTRR_LIB_IA32_MTRR_FIX64K_00000, + MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000 }, { - MTRR_LIB_IA32_MTRR_FIX16K_80000, + MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000 }, { - MTRR_LIB_IA32_MTRR_FIX16K_A0000, + MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_C0000, + MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_C8000, + MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_D0000, + MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_D8000, + MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_E0000, + MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_E8000, + MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_F0000, + MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000 }, { - MTRR_LIB_IA32_MTRR_FIX4K_F8000, + MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000 }, }; -#endif + EFI_CPU_ARCH_PROTOCOL gCpu = { CpuFlushCpuDataCache, @@ -104,260 +96,10 @@ EFI_CPU_ARCH_PROTOCOL gCpu = { 4 // DmaBufferAlignment }; -// -// Error code flag indicating whether or not an error code will be -// pushed on the stack if an exception occurs. -// -// 1 means an error code will be pushed, otherwise 0 -// -// bit 0 - exception 0 -// bit 1 - exception 1 -// etc. -// -UINT32 mErrorCodeFlag = 0x00027d00; -EFI_EVENT IdleLoopEvent; - -// -// Local function prototypes -// - -/** - Set Interrupt Descriptor Table Handler Address. - - @param Index The Index of the interrupt descriptor table handle. - @param Handler Handler address. - -**/ -VOID -SetInterruptDescriptorTableHandlerAddress ( - IN UINTN Index, - IN VOID *Handler OPTIONAL - ); - // // CPU Arch Protocol Functions // - -/** - Common exception handler. - - @param InterruptType Exception type - @param SystemContext EFI_SYSTEM_CONTEXT - -**/ -VOID -EFIAPI -CommonExceptionHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ -#if defined (MDE_CPU_IA32) - DEBUG (( - EFI_D_ERROR, - "!!!! IA32 Exception Type - %08x !!!!\n", - InterruptType - )); - if ((mErrorCodeFlag & (1 << InterruptType)) != 0) { - DEBUG (( - EFI_D_ERROR, - "ExceptionData - %08x\n", - SystemContext.SystemContextIa32->ExceptionData - )); - } - DEBUG (( - EFI_D_ERROR, - "CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n", - SystemContext.SystemContextIa32->Cs, - SystemContext.SystemContextIa32->Eip, - SystemContext.SystemContextIa32->Eflags, - SystemContext.SystemContextIa32->Ss - )); - DEBUG (( - EFI_D_ERROR, - "DS - %04x, ES - %04x, FS - %04x, GS - %04x\n", - SystemContext.SystemContextIa32->Ds, - SystemContext.SystemContextIa32->Es, - SystemContext.SystemContextIa32->Fs, - SystemContext.SystemContextIa32->Gs - )); - DEBUG (( - EFI_D_ERROR, - "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n", - SystemContext.SystemContextIa32->Eax, - SystemContext.SystemContextIa32->Ebx, - SystemContext.SystemContextIa32->Ecx, - SystemContext.SystemContextIa32->Edx - )); - DEBUG (( - EFI_D_ERROR, - "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n", - SystemContext.SystemContextIa32->Esp, - SystemContext.SystemContextIa32->Ebp, - SystemContext.SystemContextIa32->Esi, - SystemContext.SystemContextIa32->Edi - )); - DEBUG (( - EFI_D_ERROR, - "GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n", - SystemContext.SystemContextIa32->Gdtr[0], - SystemContext.SystemContextIa32->Gdtr[1], - SystemContext.SystemContextIa32->Idtr[0], - SystemContext.SystemContextIa32->Idtr[1] - )); - DEBUG (( - EFI_D_ERROR, - "LDT - %08x, TR - %08x\n", - SystemContext.SystemContextIa32->Ldtr, - SystemContext.SystemContextIa32->Tr - )); - DEBUG (( - EFI_D_ERROR, - "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n", - SystemContext.SystemContextIa32->Cr0, - SystemContext.SystemContextIa32->Cr2, - SystemContext.SystemContextIa32->Cr3, - SystemContext.SystemContextIa32->Cr4 - )); - DEBUG (( - EFI_D_ERROR, - "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n", - SystemContext.SystemContextIa32->Dr0, - SystemContext.SystemContextIa32->Dr1, - SystemContext.SystemContextIa32->Dr2, - SystemContext.SystemContextIa32->Dr3 - )); - DEBUG (( - EFI_D_ERROR, - "DR6 - %08x, DR7 - %08x\n", - SystemContext.SystemContextIa32->Dr6, - SystemContext.SystemContextIa32->Dr7 - )); -#elif defined (MDE_CPU_X64) - DEBUG (( - EFI_D_ERROR, - "!!!! X64 Exception Type - %016lx !!!!\n", - (UINT64)InterruptType - )); - if ((mErrorCodeFlag & (1 << InterruptType)) != 0) { - DEBUG (( - EFI_D_ERROR, - "ExceptionData - %016lx\n", - SystemContext.SystemContextX64->ExceptionData - )); - } - DEBUG (( - EFI_D_ERROR, - "RIP - %016lx, RFL - %016lx\n", - SystemContext.SystemContextX64->Rip, - SystemContext.SystemContextX64->Rflags - )); - DEBUG (( - EFI_D_ERROR, - "RAX - %016lx, RCX - %016lx, RDX - %016lx\n", - SystemContext.SystemContextX64->Rax, - SystemContext.SystemContextX64->Rcx, - SystemContext.SystemContextX64->Rdx - )); - DEBUG (( - EFI_D_ERROR, - "RBX - %016lx, RSP - %016lx, RBP - %016lx\n", - SystemContext.SystemContextX64->Rbx, - SystemContext.SystemContextX64->Rsp, - SystemContext.SystemContextX64->Rbp - )); - DEBUG (( - EFI_D_ERROR, - "RSI - %016lx, RDI - %016lx\n", - SystemContext.SystemContextX64->Rsi, - SystemContext.SystemContextX64->Rdi - )); - DEBUG (( - EFI_D_ERROR, - "R8 - %016lx, R9 - %016lx, R10 - %016lx\n", - SystemContext.SystemContextX64->R8, - SystemContext.SystemContextX64->R9, - SystemContext.SystemContextX64->R10 - )); - DEBUG (( - EFI_D_ERROR, - "R11 - %016lx, R12 - %016lx, R13 - %016lx\n", - SystemContext.SystemContextX64->R11, - SystemContext.SystemContextX64->R12, - SystemContext.SystemContextX64->R13 - )); - DEBUG (( - EFI_D_ERROR, - "R14 - %016lx, R15 - %016lx\n", - SystemContext.SystemContextX64->R14, - SystemContext.SystemContextX64->R15 - )); - DEBUG (( - EFI_D_ERROR, - "CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n", - SystemContext.SystemContextX64->Cs, - SystemContext.SystemContextX64->Ds, - SystemContext.SystemContextX64->Es, - SystemContext.SystemContextX64->Fs, - SystemContext.SystemContextX64->Gs, - SystemContext.SystemContextX64->Ss - )); - DEBUG (( - EFI_D_ERROR, - "GDT - %016lx; %04lx, IDT - %016lx; %04lx\n", - SystemContext.SystemContextX64->Gdtr[0], - SystemContext.SystemContextX64->Gdtr[1], - SystemContext.SystemContextX64->Idtr[0], - SystemContext.SystemContextX64->Idtr[1] - )); - DEBUG (( - EFI_D_ERROR, - "LDT - %016lx, TR - %016lx\n", - SystemContext.SystemContextX64->Ldtr, - SystemContext.SystemContextX64->Tr - )); - DEBUG (( - EFI_D_ERROR, - "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n", - SystemContext.SystemContextX64->Cr0, - SystemContext.SystemContextX64->Cr2, - SystemContext.SystemContextX64->Cr3 - )); - DEBUG (( - EFI_D_ERROR, - "CR4 - %016lx, CR8 - %016lx\n", - SystemContext.SystemContextX64->Cr4, - SystemContext.SystemContextX64->Cr8 - )); - DEBUG (( - EFI_D_ERROR, - "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n", - SystemContext.SystemContextX64->Dr0, - SystemContext.SystemContextX64->Dr1, - SystemContext.SystemContextX64->Dr2 - )); - DEBUG (( - EFI_D_ERROR, - "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n", - SystemContext.SystemContextX64->Dr3, - SystemContext.SystemContextX64->Dr6, - SystemContext.SystemContextX64->Dr7 - )); -//#else -//#error CPU type not supported for exception information dump! -#endif - - // - // Hang the system with CpuSleep so the processor will enter a lower power - // state. - // - while (TRUE) { - CpuSleep (); - }; -} - - /** Flush CPU data cache. If the instruction cache is fully coherent with all DMA operations then function can just return EFI_SUCCESS. @@ -515,29 +257,7 @@ CpuRegisterInterruptHandler ( IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler ) { - if (InterruptType < 0 || InterruptType > 0xff) { - return EFI_UNSUPPORTED; - } - - if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) { - return EFI_ALREADY_STARTED; - } - - if (InterruptHandler != NULL) { - SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL); - } else { - // - // Restore the original IDT handler address if InterruptHandler is NULL. - // - RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType); - } - - ExternalVectorTable[InterruptType] = InterruptHandler; - return EFI_SUCCESS; + return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); } @@ -573,6 +293,9 @@ CpuGetTimerValue ( OUT UINT64 *TimerPeriod OPTIONAL ) { + UINT64 BeginValue; + UINT64 EndValue; + if (TimerValue == NULL) { return EFI_INVALID_PARAMETER; } @@ -584,18 +307,46 @@ CpuGetTimerValue ( *TimerValue = AsmReadTsc (); if (TimerPeriod != NULL) { + if (mTimerPeriod == 0) { // - // BugBug: Hard coded. Don't know how to do this generically + // Read time stamp counter before and after delay of 100 microseconds // - //Slice: Don't wonder. This value is for Tsc timer. - // using ACPI, HPET or TMR timer we will use other value for TimerPeriod. - // ;) - *TimerPeriod = 1000000000; + BeginValue = AsmReadTsc (); + MicroSecondDelay (100); + EndValue = AsmReadTsc (); + // + // Calculate the actual frequency + // + mTimerPeriod = DivU64x64Remainder ( + MultU64x32 ( + 1000 * 1000 * 1000, + 100 + ), + EndValue - BeginValue, + NULL + ); + } + *TimerPeriod = mTimerPeriod; } return EFI_SUCCESS; } +/** + A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure. + + @param[in] Buffer Pointer to an MTRR_SETTINGS object, to be passed to + MtrrSetAllMtrrs(). +**/ +VOID +EFIAPI +SetMtrrsFromBuffer ( + IN VOID *Buffer + ) +{ + MtrrSetAllMtrrs (Buffer); +} /** Implementation of SetMemoryAttributes() service of CPU Architecture Protocol. @@ -631,68 +382,121 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes ) { - return EFI_UNSUPPORTED; - -#if USE_MTRR /*this is extra bug, we need no it */ RETURN_STATUS Status; MTRR_MEMORY_CACHE_TYPE CacheType; - - if (!IsMtrrSupported ()) { - return EFI_UNSUPPORTED; - } + EFI_STATUS MpStatus; + EFI_MP_SERVICES_PROTOCOL *MpService; + MTRR_SETTINGS MtrrSettings; + UINT64 CacheAttributes; + UINT64 MemoryAttributes; + MTRR_MEMORY_CACHE_TYPE CurrentCacheType; // // If this function is called because GCD SetMemorySpaceAttributes () is called - // by RefreshGcdMemoryAttributes (), then we are just synchronzing GCD memory + // by RefreshGcdMemoryAttributes (), then we are just synchronizing GCD memory // map with MTRR values. So there is no need to modify MTRRs, just return immediately // to avoid unnecessary computing. // if (mIsFlushingGCD) { - DEBUG((EFI_D_ERROR, " Flushing GCD\n")); - return EFI_SUCCESS; - } + DEBUG((DEBUG_VERBOSE, " Flushing GCD\n")); + return EFI_SUCCESS; + } - switch (Attributes) { - case EFI_MEMORY_UC: - CacheType = CacheUncacheable; - break; + // + // During memory attributes updating, new pages may be allocated to setup + // smaller granularity of page table. Page allocation action might then cause + // another calling of CpuSetMemoryAttributes() recursively, due to memory + // protection policy configured (such as PcdDxeNxMemoryProtectionPolicy). + // Since this driver will always protect memory used as page table by itself, + // there's no need to apply protection policy requested from memory service. + // So it's safe to just return EFI_SUCCESS if this time of calling is caused + // by page table memory allocation. + // + if (mIsAllocatingPageTable) { + DEBUG((DEBUG_VERBOSE, " Allocating page table memory\n")); + return EFI_SUCCESS; + } - case EFI_MEMORY_WC: - CacheType = CacheWriteCombining; - break; + CacheAttributes = Attributes & CACHE_ATTRIBUTE_MASK; + MemoryAttributes = Attributes & MEMORY_ATTRIBUTE_MASK; - case EFI_MEMORY_WT: - CacheType = CacheWriteThrough; - break; - - case EFI_MEMORY_WP: - CacheType = CacheWriteProtected; - break; - - case EFI_MEMORY_WB: - CacheType = CacheWriteBack; - break; - - case EFI_MEMORY_UCE: - case EFI_MEMORY_RP: - case EFI_MEMORY_XP: - case EFI_MEMORY_RUNTIME: - return EFI_UNSUPPORTED; - - default: + if (Attributes != (CacheAttributes | MemoryAttributes)) { return EFI_INVALID_PARAMETER; } - // - // call MTRR libary function - // - Status = MtrrSetMemoryAttribute ( - BaseAddress, - Length, - CacheType - ); - return (EFI_STATUS) Status; -#endif + if (CacheAttributes != 0) { + if (!IsMtrrSupported ()) { + return EFI_UNSUPPORTED; + } + + switch (CacheAttributes) { + case EFI_MEMORY_UC: + CacheType = CacheUncacheable; + break; + + case EFI_MEMORY_WC: + CacheType = CacheWriteCombining; + break; + + case EFI_MEMORY_WT: + CacheType = CacheWriteThrough; + break; + + case EFI_MEMORY_WP: + CacheType = CacheWriteProtected; + break; + + case EFI_MEMORY_WB: + CacheType = CacheWriteBack; + break; + + default: + return EFI_INVALID_PARAMETER; + } + CurrentCacheType = MtrrGetMemoryAttribute(BaseAddress); + if (CurrentCacheType != CacheType) { + // + // call MTRR library function + // + Status = MtrrSetMemoryAttribute ( + BaseAddress, + Length, + CacheType + ); + + if (!RETURN_ERROR (Status)) { + MpStatus = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **)&MpService + ); + // + // Synchronize the update with all APs + // + if (!EFI_ERROR (MpStatus)) { + MtrrGetAllMtrrs (&MtrrSettings); + MpStatus = MpService->StartupAllAPs ( + MpService, // This + SetMtrrsFromBuffer, // Procedure + FALSE, // SingleThread + NULL, // WaitEvent + 0, // TimeoutInMicrosecsond + &MtrrSettings, // ProcedureArgument + NULL // FailedCpuList + ); + ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED); + } + } + if (EFI_ERROR(Status)) { + return Status; + } + } + } + + // + // Set memory attribute by page table + // + return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, NULL); } /** @@ -701,7 +505,6 @@ CpuSetMemoryAttributes ( This function initializes the valid bits mask and valid address mask for MTRRs. **/ -#if USE_MTRR VOID InitializeMtrrMask ( VOID @@ -716,15 +519,14 @@ InitializeMtrrMask ( AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); PhysicalAddressBits = (UINT8) RegEax; - - mValidMtrrBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1; - mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL; } else { - mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK; - mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS; + PhysicalAddressBits = 36; } + + mValidMtrrBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1; + mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL; } -#endif + /** Gets GCD Mem Space type from MTRR Type. @@ -735,7 +537,6 @@ InitializeMtrrMask ( @return GCD Mem Space type **/ -#if USE_MTRR UINT64 GetMemorySpaceAttributeFromMtrrType ( IN UINT8 MtrrAttributes @@ -756,7 +557,7 @@ GetMemorySpaceAttributeFromMtrrType ( return 0; } } -#endif + /** Searches memory descriptors covered by given memory range. @@ -846,7 +647,7 @@ SetGcdMemorySpaceAttributes ( &StartIndex, &EndIndex ); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -890,9 +691,8 @@ SetGcdMemorySpaceAttributes ( This function refreshes the GCD Memory Space attributes according to MTRRs. **/ -#if USE_MTRR VOID -RefreshGcdMemoryAttributes ( +RefreshMemoryAttributesFromMtrr ( VOID ) { @@ -913,14 +713,9 @@ RefreshGcdMemoryAttributes ( UINT32 FirmwareVariableMtrrCount; UINT8 DefaultMemoryType; - if (!IsMtrrSupported ()) { - return; - } - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - mIsFlushingGCD = TRUE; MemorySpaceMap = NULL; // @@ -944,7 +739,7 @@ RefreshGcdMemoryAttributes ( &NumberOfDescriptors, &MemorySpaceMap ); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); DefaultMemoryType = (UINT8) MtrrGetDefaultMemoryType (); DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (DefaultMemoryType); @@ -1036,7 +831,7 @@ RefreshGcdMemoryAttributes ( Attributes = CurrentAttributes; } else { // - // If fixed MTRR attribute changed, then set memory attribute for previous atrribute + // If fixed MTRR attribute changed, then set memory attribute for previous attribute // if (CurrentAttributes != Attributes) { SetGcdMemorySpaceAttributes ( @@ -1069,66 +864,51 @@ RefreshGcdMemoryAttributes ( // Free memory space map allocated by GCD service GetMemorySpaceMap () // if (MemorySpaceMap != NULL) { - FreePool(MemorySpaceMap); + FreePool (MemorySpaceMap); + } +} + +/** + Check if paging is enabled or not. +**/ +BOOLEAN +IsPagingAndPageAddressExtensionsEnabled ( + VOID + ) +{ + IA32_CR0 Cr0; + IA32_CR4 Cr4; + + Cr0.UintN = AsmReadCr0 (); + Cr4.UintN = AsmReadCr4 (); + + return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0)); +} + +/** + Refreshes the GCD Memory Space attributes according to MTRRs and Paging. + + This function refreshes the GCD Memory Space attributes according to MTRRs + and page tables. + +**/ +VOID +RefreshGcdMemoryAttributes ( + VOID + ) +{ + mIsFlushingGCD = TRUE; + + if (IsMtrrSupported ()) { + RefreshMemoryAttributesFromMtrr (); + } + + if (IsPagingAndPageAddressExtensionsEnabled ()) { + RefreshGcdMemoryAttributesFromPaging (); } mIsFlushingGCD = FALSE; } -#endif -/** - Set Interrupt Descriptor Table Handler Address. - - @param Index The Index of the interrupt descriptor table handle. - @param Handler Handler address. - -**/ -VOID -SetInterruptDescriptorTableHandlerAddress ( - IN UINTN Index, - IN VOID *Handler OPTIONAL - ) -{ - UINTN UintnHandler; - - if (Handler != NULL) { - UintnHandler = (UINTN) Handler; - } else { - UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index); - } - - gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler; - gIdtTable[Index].Bits.Reserved_0 = 0; - gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; - gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16); -#if defined (MDE_CPU_X64) - gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32); - gIdtTable[Index].Bits.Reserved_1 = 0; -#endif -} - -/** - Restore original Interrupt Descriptor Table Handler Address. - - @param Index The Index of the interrupt descriptor table handle. - -**/ -VOID -RestoreInterruptDescriptorTableHandlerAddress ( - IN UINTN Index - ) -{ - if (Index < mOrigIdtEntryCount) { - gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow; - gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh; -#if defined (MDE_CPU_X64) - gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper; -#endif - } - if (Index >= mOrigIdtEntryCount) - return; - CopyMem(gIdtTable + Index, mOrigIdtEntry + Index, - sizeof(gIdtTable[Index])); -} /** Initialize Interrupt Descriptor Table for interrupt handling. @@ -1139,95 +919,17 @@ InitInterruptDescriptorTable ( VOID ) { - EFI_STATUS Status; - IA32_DESCRIPTOR OldIdtPtr; - IA32_IDT_GATE_DESCRIPTOR *OldIdt; - UINTN OldIdtSize; - VOID *IdtPtrAlignmentBuffer; - IA32_DESCRIPTOR *IdtPtr; - UINTN Index; - UINT16 CurrentCs; - VOID *IntHandler; + EFI_STATUS Status; + EFI_VECTOR_HANDOFF_INFO *VectorInfoList; + EFI_VECTOR_HANDOFF_INFO *VectorInfo; - SetMem(ExternalVectorTable, sizeof(ExternalVectorTable), 0); - - // - // Get original IDT address and size. - // - AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr); - - if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) { - OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base; - OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); - // - // Save original IDT entry and IDT entry count. - // - mOrigIdtEntry = AllocateCopyPool(OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base); -// ASSERT (mOrigIdtEntry != NULL); - mOrigIdtEntryCount = (UINT16) OldIdtSize; - } else { - OldIdt = NULL; - OldIdtSize = 0; + VectorInfo = NULL; + Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList); + if (Status == EFI_SUCCESS && VectorInfoList != NULL) { + VectorInfo = VectorInfoList; } - - // - // Intialize IDT - // - CurrentCs = AsmReadCs(); - for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) { - // - // If the old IDT had a handler for this interrupt, then - // preserve it. - // - if (Index < OldIdtSize) { - IntHandler = - (VOID*) ( - OldIdt[Index].Bits.OffsetLow + - (((UINTN) OldIdt[Index].Bits.OffsetHigh) << 16) -#if defined (MDE_CPU_X64) - + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32) -#endif - ); - } else { - IntHandler = NULL; - } -#if 1 //patch by nms42 for AMD CPU - if (Index == 0x6F) { - IntHandler = NULL; - } -#endif - - gIdtTable[Index].Bits.Selector = CurrentCs; - gIdtTable[Index].Bits.Reserved_0 = 0; - gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; - SetInterruptDescriptorTableHandlerAddress (Index, IntHandler); - } - - // - // Load IDT Pointer - // - IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); - IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); -// IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); - IdtPtr->Base = (UINTN)(VOID*) gIdtTable; - IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1); - AsmWriteIdtr (IdtPtr); - - FreePool(IdtPtrAlignmentBuffer); - - // - // Initialize Exception Handlers - // - for (Index = OldIdtSize; Index < 32; Index++) { - Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler); -// ASSERT_EFI_ERROR(Status); - } - - // - // Set the pointer to the array of C based exception handling routines. - // - InitializeExternalVectorTablePtr (ExternalVectorTable); - + Status = InitializeCpuInterruptHandlers (VectorInfo); + ASSERT_EFI_ERROR (Status); } @@ -1249,6 +951,192 @@ IdleLoopEventCallback ( CpuSleep (); } +/** + Ensure the compatibility of a memory space descriptor with the MMIO aperture. + + The memory space descriptor can come from the GCD memory space map, or it can + represent a gap between two neighboring memory space descriptors. In the + latter case, the GcdMemoryType field is expected to be + EfiGcdMemoryTypeNonExistent. + + If the memory space descriptor already has type + EfiGcdMemoryTypeMemoryMappedIo, and its capabilities are a superset of the + required capabilities, then no action is taken -- it is by definition + compatible with the aperture. + + Otherwise, the intersection of the memory space descriptor is calculated with + the aperture. If the intersection is the empty set (no overlap), no action is + taken; the memory space descriptor is compatible with the aperture. + + Otherwise, the type of the descriptor is investigated again. If the type is + EfiGcdMemoryTypeNonExistent (representing a gap, or a genuine descriptor with + such a type), then an attempt is made to add the intersection as MMIO space + to the GCD memory space map, with the specified capabilities. This ensures + continuity for the aperture, and the descriptor is deemed compatible with the + aperture. + + Otherwise, the memory space descriptor is incompatible with the MMIO + aperture. + + @param[in] Base Base address of the aperture. + @param[in] Length Length of the aperture. + @param[in] Capabilities Capabilities required by the aperture. + @param[in] Descriptor The descriptor to ensure compatibility with the + aperture for. + + @retval EFI_SUCCESS The descriptor is compatible. The GCD memory + space map may have been updated, for + continuity within the aperture. + @retval EFI_INVALID_PARAMETER The descriptor is incompatible. + @return Error codes from gDS->AddMemorySpace(). +**/ +EFI_STATUS +IntersectMemoryDescriptor ( + IN UINT64 Base, + IN UINT64 Length, + IN UINT64 Capabilities, + IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor + ) +{ + UINT64 IntersectionBase; + UINT64 IntersectionEnd; + EFI_STATUS Status; + + if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo && + (Descriptor->Capabilities & Capabilities) == Capabilities) { + return EFI_SUCCESS; + } + + IntersectionBase = MAX (Base, Descriptor->BaseAddress); + IntersectionEnd = MIN (Base + Length, + Descriptor->BaseAddress + Descriptor->Length); + if (IntersectionBase >= IntersectionEnd) { + // + // The descriptor and the aperture don't overlap. + // + return EFI_SUCCESS; + } + + if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeNonExistent) { + Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo, + IntersectionBase, IntersectionEnd - IntersectionBase, + Capabilities); + + DEBUG ((EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE, + "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__, + IntersectionBase, IntersectionEnd, Status)); + return Status; + } + + DEBUG ((DEBUG_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts " + "with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__, + Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length, + (UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities, + Base, Base + Length, Capabilities)); + return EFI_INVALID_PARAMETER; +} + +/** + Add MMIO space to GCD. + The routine checks the GCD database and only adds those which are + not added in the specified range to GCD. + + @param Base Base address of the MMIO space. + @param Length Length of the MMIO space. + @param Capabilities Capabilities of the MMIO space. + + @retval EFI_SUCCESS The MMIO space was added successfully. +**/ +EFI_STATUS +AddMemoryMappedIoSpace ( + IN UINT64 Base, + IN UINT64 Length, + IN UINT64 Capabilities + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN NumberOfDescriptors; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; + + Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n", + gEfiCallerBaseName, __FUNCTION__, Status)); + return Status; + } + + for (Index = 0; Index < NumberOfDescriptors; Index++) { + Status = IntersectMemoryDescriptor (Base, Length, Capabilities, + &MemorySpaceMap[Index]); + if (EFI_ERROR (Status)) { + goto FreeMemorySpaceMap; + } + } + + DEBUG_CODE ( + // + // Make sure there are adjacent descriptors covering [Base, Base + Length). + // It is possible that they have not been merged; merging can be prevented + // by allocation and different capabilities. + // + UINT64 CheckBase; + EFI_STATUS CheckStatus; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + + for (CheckBase = Base; + CheckBase < Base + Length; + CheckBase = Descriptor.BaseAddress + Descriptor.Length) { + CheckStatus = gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor); + ASSERT_EFI_ERROR (CheckStatus); + ASSERT (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo); + ASSERT ((Descriptor.Capabilities & Capabilities) == Capabilities); + } + ); + +FreeMemorySpaceMap: + FreePool (MemorySpaceMap); + + return Status; +} + +/** + Add and allocate CPU local APIC memory mapped space. + + @param[in]ImageHandle Image handle this driver. + +**/ +VOID +AddLocalApicMemorySpace ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS BaseAddress; + + BaseAddress = (EFI_PHYSICAL_ADDRESS) GetLocalApicBaseAddress(); + Status = AddMemoryMappedIoSpace (BaseAddress, SIZE_4KB, EFI_MEMORY_UC); + ASSERT_EFI_ERROR (Status); + + // + // Try to allocate APIC memory mapped space, does not check return + // status because it may be allocated by other driver, or DXE Core if + // this range is built into Memory Allocation HOB. + // + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + EfiGcdMemoryTypeMemoryMappedIo, + 0, + SIZE_4KB, + &BaseAddress, + ImageHandle, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: %a: AllocateMemorySpace() Status - %r\n", + gEfiCallerBaseName, __FUNCTION__, Status)); + } +} /** Initialize the state information for the CPU Architectural Protocol. @@ -1269,9 +1157,11 @@ InitializeCpu ( ) { EFI_STATUS Status; + EFI_EVENT IdleLoopEvent; + InitializePageTableLib(); -// InitializeFloatingPointUnits (); //nah + InitializeFloatingPointUnits (); // // Make sure interrupts are disabled @@ -1288,11 +1178,6 @@ InitializeCpu ( // InitInterruptDescriptorTable (); - // - // Enable the local APIC for Virtual Wire Mode. - // - ProgramVirtualWireMode (); - // // Install CPU Architectural Protocol // @@ -1301,15 +1186,17 @@ InitializeCpu ( &gEfiCpuArchProtocolGuid, &gCpu, NULL ); -// ASSERT_EFI_ERROR(Status); - if (EFI_ERROR(Status)) { - return Status; - } + ASSERT_EFI_ERROR (Status); // // Refresh GCD memory space map according to MTRR value. // -// RefreshGcdMemoryAttributes (); + RefreshGcdMemoryAttributes (); + + // + // Add and allocate local APIC memory mapped space + // + AddLocalApicMemorySpace (ImageHandle); // // Setup a callback for idle events @@ -1322,7 +1209,9 @@ InitializeCpu ( &gIdleLoopEventGuid, &IdleLoopEvent ); -// ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); + + InitializeMpSupport (); return Status; } diff --git a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h similarity index 76% rename from CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.h rename to UefiCpuPkg/CpuDxe/CpuDxe.h index a75ec0593..9299eaa63 100644 --- a/CloverEFI/UefiCpuPkg/CpuDxe/CpuDxe.h +++ b/UefiCpuPkg/CpuDxe/CpuDxe.h @@ -1,14 +1,8 @@ /** @file - CPU DXE Module. + CPU DXE Module to produce CPU ARCH Protocol and CPU MP Protocol. - Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -18,6 +12,11 @@ #include #include +#include +#include + +#include +#include #include #include @@ -30,12 +29,15 @@ #include #include #include -#include +#include +#include +#include +#include +#include +#include -// -// -// -#define INTERRUPT_VECTOR_NUMBER 256 +#include +#include #define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \ EFI_MEMORY_WC | \ @@ -44,6 +46,16 @@ EFI_MEMORY_UCE \ ) +#define EFI_MEMORY_PAGETYPE_MASK (EFI_MEMORY_RP | \ + EFI_MEMORY_XP | \ + EFI_MEMORY_RO \ + ) + +#define HEAP_GUARD_NONSTOP_MODE \ + ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT6|BIT4|BIT1|BIT0)) > BIT6) + +#define NULL_DETECTION_NONSTOP_MODE \ + ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT6|BIT0)) > BIT6) /** Flush CPU data cache. If the instruction cache is fully coherent @@ -196,7 +208,7 @@ CpuGetTimerValue ( ); /** - Set memory cacheability attributes for given range of memeory. + Set memory cacheability attributes for given range of memory. @param This Protocol instance structure @param BaseAddress Specifies the start address of the @@ -220,30 +232,6 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes ); -/** - Label of base address of IDT vector 0. - - This is just a label of base address of IDT vector 0. - -**/ -VOID -EFIAPI -AsmIdtVector00 ( - VOID - ); - -/** - Initializes the pointer to the external interrupt vector table. - - @param VectorTable Address of the external interrupt vector table. - -**/ -VOID -EFIAPI -InitializeExternalVectorTablePtr ( - EFI_CPU_INTERRUPT_HANDLER *VectorTable - ); - /** Initialize Global Descriptor Table. @@ -278,15 +266,47 @@ SetDataSelectors ( ); /** - Restore original Interrupt Descriptor Table Handler Address. + Update GCD memory space attributes according to current page table setup. +**/ +VOID +RefreshGcdMemoryAttributesFromPaging ( + VOID + ); - @param Index The Index of the interrupt descriptor table handle. +/** + Special handler for #DB exception, which will restore the page attributes + (not-present). It should work with #PF handler which will set pages to + 'present'. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. **/ VOID -RestoreInterruptDescriptorTableHandlerAddress ( - IN UINTN Index +EFIAPI +DebugExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext ); +/** + Special handler for #PF exception, which will set the pages which caused + #PF to be 'present'. The attribute of those pages should be restored in + the subsequent #DB handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. + +**/ +VOID +EFIAPI +PageFaultExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ); + +extern BOOLEAN mIsAllocatingPageTable; +extern UINTN mNumberOfProcessors; + #endif diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf new file mode 100644 index 000000000..d87fe503d --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf @@ -0,0 +1,88 @@ +## @file +# CPU driver installs CPU Architecture Protocol and CPU MP protocol. +# +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuDxe + MODULE_UNI_FILE = CpuDxe.uni + FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitializeCpu + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + CpuLib + DebugLib + DxeServicesTableLib + MemoryAllocationLib + MtrrLib + UefiBootServicesTableLib + UefiDriverEntryPoint + LocalApicLib + UefiCpuLib + UefiLib + CpuExceptionHandlerLib + HobLib + ReportStatusCodeLib + MpInitLib + TimerLib + PeCoffGetEntryPointLib + +[Sources] + CpuDxe.c + CpuDxe.h + CpuGdt.c + CpuGdt.h + CpuMp.c + CpuMp.h + CpuPageTable.h + CpuPageTable.c + +[Sources.IA32] + Ia32/CpuAsm.nasm + Ia32/PagingAttribute.c + +[Sources.X64] + X64/CpuAsm.nasm + X64/PagingAttribute.c + +[Protocols] + gEfiCpuArchProtocolGuid ## PRODUCES + gEfiMpServiceProtocolGuid ## PRODUCES + gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gIdleLoopEventGuid ## CONSUMES ## Event + gEfiVectorHandoffTableGuid ## SOMETIMES_CONSUMES ## SystemTable + +[Ppis] + gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB + gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuDxeExtra.uni diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.uni b/UefiCpuPkg/CpuDxe/CpuDxe.uni new file mode 100644 index 000000000..85d977d8c --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuDxe.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. +// +// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. +// +// Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol." + diff --git a/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni b/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni new file mode 100644 index 000000000..5bb116fee --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuDxe Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU Architectural and CPU Multi-processor DXE Driver" + + diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.c b/UefiCpuPkg/CpuDxe/CpuGdt.c new file mode 100644 index 000000000..64efadeba --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuGdt.c @@ -0,0 +1,155 @@ +/** @file + C based implementation of IA32 interrupt handling only + requiring a minimal assembly interrupt entry point. + + Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuDxe.h" +#include "CpuGdt.h" + +// +// Global descriptor table (GDT) Template +// +STATIC GDT_ENTRIES GdtTemplate = { + // + // NULL_SEL + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // LINEAR_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x092, // present, ring 0, data, read/write + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // LINEAR_CODE_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x09F, // present, ring 0, code, execute/read, conforming, accessed + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // SYS_DATA_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x093, // present, ring 0, data, read/write, accessed + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // SYS_CODE_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x09A, // present, ring 0, code, execute/read + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // SPARE4_SEL + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // LINEAR_DATA64_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x092, // present, ring 0, data, read/write + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // LINEAR_CODE64_SEL + // + { + 0x0FFFF, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x09A, // present, ring 0, code, execute/read + 0x0AF, // page-granular, 64-bit code + 0x0, // base (high) + }, + // + // SPARE5_SEL + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, +}; + +/** + Initialize Global Descriptor Table. + +**/ +VOID +InitGlobalDescriptorTable ( + VOID + ) +{ + GDT_ENTRIES *gdt; + IA32_DESCRIPTOR gdtPtr; + + // + // Allocate Runtime Data for the GDT + // + gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); + ASSERT (gdt != NULL); + gdt = ALIGN_POINTER (gdt, 8); + + // + // Initialize all GDT entries + // + CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate)); + + // + // Write GDT register + // + gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt; + gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); + AsmWriteGdtr (&gdtPtr); + + // + // Update selector (segment) registers base on new GDT + // + SetCodeSelector ((UINT16)CPU_CODE_SEL); + SetDataSelectors ((UINT16)CPU_DATA_SEL); +} + diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.h b/UefiCpuPkg/CpuDxe/CpuGdt.h new file mode 100644 index 000000000..3a0210b2f --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuGdt.h @@ -0,0 +1,68 @@ +/** @file + C based implementation of IA32 interrupt handling only + requiring a minimal assembly interrupt entry point. + + Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_GDT_H_ +#define _CPU_GDT_H_ + +// +// Local structure definitions +// + +#pragma pack (1) + +// +// Global Descriptor Entry structures +// + +typedef struct _GDT_ENTRY { + UINT16 Limit15_0; + UINT16 Base15_0; + UINT8 Base23_16; + UINT8 Type; + UINT8 Limit19_16_and_flags; + UINT8 Base31_24; +} GDT_ENTRY; + +typedef +struct _GDT_ENTRIES { + GDT_ENTRY Null; + GDT_ENTRY Linear; + GDT_ENTRY LinearCode; + GDT_ENTRY SysData; + GDT_ENTRY SysCode; + GDT_ENTRY Spare4; + GDT_ENTRY LinearData64; + GDT_ENTRY LinearCode64; + GDT_ENTRY Spare5; +} GDT_ENTRIES; + +#pragma pack () + +#define NULL_SEL OFFSET_OF (GDT_ENTRIES, Null) +#define LINEAR_SEL OFFSET_OF (GDT_ENTRIES, Linear) +#define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode) +#define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData) +#define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode) +#define SPARE4_SEL OFFSET_OF (GDT_ENTRIES, Spare4) +#define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64) +#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64) +#define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5) + +#if defined (MDE_CPU_IA32) +#define CPU_CODE_SEL LINEAR_CODE_SEL +#define CPU_DATA_SEL LINEAR_SEL +#elif defined (MDE_CPU_X64) +#define CPU_CODE_SEL LINEAR_CODE64_SEL +#define CPU_DATA_SEL LINEAR_DATA64_SEL +#else +#error CPU type not supported for CPU GDT initialization! +#endif + +#endif // _CPU_GDT_H_ + diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c new file mode 100644 index 000000000..60ede38df --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -0,0 +1,849 @@ +/** @file + CPU DXE Module to produce CPU MP Protocol. + + Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuDxe.h" +#include "CpuMp.h" + +EFI_HANDLE mMpServiceHandle = NULL; +UINTN mNumberOfProcessors = 1; + +EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = { + GetNumberOfProcessors, + GetProcessorInfo, + StartupAllAPs, + StartupThisAP, + SwitchBSP, + EnableDisableAP, + WhoAmI +}; + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Protocol provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL. + +**/ +EFI_STATUS +EFIAPI +GetNumberOfProcessors ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ) +{ + if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) { + return EFI_INVALID_PARAMETER; + } + + return MpInitLibGetNumberOfProcessors ( + NumberOfProcessors, + NumberOfEnabledProcessors + ); +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + +**/ +EFI_STATUS +EFIAPI +GetProcessorInfo ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL); +} + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking and non-blocking requests. The non-blocking requests use EFI + events so the BSP can detect when the APs have finished. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all + APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking + mode, and the BSP returns from this service without waiting for APs. If a + non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled, then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Protocol does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. EFI services and protocols may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroseconds expires. + + In non-blocking execution mode, BSP is freed to return to the caller and then + proceed to the next task without having to wait for APs. The following + sequence needs to occur in a non-blocking execution mode: + + -# The caller that intends to use this MP Services Protocol in non-blocking + mode creates WaitEvent by calling the EFI CreateEvent() service. The caller + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent + is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests + the function specified by Procedure to be started on all the enabled APs, + and releases the BSP to continue with other tasks. + -# The caller can use the CheckEvent() and WaitForEvent() services to check + the state of the WaitEvent created in step 1. + -# When the APs complete their task or TimeoutInMicroSeconds expires, the MP + Service signals WaitEvent by calling the EFI SignalEvent() function. If + FailedCpuList is not NULL, its content is available when WaitEvent is + signaled. If all APs returned from Procedure prior to the timeout, then + FailedCpuList is set to NULL. If not all APs return from Procedure before + the timeout, then FailedCpuList is filled in with the list of the failed + APs. The buffer is allocated by MP Service Protocol using AllocatePool(). + It is the caller's responsibility to free the buffer with FreePool() service. + -# This invocation of SignalEvent() function informs the caller that invoked + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed + the specified task or a timeout occurred. The contents of FailedCpuList + can be examined to determine which APs did not complete the specified task + prior to the timeout. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroseconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroseconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Service Protocol, + and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +StartupAllAPs ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ) +{ + return MpInitLibStartupAllAPs ( + Procedure, + SingleThread, + WaitEvent, + TimeoutInMicroseconds, + ProcedureArgument, + FailedCpuList + ); +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to either wait for the completion + of the AP or just proceed with the next task by using the EFI event mechanism. + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking + execution support. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. If WaitEvent + is NULL, execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSeconds expires. Otherwise, execution is in non-blocking mode. + BSP proceeds to the next task without waiting for the AP. If a non-blocking mode + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, + then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and + EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +StartupThisAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ) +{ + return MpInitLibStartupThisAP ( + Procedure, + ProcessorNumber, + WaitEvent, + TimeoutInMicroseconds, + ProcedureArgument, + Finished + ); +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + +**/ +EFI_STATUS +EFIAPI +SwitchBSP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP); +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. This service may not be supported + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + +**/ +EFI_STATUS +EFIAPI +EnableDisableAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag); +} + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +EFI_STATUS +EFIAPI +WhoAmI ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ) +{ + return MpInitLibWhoAmI (ProcessorNumber);; +} + +/** + Collects BIST data from HOB. + + This function collects BIST data from HOB built from Sec Platform Information + PPI or SEC Platform Information2 PPI. + +**/ +VOID +CollectBistDataFromHob ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; + EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation; + UINTN NumberOfData; + EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance; + EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance; + UINTN ProcessorNumber; + EFI_PROCESSOR_INFORMATION ProcessorInfo; + EFI_HEALTH_FLAGS BistData; + UINTN CpuInstanceNumber; + + SecPlatformInformation2 = NULL; + SecPlatformInformation = NULL; + + // + // Get gEfiSecPlatformInformation2PpiGuid Guided HOB firstly + // + GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid); + if (GuidHob != NULL) { + // + // Sec Platform Information2 PPI includes BSP/APs' BIST information + // + SecPlatformInformation2 = GET_GUID_HOB_DATA (GuidHob); + NumberOfData = SecPlatformInformation2->NumberOfCpus; + CpuInstance = SecPlatformInformation2->CpuInstance; + } else { + // + // Otherwise, get gEfiSecPlatformInformationPpiGuid Guided HOB + // + GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid); + if (GuidHob != NULL) { + SecPlatformInformation = GET_GUID_HOB_DATA (GuidHob); + NumberOfData = 1; + // + // SEC Platform Information only includes BSP's BIST information + // does not have BSP's APIC ID + // + BspCpuInstance.CpuLocation = GetApicId (); + BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32; + CpuInstance = &BspCpuInstance; + } else { + DEBUG ((DEBUG_INFO, "Does not find any HOB stored CPU BIST information!\n")); + // + // Does not find any HOB stored BIST information + // + return; + } + } + + for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) { + MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData); + for (CpuInstanceNumber = 0; CpuInstanceNumber < NumberOfData; CpuInstanceNumber++) { + if (ProcessorInfo.ProcessorId == CpuInstance[CpuInstanceNumber].CpuLocation) { + // + // Update CPU health status for MP Services Protocol according to BIST data. + // + BistData = CpuInstance[CpuInstanceNumber].InfoRecord.IA32HealthFlags; + } + } + if (BistData.Uint32 != 0) { + // + // Report Status Code that self test is failed + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST) + ); + } + } +} + +/** + Get GDT register value. + + This function is mainly for AP purpose because AP may have different GDT + table than BSP. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +GetGdtr ( + IN OUT VOID *Buffer + ) +{ + AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer); +} + +/** + Initializes CPU exceptions handlers for the sake of stack switch requirement. + + This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly + for the sake of AP's init because of EFI_AP_PROCEDURE API requirement. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +InitializeExceptionStackSwitchHandlers ( + IN OUT VOID *Buffer + ) +{ + CPU_EXCEPTION_INIT_DATA *EssData; + IA32_DESCRIPTOR Idtr; + EFI_STATUS Status; + + EssData = Buffer; + // + // We don't plan to replace IDT table with a new one, but we should not assume + // the AP's IDT is the same as BSP's IDT either. + // + AsmReadIdtr (&Idtr); + EssData->Ia32.IdtTable = (VOID *)Idtr.Base; + EssData->Ia32.IdtTableSize = Idtr.Limit + 1; + Status = InitializeCpuExceptionHandlersEx (NULL, EssData); + ASSERT_EFI_ERROR (Status); +} + +/** + Initializes MP exceptions handlers for the sake of stack switch requirement. + + This function will allocate required resources required to setup stack switch + and pass them through CPU_EXCEPTION_INIT_DATA to each logic processor. + +**/ +VOID +InitializeMpExceptionStackSwitchHandlers ( + VOID + ) +{ + UINTN Index; + UINTN Bsp; + UINTN ExceptionNumber; + UINTN OldGdtSize; + UINTN NewGdtSize; + UINTN NewStackSize; + IA32_DESCRIPTOR Gdtr; + CPU_EXCEPTION_INIT_DATA EssData; + UINT8 *GdtBuffer; + UINT8 *StackTop; + + ExceptionNumber = FixedPcdGetSize (PcdCpuStackSwitchExceptionList); + NewStackSize = FixedPcdGet32 (PcdCpuKnownGoodStackSize) * ExceptionNumber; + + StackTop = AllocateRuntimeZeroPool (NewStackSize * mNumberOfProcessors); + ASSERT (StackTop != NULL); + StackTop += NewStackSize * mNumberOfProcessors; + + // + // The default exception handlers must have been initialized. Let's just skip + // it in this method. + // + EssData.Ia32.Revision = CPU_EXCEPTION_INIT_DATA_REV; + EssData.Ia32.InitDefaultHandlers = FALSE; + + EssData.Ia32.StackSwitchExceptions = FixedPcdGetPtr(PcdCpuStackSwitchExceptionList); + EssData.Ia32.StackSwitchExceptionNumber = ExceptionNumber; + EssData.Ia32.KnownGoodStackSize = FixedPcdGet32(PcdCpuKnownGoodStackSize); + + // + // Initialize Gdtr to suppress incorrect compiler/analyzer warnings. + // + Gdtr.Base = 0; + Gdtr.Limit = 0; + MpInitLibWhoAmI (&Bsp); + for (Index = 0; Index < mNumberOfProcessors; ++Index) { + // + // To support stack switch, we need to re-construct GDT but not IDT. + // + if (Index == Bsp) { + GetGdtr (&Gdtr); + } else { + // + // AP might have different size of GDT from BSP. + // + MpInitLibStartupThisAP (GetGdtr, Index, NULL, 0, (VOID *)&Gdtr, NULL); + } + + // + // X64 needs only one TSS of current task working for all exceptions + // because of its IST feature. IA32 needs one TSS for each exception + // in addition to current task. Since AP is not supposed to allocate + // memory, we have to do it in BSP. To simplify the code, we allocate + // memory for IA32 case to cover both IA32 and X64 exception stack + // switch. + // + // Layout of memory to allocate for each processor: + // -------------------------------- + // | Alignment | (just in case) + // -------------------------------- + // | | + // | Original GDT | + // | | + // -------------------------------- + // | Current task descriptor | + // -------------------------------- + // | | + // | Exception task descriptors | X ExceptionNumber + // | | + // -------------------------------- + // | Current task-state segment | + // -------------------------------- + // | | + // | Exception task-state segment | X ExceptionNumber + // | | + // -------------------------------- + // + OldGdtSize = Gdtr.Limit + 1; + EssData.Ia32.ExceptionTssDescSize = sizeof (IA32_TSS_DESCRIPTOR) * + (ExceptionNumber + 1); + EssData.Ia32.ExceptionTssSize = sizeof (IA32_TASK_STATE_SEGMENT) * + (ExceptionNumber + 1); + NewGdtSize = sizeof (IA32_TSS_DESCRIPTOR) + + OldGdtSize + + EssData.Ia32.ExceptionTssDescSize + + EssData.Ia32.ExceptionTssSize; + + GdtBuffer = AllocateRuntimeZeroPool (NewGdtSize); + ASSERT (GdtBuffer != NULL); + + // + // Make sure GDT table alignment + // + EssData.Ia32.GdtTable = ALIGN_POINTER(GdtBuffer, sizeof (IA32_TSS_DESCRIPTOR)); + NewGdtSize -= ((UINT8 *)EssData.Ia32.GdtTable - GdtBuffer); + EssData.Ia32.GdtTableSize = NewGdtSize; + + EssData.Ia32.ExceptionTssDesc = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize); + EssData.Ia32.ExceptionTss = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize + + EssData.Ia32.ExceptionTssDescSize); + + EssData.Ia32.KnownGoodStackTop = (UINTN)StackTop; + DEBUG ((DEBUG_INFO, + "Exception stack top[cpu%lu]: 0x%lX\n", + (UINT64)(UINTN)Index, + (UINT64)(UINTN)StackTop)); + + if (Index == Bsp) { + InitializeExceptionStackSwitchHandlers (&EssData); + } else { + MpInitLibStartupThisAP ( + InitializeExceptionStackSwitchHandlers, + Index, + NULL, + 0, + (VOID *)&EssData, + NULL + ); + } + + StackTop -= NewStackSize; + } +} + +/** + Initializes MP exceptions handlers for special features, such as Heap Guard + and Stack Guard. +**/ +VOID +InitializeMpExceptionHandlers ( + VOID + ) +{ + // + // Enable non-stop mode for #PF triggered by Heap Guard or NULL Pointer + // Detection. + // + if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) { + RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler); + RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, PageFaultExceptionHandler); + } + + // + // Setup stack switch for Stack Guard feature. + // + if (PcdGetBool (PcdCpuStackGuard)) { + InitializeMpExceptionStackSwitchHandlers (); + } +} + +/** + Initialize Multi-processor support. + +**/ +VOID +InitializeMpSupport ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + + // + // Wakeup APs to do initialization + // + Status = MpInitLibInitialize (); + ASSERT_EFI_ERROR (Status); + + MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors); + mNumberOfProcessors = NumberOfProcessors; + DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mNumberOfProcessors)); + + // + // Initialize special exception handlers for each logic processor. + // + InitializeMpExceptionHandlers (); + + // + // Update CPU healthy information from Guided HOB + // + CollectBistDataFromHob (); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &mMpServiceHandle, + &gEfiMpServiceProtocolGuid, &mMpServicesTemplate, + NULL + ); + ASSERT_EFI_ERROR (Status); +} + diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h new file mode 100644 index 000000000..4ee171d8c --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuMp.h @@ -0,0 +1,470 @@ +/** @file + CPU DXE MP support + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_MP_H_ +#define _CPU_MP_H_ + +/** + Initialize Multi-processor support. + +**/ +VOID +InitializeMpSupport ( + VOID + ); + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Protocol provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL. + +**/ +EFI_STATUS +EFIAPI +GetNumberOfProcessors ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + +**/ +EFI_STATUS +EFIAPI +GetProcessorInfo ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking and non-blocking requests. The non-blocking requests use EFI + events so the BSP can detect when the APs have finished. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all + APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking + mode, and the BSP returns from this service without waiting for APs. If a + non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled, then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Protocol does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. EFI services and protocols may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroseconds expires. + + In non-blocking execution mode, BSP is freed to return to the caller and then + proceed to the next task without having to wait for APs. The following + sequence needs to occur in a non-blocking execution mode: + + -# The caller that intends to use this MP Services Protocol in non-blocking + mode creates WaitEvent by calling the EFI CreateEvent() service. The caller + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent + is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests + the function specified by Procedure to be started on all the enabled APs, + and releases the BSP to continue with other tasks. + -# The caller can use the CheckEvent() and WaitForEvent() services to check + the state of the WaitEvent created in step 1. + -# When the APs complete their task or TimeoutInMicroSeconds expires, the MP + Service signals WaitEvent by calling the EFI SignalEvent() function. If + FailedCpuList is not NULL, its content is available when WaitEvent is + signaled. If all APs returned from Procedure prior to the timeout, then + FailedCpuList is set to NULL. If not all APs return from Procedure before + the timeout, then FailedCpuList is filled in with the list of the failed + APs. The buffer is allocated by MP Service Protocol using AllocatePool(). + It is the caller's responsibility to free the buffer with FreePool() service. + -# This invocation of SignalEvent() function informs the caller that invoked + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed + the specified task or a timeout occurred. The contents of FailedCpuList + can be examined to determine which APs did not complete the specified task + prior to the timeout. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroseconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroseconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Service Protocol, + and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +StartupAllAPs ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to either wait for the completion + of the AP or just proceed with the next task by using the EFI event mechanism. + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking + execution support. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. If WaitEvent + is NULL, execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSeconds expires. Otherwise, execution is in non-blocking mode. + BSP proceeds to the next task without waiting for the AP. If a non-blocking mode + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, + then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and + EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroseconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure or TimeoutInMicroseconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +StartupThisAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + +**/ +EFI_STATUS +EFIAPI +SwitchBSP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. This service may not be supported + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + +**/ +EFI_STATUS +EFIAPI +EnableDisableAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[out] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +EFI_STATUS +EFIAPI +WhoAmI ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ); + +#endif // _CPU_MP_H_ + diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTable.c new file mode 100644 index 000000000..0a02cb3f6 --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c @@ -0,0 +1,1382 @@ +/** @file + Page table management support. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CpuDxe.h" +#include "CpuPageTable.h" + +/// +/// Page Table Entry +/// +#define IA32_PG_P BIT0 +#define IA32_PG_RW BIT1 +#define IA32_PG_U BIT2 +#define IA32_PG_WT BIT3 +#define IA32_PG_CD BIT4 +#define IA32_PG_A BIT5 +#define IA32_PG_D BIT6 +#define IA32_PG_PS BIT7 +#define IA32_PG_PAT_2M BIT12 +#define IA32_PG_PAT_4K IA32_PG_PS +#define IA32_PG_PMNT BIT62 +#define IA32_PG_NX BIT63 + +#define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P) +// +// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE +// X64 PAE PDPTE does not have such restriction +// +#define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P) + +#define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS) + +#define PAGING_4K_MASK 0xFFF +#define PAGING_2M_MASK 0x1FFFFF +#define PAGING_1G_MASK 0x3FFFFFFF + +#define PAGING_PAE_INDEX_MASK 0x1FF + +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull +#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull + +#define MAX_PF_ENTRY_COUNT 10 +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 +#define IA32_PF_EC_ID BIT4 + +typedef enum { + PageNone, + Page4K, + Page2M, + Page1G, +} PAGE_ATTRIBUTE; + +typedef struct { + PAGE_ATTRIBUTE Attribute; + UINT64 Length; + UINT64 AddressMask; +} PAGE_ATTRIBUTE_TABLE; + +typedef enum { + PageActionAssign, + PageActionSet, + PageActionClear, +} PAGE_ACTION; + +PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { + {Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64}, + {Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64}, + {Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64}, +}; + +PAGE_TABLE_POOL *mPageTablePool = NULL; +BOOLEAN mPageTablePoolLock = FALSE; +PAGE_TABLE_LIB_PAGING_CONTEXT mPagingContext; +EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL; + +// +// Record the page fault exception count for one instruction execution. +// +UINTN *mPFEntryCount; +UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; + +/** + Check if current execution environment is in SMM mode or not, via + EFI_SMM_BASE2_PROTOCOL. + + This is necessary because of the fact that MdePkg\Library\SmmMemoryAllocationLib + supports to free memory outside SMRAM. The library will call gBS->FreePool() or + gBS->FreePages() and then SetMemorySpaceAttributes interface in turn to change + memory paging attributes during free operation, if some memory related features + are enabled (like Heap Guard). + + This means that SetMemorySpaceAttributes() has chance to run in SMM mode. This + will cause incorrect result because SMM mode always loads its own page tables, + which are usually different from DXE. This function can be used to detect such + situation and help to avoid further misoperations. + + @retval TRUE In SMM mode. + @retval FALSE Not in SMM mode. +**/ +BOOLEAN +IsInSmm ( + VOID + ) +{ + BOOLEAN InSmm; + + InSmm = FALSE; + if (mSmmBase2 == NULL) { + gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&mSmmBase2); + } + + if (mSmmBase2 != NULL) { + mSmmBase2->InSmm (mSmmBase2, &InSmm); + } + + // + // mSmmBase2->InSmm() can only detect if the caller is running in SMRAM + // or from SMM driver. It cannot tell if the caller is running in SMM mode. + // Check page table base address to guarantee that because SMM mode willl + // load its own page table. + // + return (InSmm && + mPagingContext.ContextData.X64.PageTableBase != (UINT64)AsmReadCr3()); +} + +/** + Return current paging context. + + @param[in,out] PagingContext The paging context. +**/ +VOID +GetCurrentPagingContext ( + IN OUT PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext + ) +{ + UINT32 RegEax; + CPUID_EXTENDED_CPU_SIG_EDX RegEdx; + MSR_IA32_EFER_REGISTER MsrEfer; + IA32_CR4 Cr4; + IA32_CR0 Cr0; + UINT32 *Attributes; + UINTN *PageTableBase; + + // + // Don't retrieve current paging context from processor if in SMM mode. + // + if (!IsInSmm ()) { + ZeroMem (&mPagingContext, sizeof(mPagingContext)); + if (sizeof(UINTN) == sizeof(UINT64)) { + mPagingContext.MachineType = IMAGE_FILE_MACHINE_X64; + } else { + mPagingContext.MachineType = IMAGE_FILE_MACHINE_I386; + } + + GetPagingDetails (&mPagingContext.ContextData, &PageTableBase, &Attributes); + + Cr0.UintN = AsmReadCr0 (); + Cr4.UintN = AsmReadCr4 (); + + if (Cr0.Bits.PG != 0) { + *PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64); + } else { + *PageTableBase = 0; + } + if (Cr0.Bits.WP != 0) { + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE; + } + if (Cr4.Bits.PSE != 0) { + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE; + } + if (Cr4.Bits.PAE != 0) { + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE; + } + if (Cr4.Bits.LA57 != 0) { + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL; + } + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32); + + if (RegEdx.Bits.NX != 0) { + // XD supported + MsrEfer.Uint64 = AsmReadMsr64(MSR_CORE_IA32_EFER); + if (MsrEfer.Bits.NXE != 0) { + // XD activated + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED; + } + } + + if (RegEdx.Bits.Page1GB != 0) { + *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT; + } + } + } + + // + // This can avoid getting SMM paging context if in SMM mode. We cannot assume + // SMM mode shares the same paging context as DXE. + // + CopyMem (PagingContext, &mPagingContext, sizeof (mPagingContext)); +} + +/** + Return length according to page attributes. + + @param[in] PageAttributes The page attribute of the page entry. + + @return The length of page entry. +**/ +UINTN +PageAttributeToLength ( + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mPageAttributeTable)/sizeof(mPageAttributeTable[0]); Index++) { + if (PageAttribute == mPageAttributeTable[Index].Attribute) { + return (UINTN)mPageAttributeTable[Index].Length; + } + } + return 0; +} + +/** + Return address mask according to page attributes. + + @param[in] PageAttributes The page attribute of the page entry. + + @return The address mask of page entry. +**/ +UINTN +PageAttributeToMask ( + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mPageAttributeTable)/sizeof(mPageAttributeTable[0]); Index++) { + if (PageAttribute == mPageAttributeTable[Index].Attribute) { + return (UINTN)mPageAttributeTable[Index].AddressMask; + } + } + return 0; +} + +/** + Return page table entry to match the address. + + @param[in] PagingContext The paging context. + @param[in] Address The address to be checked. + @param[out] PageAttributes The page attribute of the page entry. + + @return The page entry. +**/ +VOID * +GetPageTableEntry ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext, + IN PHYSICAL_ADDRESS Address, + OUT PAGE_ATTRIBUTE *PageAttribute + ) +{ + UINTN Index1; + UINTN Index2; + UINTN Index3; + UINTN Index4; + UINTN Index5; + UINT64 *L1PageTable; + UINT64 *L2PageTable; + UINT64 *L3PageTable; + UINT64 *L4PageTable; + UINT64 *L5PageTable; + UINT64 AddressEncMask; + + ASSERT (PagingContext != NULL); + + Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK; + Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK; + Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK; + Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK; + Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK; + + // Make sure AddressEncMask is contained to smallest supported address field. + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + if (PagingContext->MachineType == IMAGE_FILE_MACHINE_X64) { + if ((PagingContext->ContextData.X64.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL) != 0) { + L5PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase; + if (L5PageTable[Index5] == 0) { + *PageAttribute = PageNone; + return NULL; + } + + L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + } else { + L4PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase; + } + if (L4PageTable[Index4] == 0) { + *PageAttribute = PageNone; + return NULL; + } + + L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + } else { + ASSERT((PagingContext->ContextData.Ia32.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0); + L3PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.Ia32.PageTableBase; + } + if (L3PageTable[Index3] == 0) { + *PageAttribute = PageNone; + return NULL; + } + if ((L3PageTable[Index3] & IA32_PG_PS) != 0) { + // 1G + *PageAttribute = Page1G; + return &L3PageTable[Index3]; + } + + L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L2PageTable[Index2] == 0) { + *PageAttribute = PageNone; + return NULL; + } + if ((L2PageTable[Index2] & IA32_PG_PS) != 0) { + // 2M + *PageAttribute = Page2M; + return &L2PageTable[Index2]; + } + + // 4k + L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if ((L1PageTable[Index1] == 0) && (Address != 0)) { + *PageAttribute = PageNone; + return NULL; + } + *PageAttribute = Page4K; + return &L1PageTable[Index1]; +} + +/** + Return memory attributes of page entry. + + @param[in] PageEntry The page entry. + + @return Memory attributes of page entry. +**/ +UINT64 +GetAttributesFromPageEntry ( + IN UINT64 *PageEntry + ) +{ + UINT64 Attributes; + Attributes = 0; + if ((*PageEntry & IA32_PG_P) == 0) { + Attributes |= EFI_MEMORY_RP; + } + if ((*PageEntry & IA32_PG_RW) == 0) { + Attributes |= EFI_MEMORY_RO; + } + if ((*PageEntry & IA32_PG_NX) != 0) { + Attributes |= EFI_MEMORY_XP; + } + return Attributes; +} + +/** + Modify memory attributes of page entry. + + @param[in] PagingContext The paging context. + @param[in] PageEntry The page entry. + @param[in] Attributes The bit mask of attributes to modify for the memory region. + @param[in] PageAction The page action. + @param[out] IsModified TRUE means page table modified. FALSE means page table not modified. +**/ +VOID +ConvertPageEntryAttribute ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext, + IN UINT64 *PageEntry, + IN UINT64 Attributes, + IN PAGE_ACTION PageAction, + OUT BOOLEAN *IsModified + ) +{ + UINT64 CurrentPageEntry; + UINT64 NewPageEntry; + UINT32 *PageAttributes; + + CurrentPageEntry = *PageEntry; + NewPageEntry = CurrentPageEntry; + if ((Attributes & EFI_MEMORY_RP) != 0) { + switch (PageAction) { + case PageActionAssign: + case PageActionSet: + NewPageEntry &= ~(UINT64)IA32_PG_P; + break; + case PageActionClear: + NewPageEntry |= IA32_PG_P; + break; + } + } else { + switch (PageAction) { + case PageActionAssign: + NewPageEntry |= IA32_PG_P; + break; + case PageActionSet: + case PageActionClear: + break; + } + } + if ((Attributes & EFI_MEMORY_RO) != 0) { + switch (PageAction) { + case PageActionAssign: + case PageActionSet: + NewPageEntry &= ~(UINT64)IA32_PG_RW; + break; + case PageActionClear: + NewPageEntry |= IA32_PG_RW; + break; + } + } else { + switch (PageAction) { + case PageActionAssign: + NewPageEntry |= IA32_PG_RW; + break; + case PageActionSet: + case PageActionClear: + break; + } + } + + GetPagingDetails (&PagingContext->ContextData, NULL, &PageAttributes); + + if ((*PageAttributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) { + if ((Attributes & EFI_MEMORY_XP) != 0) { + switch (PageAction) { + case PageActionAssign: + case PageActionSet: + NewPageEntry |= IA32_PG_NX; + break; + case PageActionClear: + NewPageEntry &= ~IA32_PG_NX; + break; + } + } else { + switch (PageAction) { + case PageActionAssign: + NewPageEntry &= ~IA32_PG_NX; + break; + case PageActionSet: + case PageActionClear: + break; + } + } + } + *PageEntry = NewPageEntry; + if (CurrentPageEntry != NewPageEntry) { + *IsModified = TRUE; + DEBUG ((DEBUG_VERBOSE, "ConvertPageEntryAttribute 0x%lx", CurrentPageEntry)); + DEBUG ((DEBUG_VERBOSE, "->0x%lx\n", NewPageEntry)); + } else { + *IsModified = FALSE; + } +} + +/** + This function returns if there is need to split page entry. + + @param[in] BaseAddress The base address to be checked. + @param[in] Length The length to be checked. + @param[in] PageEntry The page entry to be checked. + @param[in] PageAttribute The page attribute of the page entry. + + @retval SplitAttributes on if there is need to split page entry. +**/ +PAGE_ATTRIBUTE +NeedSplitPage ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 *PageEntry, + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINT64 PageEntryLength; + + PageEntryLength = PageAttributeToLength (PageAttribute); + + if (((BaseAddress & (PageEntryLength - 1)) == 0) && (Length >= PageEntryLength)) { + return PageNone; + } + + if (((BaseAddress & PAGING_2M_MASK) != 0) || (Length < SIZE_2MB)) { + return Page4K; + } + + return Page2M; +} + +/** + This function splits one page entry to small page entries. + + @param[in] PageEntry The page entry to be splitted. + @param[in] PageAttribute The page attribute of the page entry. + @param[in] SplitAttribute How to split the page entry. + @param[in] AllocatePagesFunc If page split is needed, this function is used to allocate more pages. + + @retval RETURN_SUCCESS The page entry is splitted. + @retval RETURN_UNSUPPORTED The page entry does not support to be splitted. + @retval RETURN_OUT_OF_RESOURCES No resource to split page entry. +**/ +RETURN_STATUS +SplitPage ( + IN UINT64 *PageEntry, + IN PAGE_ATTRIBUTE PageAttribute, + IN PAGE_ATTRIBUTE SplitAttribute, + IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc + ) +{ + UINT64 BaseAddress; + UINT64 *NewPageEntry; + UINTN Index; + UINT64 AddressEncMask; + + ASSERT (PageAttribute == Page2M || PageAttribute == Page1G); + + ASSERT (AllocatePagesFunc != NULL); + + // Make sure AddressEncMask is contained to smallest supported address field. + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + if (PageAttribute == Page2M) { + // + // Split 2M to 4K + // + ASSERT (SplitAttribute == Page4K); + if (SplitAttribute == Page4K) { + NewPageEntry = AllocatePagesFunc (1); + DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); + if (NewPageEntry == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + BaseAddress = *PageEntry & ~AddressEncMask & PAGING_2M_ADDRESS_MASK_64; + for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { + NewPageEntry[Index] = (BaseAddress + SIZE_4KB * Index) | AddressEncMask | ((*PageEntry) & PAGE_PROGATE_BITS); + } + (*PageEntry) = (UINT64)(UINTN)NewPageEntry | AddressEncMask | ((*PageEntry) & PAGE_ATTRIBUTE_BITS); + return RETURN_SUCCESS; + } else { + return RETURN_UNSUPPORTED; + } + } else if (PageAttribute == Page1G) { + // + // Split 1G to 2M + // No need support 1G->4K directly, we should use 1G->2M, then 2M->4K to get more compact page table. + // + ASSERT (SplitAttribute == Page2M || SplitAttribute == Page4K); + if ((SplitAttribute == Page2M || SplitAttribute == Page4K)) { + NewPageEntry = AllocatePagesFunc (1); + DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); + if (NewPageEntry == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + BaseAddress = *PageEntry & ~AddressEncMask & PAGING_1G_ADDRESS_MASK_64; + for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { + NewPageEntry[Index] = (BaseAddress + SIZE_2MB * Index) | AddressEncMask | IA32_PG_PS | ((*PageEntry) & PAGE_PROGATE_BITS); + } + (*PageEntry) = (UINT64)(UINTN)NewPageEntry | AddressEncMask | ((*PageEntry) & PAGE_ATTRIBUTE_BITS); + return RETURN_SUCCESS; + } else { + return RETURN_UNSUPPORTED; + } + } else { + return RETURN_UNSUPPORTED; + } +} + +/** + Check the WP status in CR0 register. This bit is used to lock or unlock write + access to pages marked as read-only. + + @retval TRUE Write protection is enabled. + @retval FALSE Write protection is disabled. +**/ +BOOLEAN +IsReadOnlyPageWriteProtected ( + VOID + ) +{ + IA32_CR0 Cr0; + // + // To avoid unforseen consequences, don't touch paging settings in SMM mode + // in this driver. + // + if (!IsInSmm ()) { + Cr0.UintN = AsmReadCr0 (); + return (BOOLEAN) (Cr0.Bits.WP != 0); + } + return FALSE; +} + +/** + Disable Write Protect on pages marked as read-only. +**/ +VOID +DisableReadOnlyPageWriteProtect ( + VOID + ) +{ + IA32_CR0 Cr0; + // + // To avoid unforseen consequences, don't touch paging settings in SMM mode + // in this driver. + // + if (!IsInSmm ()) { + Cr0.UintN = AsmReadCr0 (); + Cr0.Bits.WP = 0; + AsmWriteCr0 (Cr0.UintN); + } +} + +/** + Enable Write Protect on pages marked as read-only. +**/ +VOID +EnableReadOnlyPageWriteProtect ( + VOID + ) +{ + IA32_CR0 Cr0; + // + // To avoid unforseen consequences, don't touch paging settings in SMM mode + // in this driver. + // + if (!IsInSmm ()) { + Cr0.UintN = AsmReadCr0 (); + Cr0.Bits.WP = 1; + AsmWriteCr0 (Cr0.UintN); + } +} + +/** + This function modifies the page attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + Caller should make sure BaseAddress and Length is at page boundary. + + @param[in] PagingContext The paging context. NULL means get page table from current CPU context. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to modify for the memory region. + @param[in] PageAction The page action. + @param[in] AllocatePagesFunc If page split is needed, this function is used to allocate more pages. + NULL mean page split is unsupported. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + @param[out] IsModified TRUE means page table modified. FALSE means page table not modified. + + @retval RETURN_SUCCESS The attributes were modified for the memory region. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. +**/ +RETURN_STATUS +ConvertMemoryPageAttributes ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext OPTIONAL, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN PAGE_ACTION PageAction, + IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc OPTIONAL, + OUT BOOLEAN *IsSplitted, OPTIONAL + OUT BOOLEAN *IsModified OPTIONAL + ) +{ + PAGE_TABLE_LIB_PAGING_CONTEXT CurrentPagingContext; + UINT64 *PageEntry; + PAGE_ATTRIBUTE PageAttribute; + UINTN PageEntryLength; + PAGE_ATTRIBUTE SplitAttribute; + RETURN_STATUS Status; + BOOLEAN IsEntryModified; + BOOLEAN IsWpEnabled; + + if ((BaseAddress & (SIZE_4KB - 1)) != 0) { + DEBUG ((DEBUG_ERROR, "BaseAddress(0x%lx) is not aligned!\n", BaseAddress)); + return EFI_UNSUPPORTED; + } + if ((Length & (SIZE_4KB - 1)) != 0) { + DEBUG ((DEBUG_ERROR, "Length(0x%lx) is not aligned!\n", Length)); + return EFI_UNSUPPORTED; + } + if (Length == 0) { + DEBUG ((DEBUG_ERROR, "Length is 0!\n")); + return RETURN_INVALID_PARAMETER; + } + + if ((Attributes & ~(EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP)) != 0) { + DEBUG ((DEBUG_ERROR, "Attributes(0x%lx) has unsupported bit\n", Attributes)); + return EFI_UNSUPPORTED; + } + + if (PagingContext == NULL) { + GetCurrentPagingContext (&CurrentPagingContext); + } else { + CopyMem (&CurrentPagingContext, PagingContext, sizeof(CurrentPagingContext)); + } + switch(CurrentPagingContext.MachineType) { + case IMAGE_FILE_MACHINE_I386: + if (CurrentPagingContext.ContextData.Ia32.PageTableBase == 0) { + if (Attributes == 0) { + return EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, "PageTable is 0!\n")); + return EFI_UNSUPPORTED; + } + } + if ((CurrentPagingContext.ContextData.Ia32.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) == 0) { + DEBUG ((DEBUG_ERROR, "Non-PAE Paging!\n")); + return EFI_UNSUPPORTED; + } + if ((BaseAddress + Length) > BASE_4GB) { + DEBUG ((DEBUG_ERROR, "Beyond 4GB memory in 32-bit mode!\n")); + return EFI_UNSUPPORTED; + } + break; + case IMAGE_FILE_MACHINE_X64: + ASSERT (CurrentPagingContext.ContextData.X64.PageTableBase != 0); + break; + default: + ASSERT(FALSE); + return EFI_UNSUPPORTED; + break; + } + +// DEBUG ((DEBUG_ERROR, "ConvertMemoryPageAttributes(%x) - %016lx, %016lx, %02lx\n", IsSet, BaseAddress, Length, Attributes)); + + if (IsSplitted != NULL) { + *IsSplitted = FALSE; + } + if (IsModified != NULL) { + *IsModified = FALSE; + } + if (AllocatePagesFunc == NULL) { + AllocatePagesFunc = AllocatePageTableMemory; + } + + // + // Make sure that the page table is changeable. + // + IsWpEnabled = IsReadOnlyPageWriteProtected (); + if (IsWpEnabled) { + DisableReadOnlyPageWriteProtect (); + } + + // + // Below logic is to check 2M/4K page to make sure we do not waste memory. + // + Status = EFI_SUCCESS; + while (Length != 0) { + PageEntry = GetPageTableEntry (&CurrentPagingContext, BaseAddress, &PageAttribute); + if (PageEntry == NULL) { + Status = RETURN_UNSUPPORTED; + goto Done; + } + PageEntryLength = PageAttributeToLength (PageAttribute); + SplitAttribute = NeedSplitPage (BaseAddress, Length, PageEntry, PageAttribute); + if (SplitAttribute == PageNone) { + ConvertPageEntryAttribute (&CurrentPagingContext, PageEntry, Attributes, PageAction, &IsEntryModified); + if (IsEntryModified) { + if (IsModified != NULL) { + *IsModified = TRUE; + } + } + // + // Convert success, move to next + // + BaseAddress += PageEntryLength; + Length -= PageEntryLength; + } else { + if (AllocatePagesFunc == NULL) { + Status = RETURN_UNSUPPORTED; + goto Done; + } + Status = SplitPage (PageEntry, PageAttribute, SplitAttribute, AllocatePagesFunc); + if (RETURN_ERROR (Status)) { + Status = RETURN_UNSUPPORTED; + goto Done; + } + if (IsSplitted != NULL) { + *IsSplitted = TRUE; + } + if (IsModified != NULL) { + *IsModified = TRUE; + } + // + // Just split current page + // Convert success in next around + // + } + } + +Done: + // + // Restore page table write protection, if any. + // + if (IsWpEnabled) { + EnableReadOnlyPageWriteProtect (); + } + return Status; +} + +/** + This function assigns the page attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + Caller should make sure BaseAddress and Length is at page boundary. + + Caller need guarantee the TPL <= TPL_NOTIFY, if there is split page request. + + @param[in] PagingContext The paging context. NULL means get page table from current CPU context. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + @param[in] AllocatePagesFunc If page split is needed, this function is used to allocate more pages. + NULL mean page split is unsupported. + + @retval RETURN_SUCCESS The attributes were cleared for the memory region. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. +**/ +RETURN_STATUS +EFIAPI +AssignMemoryPageAttributes ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext OPTIONAL, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc OPTIONAL + ) +{ + RETURN_STATUS Status; + BOOLEAN IsModified; + BOOLEAN IsSplitted; + +// DEBUG((DEBUG_INFO, "AssignMemoryPageAttributes: 0x%lx - 0x%lx (0x%lx)\n", BaseAddress, Length, Attributes)); + Status = ConvertMemoryPageAttributes (PagingContext, BaseAddress, Length, Attributes, PageActionAssign, AllocatePagesFunc, &IsSplitted, &IsModified); + if (!EFI_ERROR(Status)) { + if ((PagingContext == NULL) && IsModified) { + // + // Flush TLB as last step. + // + // Note: Since APs will always init CR3 register in HLT loop mode or do + // TLB flush in MWAIT loop mode, there's no need to flush TLB for them + // here. + // + CpuFlushTlb(); + } + } + + return Status; +} + +/** + Check if Execute Disable feature is enabled or not. +**/ +BOOLEAN +IsExecuteDisableEnabled ( + VOID + ) +{ + MSR_CORE_IA32_EFER_REGISTER MsrEfer; + + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + return (MsrEfer.Bits.NXE == 1); +} + +/** + Update GCD memory space attributes according to current page table setup. +**/ +VOID +RefreshGcdMemoryAttributesFromPaging ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NumberOfDescriptors; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; + PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext; + PAGE_ATTRIBUTE PageAttribute; + UINT64 *PageEntry; + UINT64 PageLength; + UINT64 MemorySpaceLength; + UINT64 Length; + UINT64 BaseAddress; + UINT64 PageStartAddress; + UINT64 Attributes; + UINT64 Capabilities; + UINT64 NewAttributes; + UINTN Index; + + // + // Assuming that memory space map returned is sorted already; otherwise sort + // them in the order of lowest address to highest address. + // + Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); + ASSERT_EFI_ERROR (Status); + + GetCurrentPagingContext (&PagingContext); + + Attributes = 0; + NewAttributes = 0; + BaseAddress = 0; + PageLength = 0; + + if (IsExecuteDisableEnabled ()) { + Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP; + } else { + Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP; + } + + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) { + continue; + } + + // + // Sync the actual paging related capabilities back to GCD service first. + // As a side effect (good one), this can also help to avoid unnecessary + // memory map entries due to the different capabilities of the same type + // memory, such as multiple RT_CODE and RT_DATA entries in memory map, + // which could cause boot failure of some old Linux distro (before v4.3). + // + Status = gDS->SetMemorySpaceCapabilities ( + MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].Length, + MemorySpaceMap[Index].Capabilities | Capabilities + ); + if (EFI_ERROR (Status)) { + // + // If we cannot update the capabilities, we cannot update its + // attributes either. So just simply skip current block of memory. + // + DEBUG (( + DEBUG_WARN, + "Failed to update capability: [%lu] %016lx - %016lx (%016lx -> %016lx)\r\n", + (UINT64)Index, MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1, + MemorySpaceMap[Index].Capabilities, + MemorySpaceMap[Index].Capabilities | Capabilities + )); + continue; + } + + if (MemorySpaceMap[Index].BaseAddress >= (BaseAddress + PageLength)) { + // + // Current memory space starts at a new page. Resetting PageLength will + // trigger a retrieval of page attributes at new address. + // + PageLength = 0; + } else { + // + // In case current memory space is not adjacent to last one + // + PageLength -= (MemorySpaceMap[Index].BaseAddress - BaseAddress); + } + + // + // Sync actual page attributes to GCD + // + BaseAddress = MemorySpaceMap[Index].BaseAddress; + MemorySpaceLength = MemorySpaceMap[Index].Length; + while (MemorySpaceLength > 0) { + if (PageLength == 0) { + PageEntry = GetPageTableEntry (&PagingContext, BaseAddress, &PageAttribute); + if (PageEntry == NULL) { + break; + } + + // + // Note current memory space might start in the middle of a page + // + PageStartAddress = (*PageEntry) & (UINT64)PageAttributeToMask(PageAttribute); + PageLength = PageAttributeToLength (PageAttribute) - (BaseAddress - PageStartAddress); + Attributes = GetAttributesFromPageEntry (PageEntry); + } + + Length = MIN (PageLength, MemorySpaceLength); + if (Attributes != (MemorySpaceMap[Index].Attributes & + EFI_MEMORY_PAGETYPE_MASK)) { + NewAttributes = (MemorySpaceMap[Index].Attributes & + ~EFI_MEMORY_PAGETYPE_MASK) | Attributes; + Status = gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + NewAttributes + ); + ASSERT_EFI_ERROR (Status); + DEBUG (( + DEBUG_VERBOSE, + "Updated memory space attribute: [%lu] %016lx - %016lx (%016lx -> %016lx)\r\n", + (UINT64)Index, BaseAddress, BaseAddress + Length - 1, + MemorySpaceMap[Index].Attributes, + NewAttributes + )); + } + + PageLength -= Length; + MemorySpaceLength -= Length; + BaseAddress += Length; + } + } + + FreePool (MemorySpaceMap); +} + +/** + Initialize a buffer pool for page table use only. + + To reduce the potential split operation on page table, the pages reserved for + page table should be allocated in the times of PAGE_TABLE_POOL_UNIT_PAGES and + at the boundary of PAGE_TABLE_POOL_ALIGNMENT. So the page pool is always + initialized with number of pages greater than or equal to the given PoolPages. + + Once the pages in the pool are used up, this method should be called again to + reserve at least another PAGE_TABLE_POOL_UNIT_PAGES. Usually this won't happen + often in practice. + + @param[in] PoolPages The least page number of the pool to be created. + + @retval TRUE The pool is initialized successfully. + @retval FALSE The memory is out of resource. +**/ +BOOLEAN +InitializePageTablePool ( + IN UINTN PoolPages + ) +{ + VOID *Buffer; + BOOLEAN IsModified; + + // + // Do not allow re-entrance. + // + if (mPageTablePoolLock) { + return FALSE; + } + + mPageTablePoolLock = TRUE; + IsModified = FALSE; + + // + // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for + // header. + // + PoolPages += 1; // Add one page for header. + PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) * + PAGE_TABLE_POOL_UNIT_PAGES; + Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT); + if (Buffer == NULL) { + DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n")); + goto Done; + } + + DEBUG (( + DEBUG_INFO, + "Paging: added %lu pages to page table pool\r\n", + (UINT64)PoolPages + )); + + // + // Link all pools into a list for easier track later. + // + if (mPageTablePool == NULL) { + mPageTablePool = Buffer; + mPageTablePool->NextPool = mPageTablePool; + } else { + ((PAGE_TABLE_POOL *)Buffer)->NextPool = mPageTablePool->NextPool; + mPageTablePool->NextPool = Buffer; + mPageTablePool = Buffer; + } + + // + // Reserve one page for pool header. + // + mPageTablePool->FreePages = PoolPages - 1; + mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1); + + // + // Mark the whole pool pages as read-only. + // + ConvertMemoryPageAttributes ( + NULL, + (PHYSICAL_ADDRESS)(UINTN)Buffer, + EFI_PAGES_TO_SIZE (PoolPages), + EFI_MEMORY_RO, + PageActionSet, + AllocatePageTableMemory, + NULL, + &IsModified + ); + ASSERT (IsModified == TRUE); + +Done: + mPageTablePoolLock = FALSE; + return IsModified; +} + +/** + This API provides a way to allocate memory for page table. + + This API can be called more than once to allocate memory for page tables. + + Allocates the number of 4KB pages and returns a pointer to the allocated + buffer. The buffer returned is aligned on a 4KB boundary. + + If Pages is 0, then NULL is returned. + If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePageTableMemory ( + IN UINTN Pages + ) +{ + VOID *Buffer; + + if (Pages == 0) { + return NULL; + } + + // + // Renew the pool if necessary. + // + if (mPageTablePool == NULL || + Pages > mPageTablePool->FreePages) { + if (!InitializePageTablePool (Pages)) { + return NULL; + } + } + + Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset; + + mPageTablePool->Offset += EFI_PAGES_TO_SIZE (Pages); + mPageTablePool->FreePages -= Pages; + + return Buffer; +} + +/** + Special handler for #DB exception, which will restore the page attributes + (not-present). It should work with #PF handler which will set pages to + 'present'. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. + +**/ +VOID +EFIAPI +DebugExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINTN CpuIndex; + UINTN PFEntry; + BOOLEAN IsWpEnabled; + + MpInitLibWhoAmI (&CpuIndex); + + // + // Clear last PF entries + // + IsWpEnabled = IsReadOnlyPageWriteProtected (); + if (IsWpEnabled) { + DisableReadOnlyPageWriteProtect (); + } + + for (PFEntry = 0; PFEntry < mPFEntryCount[CpuIndex]; PFEntry++) { + if (mLastPFEntryPointer[CpuIndex][PFEntry] != NULL) { + *mLastPFEntryPointer[CpuIndex][PFEntry] &= ~(UINT64)IA32_PG_P; + } + } + + if (IsWpEnabled) { + EnableReadOnlyPageWriteProtect (); + } + + // + // Reset page fault exception count for next page fault. + // + mPFEntryCount[CpuIndex] = 0; + + // + // Flush TLB + // + CpuFlushTlb (); + + // + // Clear TF in EFLAGS + // + if (mPagingContext.MachineType == IMAGE_FILE_MACHINE_I386) { + SystemContext.SystemContextIa32->Eflags &= (UINT32)~BIT8; + } else { + SystemContext.SystemContextX64->Rflags &= (UINT64)~BIT8; + } +} + +/** + Special handler for #PF exception, which will set the pages which caused + #PF to be 'present'. The attribute of those pages should be restored in + the subsequent #DB handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. + +**/ +VOID +EFIAPI +PageFaultExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_STATUS Status; + UINT64 PFAddress; + PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext; + PAGE_ATTRIBUTE PageAttribute; + UINT64 Attributes; + UINT64 *PageEntry; + UINTN Index; + UINTN CpuIndex; + UINTN PageNumber; + BOOLEAN NonStopMode; + + PFAddress = AsmReadCr2 () & ~EFI_PAGE_MASK; + if (PFAddress < BASE_4KB) { + NonStopMode = NULL_DETECTION_NONSTOP_MODE ? TRUE : FALSE; + } else { + NonStopMode = HEAP_GUARD_NONSTOP_MODE ? TRUE : FALSE; + } + + if (NonStopMode) { + MpInitLibWhoAmI (&CpuIndex); + GetCurrentPagingContext (&PagingContext); + // + // Memory operation cross page boundary, like "rep mov" instruction, will + // cause infinite loop between this and Debug Trap handler. We have to make + // sure that current page and the page followed are both in PRESENT state. + // + PageNumber = 2; + while (PageNumber > 0) { + PageEntry = GetPageTableEntry (&PagingContext, PFAddress, &PageAttribute); + ASSERT(PageEntry != NULL); + + if (PageEntry != NULL) { + Attributes = GetAttributesFromPageEntry (PageEntry); + if ((Attributes & EFI_MEMORY_RP) != 0) { + Attributes &= ~EFI_MEMORY_RP; + Status = AssignMemoryPageAttributes (&PagingContext, PFAddress, + EFI_PAGE_SIZE, Attributes, NULL); + if (!EFI_ERROR(Status)) { + Index = mPFEntryCount[CpuIndex]; + // + // Re-retrieve page entry because above calling might update page + // table due to table split. + // + PageEntry = GetPageTableEntry (&PagingContext, PFAddress, &PageAttribute); + mLastPFEntryPointer[CpuIndex][Index++] = PageEntry; + mPFEntryCount[CpuIndex] = Index; + } + } + } + + PFAddress += EFI_PAGE_SIZE; + --PageNumber; + } + } + + // + // Initialize the serial port before dumping. + // + SerialPortInitialize (); + // + // Display ExceptionType, CPU information and Image information + // + DumpCpuContext (ExceptionType, SystemContext); + if (NonStopMode) { + // + // Set TF in EFLAGS + // + if (mPagingContext.MachineType == IMAGE_FILE_MACHINE_I386) { + SystemContext.SystemContextIa32->Eflags |= (UINT32)BIT8; + } else { + SystemContext.SystemContextX64->Rflags |= (UINT64)BIT8; + } + } else { + CpuDeadLoop (); + } +} + +/** + Initialize the Page Table lib. +**/ +VOID +InitializePageTableLib ( + VOID + ) +{ + PAGE_TABLE_LIB_PAGING_CONTEXT CurrentPagingContext; + UINT32 *Attributes; + UINTN *PageTableBase; + + GetCurrentPagingContext (&CurrentPagingContext); + + GetPagingDetails (&CurrentPagingContext.ContextData, &PageTableBase, &Attributes); + + // + // Reserve memory of page tables for future uses, if paging is enabled. + // + if ((*PageTableBase != 0) && + (*Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0) { + DisableReadOnlyPageWriteProtect (); + InitializePageTablePool (1); + EnableReadOnlyPageWriteProtect (); + } + + if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) { + mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mNumberOfProcessors); + ASSERT (mPFEntryCount != NULL); + + mLastPFEntryPointer = (UINT64 *(*)[MAX_PF_ENTRY_COUNT]) + AllocateZeroPool (sizeof (mLastPFEntryPointer[0]) * mNumberOfProcessors); + ASSERT (mLastPFEntryPointer != NULL); + } + + DEBUG ((DEBUG_INFO, "CurrentPagingContext:\n")); + DEBUG ((DEBUG_INFO, " MachineType - 0x%x\n", CurrentPagingContext.MachineType)); + DEBUG ((DEBUG_INFO, " PageTableBase - 0x%Lx\n", (UINT64)*PageTableBase)); + DEBUG ((DEBUG_INFO, " Attributes - 0x%x\n", *Attributes)); + + return ; +} + diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.h b/UefiCpuPkg/CpuDxe/CpuPageTable.h new file mode 100644 index 000000000..0b2a02a2b --- /dev/null +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.h @@ -0,0 +1,157 @@ +/** @file + Page table management header file. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PAGE_TABLE_LIB_H_ +#define _PAGE_TABLE_LIB_H_ + +#include + +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE BIT0 +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE BIT1 +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT BIT2 +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL BIT3 +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE BIT30 +#define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED BIT31 +// Other bits are reserved for future use +typedef struct { + UINT32 PageTableBase; + UINT32 Reserved; + UINT32 Attributes; +} PAGE_TABLE_LIB_PAGING_CONTEXT_IA32; + +typedef struct { + UINT64 PageTableBase; + UINT32 Attributes; +} PAGE_TABLE_LIB_PAGING_CONTEXT_X64; + +typedef union { + PAGE_TABLE_LIB_PAGING_CONTEXT_IA32 Ia32; + PAGE_TABLE_LIB_PAGING_CONTEXT_X64 X64; +} PAGE_TABLE_LIB_PAGING_CONTEXT_DATA; + +typedef struct { + // + // PE32+ Machine type for EFI images + // + // #define IMAGE_FILE_MACHINE_I386 0x014c + // #define IMAGE_FILE_MACHINE_X64 0x8664 + // + UINT16 MachineType; + PAGE_TABLE_LIB_PAGING_CONTEXT_DATA ContextData; +} PAGE_TABLE_LIB_PAGING_CONTEXT; + +#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB +#define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB +#define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE) +#define PAGE_TABLE_POOL_ALIGN_MASK \ + (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1)) + +typedef struct { + VOID *NextPool; + UINTN Offset; + UINTN FreePages; +} PAGE_TABLE_POOL; + + +/** + Allocates one or more 4KB pages for page table. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +typedef +VOID * +(EFIAPI *PAGE_TABLE_LIB_ALLOCATE_PAGES) ( + IN UINTN Pages + ); + +/** + This function assigns the page attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + Caller should make sure BaseAddress and Length is at page boundary. + + Caller need guarantee the TPL <= TPL_NOTIFY, if there is split page request. + + @param PagingContext The paging context. NULL means get page table from current CPU context. + @param BaseAddress The physical address that is the start address of a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memory region. + @param AllocatePagesFunc If page split is needed, this function is used to allocate more pages. + NULL mean page split is unsupported. + + @retval RETURN_SUCCESS The attributes were cleared for the memory region. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. +**/ +RETURN_STATUS +EFIAPI +AssignMemoryPageAttributes ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext OPTIONAL, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc OPTIONAL + ); + +/** + Initialize the Page Table lib. +**/ +VOID +InitializePageTableLib ( + VOID + ); + +/** + This API provides a way to allocate memory for page table. + + This API can be called more once to allocate memory for page tables. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePageTableMemory ( + IN UINTN Pages + ); + +/** + Get paging details. + + @param PagingContextData The paging context. + @param PageTableBase Return PageTableBase field. + @param Attributes Return Attributes field. + +**/ +VOID +GetPagingDetails ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT_DATA *PagingContextData, + OUT UINTN **PageTableBase OPTIONAL, + OUT UINT32 **Attributes OPTIONAL + ); + +#endif diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.nasm b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.nasm new file mode 100644 index 000000000..0b99e3ec3 --- /dev/null +++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.nasm @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +;* +;* Copyright (c) 2016, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* CpuAsm.nasm +;* +;* Abstract: +;* +;------------------------------------------------------------------------------ + + SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; SetCodeSelector ( +; UINT16 Selector +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SetCodeSelector) +ASM_PFX(SetCodeSelector): + mov ecx, [esp+4] + sub esp, 0x10 + lea eax, [setCodeSelectorLongJump] + mov [esp], eax + mov [esp+4], cx + jmp dword far [esp] +setCodeSelectorLongJump: + add esp, 0x10 + ret + +;------------------------------------------------------------------------------ +; VOID +; SetDataSelectors ( +; UINT16 Selector +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SetDataSelectors) +ASM_PFX(SetDataSelectors): + mov ecx, [esp+4] +o16 mov ss, cx +o16 mov ds, cx +o16 mov es, cx +o16 mov fs, cx +o16 mov gs, cx + ret + diff --git a/UefiCpuPkg/CpuDxe/Ia32/PagingAttribute.c b/UefiCpuPkg/CpuDxe/Ia32/PagingAttribute.c new file mode 100644 index 000000000..3325a42dd --- /dev/null +++ b/UefiCpuPkg/CpuDxe/Ia32/PagingAttribute.c @@ -0,0 +1,34 @@ +/** @file + Return Paging attribute. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuPageTable.h" + + +/** + Get paging details. + + @param PagingContextData The paging context. + @param PageTableBase Return PageTableBase field. + @param Attributes Return Attributes field. + +**/ +VOID +GetPagingDetails ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT_DATA *PagingContextData, + OUT UINTN **PageTableBase OPTIONAL, + OUT UINT32 **Attributes OPTIONAL + ) +{ + if (PageTableBase != NULL) { + *PageTableBase = &PagingContextData->Ia32.PageTableBase; + } + if (Attributes != NULL) { + *Attributes = &PagingContextData->Ia32.Attributes; + } +} + diff --git a/UefiCpuPkg/CpuDxe/X64/CpuAsm.nasm b/UefiCpuPkg/CpuDxe/X64/CpuAsm.nasm new file mode 100644 index 000000000..c3489bcc3 --- /dev/null +++ b/UefiCpuPkg/CpuDxe/X64/CpuAsm.nasm @@ -0,0 +1,46 @@ +;------------------------------------------------------------------------------ +;* +;* Copyright (c) 2016, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* CpuAsm.nasm +;* +;* Abstract: +;* +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; SetCodeSelector ( +; UINT16 Selector +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SetCodeSelector) +ASM_PFX(SetCodeSelector): + sub rsp, 0x10 + lea rax, [setCodeSelectorLongJump] + mov [rsp], rax + mov [rsp+4], cx + jmp dword far [rsp] +setCodeSelectorLongJump: + add rsp, 0x10 + ret + +;------------------------------------------------------------------------------ +; VOID +; SetDataSelectors ( +; UINT16 Selector +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SetDataSelectors) +ASM_PFX(SetDataSelectors): +o16 mov ss, cx +o16 mov ds, cx +o16 mov es, cx +o16 mov fs, cx +o16 mov gs, cx + ret + diff --git a/UefiCpuPkg/CpuDxe/X64/PagingAttribute.c b/UefiCpuPkg/CpuDxe/X64/PagingAttribute.c new file mode 100644 index 000000000..796793561 --- /dev/null +++ b/UefiCpuPkg/CpuDxe/X64/PagingAttribute.c @@ -0,0 +1,34 @@ +/** @file + Return Paging attribute. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuPageTable.h" + + +/** + Get paging details. + + @param PagingContextData The paging context. + @param PageTableBase Return PageTableBase field. + @param Attributes Return Attributes field. + +**/ +VOID +GetPagingDetails ( + IN PAGE_TABLE_LIB_PAGING_CONTEXT_DATA *PagingContextData, + OUT UINTN **PageTableBase OPTIONAL, + OUT UINT32 **Attributes OPTIONAL + ) +{ + if (PageTableBase != NULL) { + *PageTableBase = &PagingContextData->X64.PageTableBase; + } + if (Attributes != NULL) { + *Attributes = &PagingContextData->X64.Attributes; + } +} + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.c b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.c new file mode 100644 index 000000000..230b9fad7 --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.c @@ -0,0 +1,136 @@ +/** @file + CPU Features DXE driver to initialize CPU features. + + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + +/** + Worker function to perform CPU feature initialization. + +**/ +VOID +CpuFeaturesInitializeWorker ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + CpuFeaturesDetect (); + + CpuFeaturesInitialize (); + + // + // Install CPU Features Init Done Protocol + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEdkiiCpuFeaturesInitDoneGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Event notification that initialize CPU features when gEfiSmmConfigurationProtocol installs. + + @param[in] Event The Event that is being processed, not used. + @param[in] Context Event Context, not used. +**/ +VOID +EFIAPI +SmmConfigurationEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_SMM_CONFIGURATION_PROTOCOL *SmmConfiguration; + + // + // Make sure this notification is for this handler + // + Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, (VOID **)&SmmConfiguration); + if (EFI_ERROR (Status)) { + return; + } + + CpuFeaturesInitializeWorker (); +} + +/** + CPU Features driver entry point function. + + If PcdCpuFeaturesInitAfterSmmRelocation is TRUE, it will register one + SMM Configuration Protocol notify function to perform CPU features + initialization. Otherwise, it will perform CPU features initialization + directly. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS CPU Features is initialized successfully. +**/ +EFI_STATUS +EFIAPI +CpuFeaturesDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VOID *Registration; + EFI_STATUS Status; + EFI_HANDLE Handle; + + if (GetFirstGuidHob (&gEdkiiCpuFeaturesInitDoneGuid) != NULL) { + // + // Try to find HOB first. This HOB exist means CPU features have + // been initialized by CpuFeaturesPei driver, just install + // gEdkiiCpuFeaturesInitDoneGuid. + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEdkiiCpuFeaturesInitDoneGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; + } + + if (PcdGetBool (PcdCpuFeaturesInitAfterSmmRelocation)) { + // + // Install notification callback on SMM Configuration Protocol + // + EfiCreateProtocolNotifyEvent ( + &gEfiSmmConfigurationProtocolGuid, + TPL_CALLBACK, + SmmConfigurationEventNotify, + NULL, + &Registration + ); + } else { + CpuFeaturesInitializeWorker (); + } + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.inf b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.inf new file mode 100644 index 000000000..497d6e8b0 --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.inf @@ -0,0 +1,48 @@ +## @file +# CPU Features DXE driver. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuFeaturesDxe + MODULE_UNI_FILE = CpuFeaturesDxe.uni + FILE_GUID = 63EB1B62-10C9-4693-88AC-AE0999EA87F8 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = CpuFeaturesDxeInitialize + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + RegisterCpuFeaturesLib + HobLib + +[Sources] + CpuFeaturesDxe.c + +[Guids] + gEdkiiCpuFeaturesInitDoneGuid ## PRODUCES ## UNDEFINED # protocol GUID installed + +[Protocols] + gEfiSmmConfigurationProtocolGuid ## NOTIFY + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitAfterSmmRelocation ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuFeaturesDxeExtra.uni diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.uni b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.uni new file mode 100644 index 000000000..e970eb300 --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Features DXE driver. +// +// CPU Features DXE driver. +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Features DXE driver to initialize CPU features." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Features DXE driver to initialize CPU features." + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesDxeExtra.uni b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxeExtra.uni new file mode 100644 index 000000000..82cb70c9a --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuFeaturesDxe Localized Strings and Content +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU Features DXE Driver" + + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.c b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.c new file mode 100644 index 000000000..be559a959 --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.c @@ -0,0 +1,75 @@ +/** @file + CPU Features PEIM driver to initialize CPU features. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include + +EFI_PEI_PPI_DESCRIPTOR mPeiCpuFeaturesInitDonePpiDesc = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiCpuFeaturesInitDoneGuid, + NULL +}; + +/** + CPU Features driver entry point function. + + It will perform CPU features initialization, except for + PcdCpuFeaturesInitOnS3Resume is FALSE on S3 resume. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS CPU Features is initialized successfully. +**/ +EFI_STATUS +EFIAPI +CpuFeaturesPeimInitialize ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + if (BootMode == BOOT_ON_S3_RESUME && + !PcdGetBool (PcdCpuFeaturesInitOnS3Resume)) { + // + // Does nothing when if PcdCpuFeaturesInitOnS3Resume is FLASE + // on S3 boot mode + // + return EFI_SUCCESS; + } + + CpuFeaturesDetect (); + + CpuFeaturesInitialize (); + + // + // Install CPU Features Init Done PPI + // + Status = PeiServicesInstallPpi(&mPeiCpuFeaturesInitDonePpiDesc); + ASSERT_EFI_ERROR (Status); + + // + // Build HOB to let CpuFeatureDxe driver skip the initialization process. + // + BuildGuidHob (&gEdkiiCpuFeaturesInitDoneGuid, 0); + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf new file mode 100644 index 000000000..0e99bcf5a --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf @@ -0,0 +1,44 @@ +## @file +# CPU Features PEIM driver. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuFeaturesPei + MODULE_UNI_FILE = CpuFeaturesPei.uni + FILE_GUID = 183BB3E1-A1E5-4445-8AC9-0E83B6547E0E + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = CpuFeaturesPeimInitialize + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PeimEntryPoint + PeiServicesLib + RegisterCpuFeaturesLib + HobLib + +[Sources] + CpuFeaturesPei.c + +[Guids] + gEdkiiCpuFeaturesInitDoneGuid ## PRODUCES ## UNDEFINED # PPI GUID installed + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuFeaturesPeiExtra.uni diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.uni b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.uni new file mode 100644 index 000000000..d57fa8fce --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesPei.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Features PEIM driver. +// +// CPU Features PEIM driver. +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Features PEIM driver to initialize CPU features." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Features PEIM driver to initialize CPU features." + diff --git a/UefiCpuPkg/CpuFeatures/CpuFeaturesPeiExtra.uni b/UefiCpuPkg/CpuFeatures/CpuFeaturesPeiExtra.uni new file mode 100644 index 000000000..dcc8fc71a --- /dev/null +++ b/UefiCpuPkg/CpuFeatures/CpuFeaturesPeiExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuFeaturesPei Localized Strings and Content +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU Features PEIM Driver" + + diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c similarity index 82% rename from CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c rename to UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c index 75ca44479..ade820728 100644 --- a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c +++ b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c @@ -1,14 +1,10 @@ /** @file Produces the CPU I/O 2 Protocol. -Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -72,16 +68,16 @@ UINT8 mOutStride[] = { /** Check parameters to a CPU I/O 2 Protocol service request. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - + @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -90,7 +86,7 @@ UINT8 mOutStride[] = { @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -135,27 +131,27 @@ CpuIoCheckParameter ( if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) { return EFI_INVALID_PARAMETER; } - + // // Check to see if Address is aligned // - if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) { + if ((Address & ((UINT64)mInStride[Width] - 1)) != 0) { return EFI_UNSUPPORTED; } // - // Check to see if any address associated with this transfer exceeds the maximum + // Check to see if any address associated with this transfer exceeds the maximum // allowed address. The maximum address implied by the parameters passed in is // Address + Size * Count. If the following condition is met, then the transfer // is not supported. // // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1 // - // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count + // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count // can also be the maximum integer value supported by the CPU, this range // check must be adjusted to avoid all oveflow conditions. - // - // The following form of the range check is equivalent but assumes that + // + // The following form of the range check is equivalent but assumes that // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). // Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); @@ -163,7 +159,7 @@ CpuIoCheckParameter ( if (Address > Limit) { return EFI_UNSUPPORTED; } - } else { + } else { MaxCount = RShiftU64 (Limit, Width); if (MaxCount < (Count - 1)) { return EFI_UNSUPPORTED; @@ -175,14 +171,11 @@ CpuIoCheckParameter ( // // Check to see if Buffer is aligned -/* // (IA-32 allows UINT64 and INT64 data types to be 32-bit aligned.) + // (IA-32 allows UINT64 and INT64 data types to be 32-bit aligned.) // if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != 0) { return EFI_UNSUPPORTED; - }*/ - if (((UINTN)Buffer & (mInStride[Width] - 1)) != 0) { - return EFI_UNSUPPORTED; - } + } return EFI_SUCCESS; } @@ -190,30 +183,30 @@ CpuIoCheckParameter ( /** Reads memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -222,7 +215,7 @@ CpuIoCheckParameter ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -243,7 +236,7 @@ CpuMemoryServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -270,30 +263,30 @@ CpuMemoryServiceRead ( /** Writes memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -302,7 +295,7 @@ CpuMemoryServiceRead ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -323,7 +316,7 @@ CpuMemoryServiceWrite ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -350,30 +343,30 @@ CpuMemoryServiceWrite ( /** Reads I/O registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -382,7 +375,7 @@ CpuMemoryServiceWrite ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -403,7 +396,7 @@ CpuIoServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -413,6 +406,31 @@ CpuIoServiceRead ( InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + + // + // Fifo operations supported for (mInStride[Width] == 0) + // + if (InStride == 0) { + switch (OperationWidth) { + case EfiCpuIoWidthUint8: + IoReadFifo8 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiCpuIoWidthUint16: + IoReadFifo16 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiCpuIoWidthUint32: + IoReadFifo32 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + default: + // + // The CpuIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiCpuIoWidthUint8) { *Uint8Buffer = IoRead8 ((UINTN)Address); @@ -429,30 +447,30 @@ CpuIoServiceRead ( /** Write I/O registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -461,9 +479,9 @@ CpuIoServiceRead ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. - + **/ EFI_STATUS EFIAPI @@ -485,7 +503,7 @@ CpuIoServiceWrite ( // Make sure the parameters are valid // Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -495,6 +513,31 @@ CpuIoServiceWrite ( InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); + + // + // Fifo operations supported for (mInStride[Width] == 0) + // + if (InStride == 0) { + switch (OperationWidth) { + case EfiCpuIoWidthUint8: + IoWriteFifo8 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiCpuIoWidthUint16: + IoWriteFifo16 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiCpuIoWidthUint32: + IoWriteFifo32 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + default: + // + // The CpuIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiCpuIoWidthUint8) { IoWrite8 ((UINTN)Address, *Uint8Buffer); @@ -504,16 +547,16 @@ CpuIoServiceWrite ( IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); } } - + return EFI_SUCCESS; } /** The user Entry Point for module CpuIo2Dxe. The user code starts with this function. - @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. - + @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. @@ -533,7 +576,7 @@ CpuIo2Initialize ( &gEfiCpuIo2ProtocolGuid, &mCpuIo2, NULL ); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); return Status; } diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h similarity index 77% rename from CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h rename to UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h index 7d00da16f..3b16b205f 100644 --- a/CloverEFI/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h +++ b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h @@ -1,14 +1,8 @@ /** @file Internal include file for the CPU I/O 2 Protocol. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -29,30 +23,30 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /** Reads memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -61,7 +55,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -78,30 +72,30 @@ CpuMemoryServiceRead ( /** Writes memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -110,7 +104,7 @@ CpuMemoryServiceRead ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -127,30 +121,30 @@ CpuMemoryServiceWrite ( /** Reads I/O registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -159,7 +153,7 @@ CpuMemoryServiceWrite ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ @@ -176,30 +170,30 @@ CpuIoServiceRead ( /** Write I/O registers. - The I/O operations are carried out exactly as requested. The caller is responsible - for satisfying any alignment and I/O width restrictions that a PI System on a - platform might require. For example on some platforms, width requests of - EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. - - If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, - or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. - - If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, - EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. - - If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, - EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is - incremented for each of the Count operations that is performed. The read or + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. - + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. - @param[in] Address The base address of the I/O operation. - @param[in] Count The number of I/O operations to perform. The number of + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @@ -208,9 +202,9 @@ CpuIoServiceRead ( @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. - + **/ EFI_STATUS EFIAPI diff --git a/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf new file mode 100644 index 000000000..499258491 --- /dev/null +++ b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf @@ -0,0 +1,47 @@ +## @file +# Produces the CPU I/O 2 Protocol by using the services of the I/O Library. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuIo2Dxe + MODULE_UNI_FILE = CpuIo2Dxe.uni + FILE_GUID = A19B1FE7-C1BC-49F8-875F-54A5D542443F + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = CpuIo2Initialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + CpuIo2Dxe.c + CpuIo2Dxe.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + UefiBootServicesTableLib + +[Protocols] + gEfiCpuIo2ProtocolGuid ## PRODUCES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuIo2DxeExtra.uni diff --git a/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni new file mode 100644 index 000000000..8d4e5dd6b --- /dev/null +++ b/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni @@ -0,0 +1,16 @@ +// /** @file +// Produces the CPU I/O 2 Protocol by using the services of the I/O Library. +// +// Produces the CPU I/O 2 Protocol by using the services of the I/O Library. +// +// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Produces the CPU I/O 2 Protocol by using the services of the I/O Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Produces the CPU I/O 2 Protocol by using the services of the I/O Library." + diff --git a/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni b/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni new file mode 100644 index 000000000..5bd426df5 --- /dev/null +++ b/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuIo2Dxe Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU I/O v2 DXE Driver" + + diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c similarity index 86% rename from CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c rename to UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c index dea5c4a4d..b840d3e10 100644 --- a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c +++ b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c @@ -1,14 +1,8 @@ /** @file Produces the SMM CPU I/O Protocol. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -48,17 +42,17 @@ UINT8 mStride[] = { @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[in] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - + **/ EFI_STATUS CpuIoCheckParameter ( @@ -82,7 +76,7 @@ CpuIoCheckParameter ( // // Check to see if Width is in the valid range // - if (Width < 0 || Width > SMM_IO_UINT64) { + if ((UINT32)Width > SMM_IO_UINT64) { return EFI_INVALID_PARAMETER; } @@ -92,20 +86,20 @@ CpuIoCheckParameter ( if (!MmioOperation && (Width == SMM_IO_UINT64)) { return EFI_INVALID_PARAMETER; } - + // - // Check to see if any address associated with this transfer exceeds the maximum + // Check to see if any address associated with this transfer exceeds the maximum // allowed address. The maximum address implied by the parameters passed in is // Address + Size * Count. If the following condition is met, then the transfer // is not supported. // // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1 // - // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count + // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count // can also be the maximum integer value supported by the CPU, this range // check must be adjusted to avoid all overflow conditions. - // - // The following form of the range check is equivalent but assumes that + // + // The following form of the range check is equivalent but assumes that // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). // Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); @@ -113,7 +107,7 @@ CpuIoCheckParameter ( if (Address > Limit) { return EFI_UNSUPPORTED; } - } else { + } else { MaxCount = RShiftU64 (Limit, Width); if (MaxCount < (Count - 1)) { return EFI_UNSUPPORTED; @@ -122,11 +116,11 @@ CpuIoCheckParameter ( return EFI_UNSUPPORTED; } } - + // // Check to see if Address is aligned // - if ((Address & (UINT64)(mStride[Width] - 1)) != 0) { + if ((Address & ((UINT64)mStride[Width] - 1)) != 0) { return EFI_UNSUPPORTED; } @@ -136,23 +130,23 @@ CpuIoCheckParameter ( /** Reads memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[out] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -171,7 +165,7 @@ CpuMemoryServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -196,23 +190,23 @@ CpuMemoryServiceRead ( /** Writes memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[in] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -231,7 +225,7 @@ CpuMemoryServiceWrite ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -256,23 +250,23 @@ CpuMemoryServiceWrite ( /** Reads I/O registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[out] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -291,7 +285,7 @@ CpuIoServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -315,23 +309,23 @@ CpuIoServiceRead ( /** Write I/O registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[in] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -353,7 +347,7 @@ CpuIoServiceWrite ( // Make sure the parameters are valid // Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -370,7 +364,7 @@ CpuIoServiceWrite ( IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); } } - + return EFI_SUCCESS; } @@ -396,7 +390,7 @@ SmmCpuIo2Initialize ( // // Copy the SMM CPU I/O Protocol instance into the System Management System Table // - CopyMem(&gSmst->SmmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2)); + CopyMem (&gSmst->SmmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2)); // // Install the SMM CPU I/O Protocol into the SMM protocol database @@ -407,7 +401,7 @@ SmmCpuIo2Initialize ( EFI_NATIVE_INTERFACE, &mSmmCpuIo2 ); - ASSERT_EFI_ERROR(Status); - + ASSERT_EFI_ERROR (Status); + return Status; } diff --git a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h similarity index 82% rename from CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h rename to UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h index 5a092594d..4c133b58c 100644 --- a/CloverEFI/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h +++ b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h @@ -1,14 +1,8 @@ /** @file Internal include file for the SMM CPU I/O Protocol. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -30,23 +24,23 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /** Reads memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[out] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -63,23 +57,23 @@ CpuMemoryServiceRead ( /** Writes memory-mapped registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[in] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -96,23 +90,23 @@ CpuMemoryServiceWrite ( /** Reads I/O registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[out] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ @@ -129,23 +123,23 @@ CpuIoServiceRead ( /** Write I/O registers. - The I/O operations are carried out exactly as requested. The caller is - responsible for any alignment and I/O width issues that the bus, device, + The I/O operations are carried out exactly as requested. The caller is + responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning the Address if required. + @param[in] Address The base address of the I/O operations. The caller is + responsible for aligning the Address if required. @param[in] Count The number of I/O operations to perform. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer + @param[in] Buffer For read operations, the destination buffer to store + the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_UNSUPPORTED The Address is not valid for this system. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources **/ diff --git a/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf new file mode 100644 index 000000000..bc78fa4e4 --- /dev/null +++ b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf @@ -0,0 +1,47 @@ +## @file +# Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuIo2Smm + MODULE_UNI_FILE = CpuIo2Smm.uni + FILE_GUID = A47EE2D8-F60E-42fd-8E58-7BD65EE4C29B + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = SmmCpuIo2Initialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CpuIo2Smm.c + CpuIo2Smm.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + SmmServicesTableLib + BaseMemoryLib + +[Protocols] + gEfiSmmCpuIo2ProtocolGuid ## PRODUCES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuIo2SmmExtra.uni diff --git a/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni new file mode 100644 index 000000000..6ab9960d7 --- /dev/null +++ b/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni @@ -0,0 +1,16 @@ +// /** @file +// Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library. +// +// Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library. +// +// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Produces the SMM CPU I/O 2 Protocol by using the services of the I/O Library." + diff --git a/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni b/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni new file mode 100644 index 000000000..6a91f87f1 --- /dev/null +++ b/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuIo2Smm Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU I/O v2 SMM Driver" + + diff --git a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.c b/UefiCpuPkg/CpuIoPei/CpuIoPei.c similarity index 88% rename from CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.c rename to UefiCpuPkg/CpuIoPei/CpuIoPei.c index efef214f4..8a24cde0c 100644 --- a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.c +++ b/UefiCpuPkg/CpuIoPei/CpuIoPei.c @@ -1,14 +1,10 @@ /** @file Produces the CPU I/O PPI. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -52,7 +48,7 @@ EFI_PEI_PPI_DESCRIPTOR gPpiList = { &gEfiPeiCpuIoPpiInstalledGuid, NULL }; - + // // Lookup table for increment values based on transfer widths // @@ -101,9 +97,9 @@ UINT8 mOutStride[] = { @retval EFI_SUCCESS The parameters for this request pass the checks. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. - + **/ EFI_STATUS CpuIoCheckParameter ( @@ -127,7 +123,7 @@ CpuIoCheckParameter ( // // Check to see if Width is in the valid range // - if (Width < 0 || Width >= EfiPeiCpuIoWidthMaximum) { + if ((UINT32)Width >= EfiPeiCpuIoWidthMaximum) { return EFI_INVALID_PARAMETER; } @@ -146,20 +142,20 @@ CpuIoCheckParameter ( if (!MmioOperation && (Width == EfiPeiCpuIoWidthUint64)) { return EFI_INVALID_PARAMETER; } - + // - // Check to see if any address associated with this transfer exceeds the maximum + // Check to see if any address associated with this transfer exceeds the maximum // allowed address. The maximum address implied by the parameters passed in is // Address + Size * Count. If the following condition is met, then the transfer // is not supported. // // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1 // - // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count + // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count // can also be the maximum integer value supported by the CPU, this range // check must be adjusted to avoid all overflow conditions. - // - // The following form of the range check is equivalent but assumes that + // + // The following form of the range check is equivalent but assumes that // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). // Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); @@ -167,7 +163,7 @@ CpuIoCheckParameter ( if (Address > Limit) { return EFI_UNSUPPORTED; } - } else { + } else { MaxCount = RShiftU64 (Limit, Width); if (MaxCount < (Count - 1)) { return EFI_UNSUPPORTED; @@ -176,7 +172,7 @@ CpuIoCheckParameter ( return EFI_UNSUPPORTED; } } - + return EFI_SUCCESS; } @@ -194,7 +190,7 @@ CpuIoCheckParameter ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -217,7 +213,7 @@ CpuMemoryServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -268,7 +264,7 @@ CpuMemoryServiceRead ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -291,7 +287,7 @@ CpuMemoryServiceWrite ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -342,7 +338,7 @@ CpuMemoryServiceWrite ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -365,7 +361,7 @@ CpuIoServiceRead ( UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -375,6 +371,31 @@ CpuIoServiceRead ( InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); + + // + // Fifo operations supported for (mInStride[Width] == 0) + // + if (InStride == 0) { + switch (OperationWidth) { + case EfiPeiCpuIoWidthUint8: + IoReadFifo8 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiPeiCpuIoWidthUint16: + IoReadFifo16 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiPeiCpuIoWidthUint32: + IoReadFifo32 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + default: + // + // The CpuIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { @@ -411,7 +432,7 @@ CpuIoServiceRead ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -437,7 +458,7 @@ CpuIoServiceWrite ( // Make sure the parameters are valid // Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return Status; } @@ -447,6 +468,31 @@ CpuIoServiceWrite ( InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); + + // + // Fifo operations supported for (mInStride[Width] == 0) + // + if (InStride == 0) { + switch (OperationWidth) { + case EfiPeiCpuIoWidthUint8: + IoWriteFifo8 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiPeiCpuIoWidthUint16: + IoWriteFifo16 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + case EfiPeiCpuIoWidthUint32: + IoWriteFifo32 ((UINTN)Address, Count, Buffer); + return EFI_SUCCESS; + default: + // + // The CpuIoCheckParameter call above will ensure that this + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { @@ -465,14 +511,14 @@ CpuIoServiceWrite ( } } } - + return EFI_SUCCESS; } /** 8-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -493,7 +539,7 @@ CpuIoRead8 ( /** 16-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -515,7 +561,7 @@ CpuIoRead16 ( /** 32-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -537,7 +583,7 @@ CpuIoRead32 ( /** 64-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -559,7 +605,7 @@ CpuIoRead64 ( /** 8-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -581,7 +627,7 @@ CpuIoWrite8 ( /** 16-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -603,7 +649,7 @@ CpuIoWrite16 ( /** 32-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -625,7 +671,7 @@ CpuIoWrite32 ( /** 64-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -647,7 +693,7 @@ CpuIoWrite64 ( /** 8-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -669,7 +715,7 @@ CpuMemRead8 ( /** 16-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -691,7 +737,7 @@ CpuMemRead16 ( /** 32-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -713,7 +759,7 @@ CpuMemRead32 ( /** 64-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -735,7 +781,7 @@ CpuMemRead64 ( /** 8-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -757,7 +803,7 @@ CpuMemWrite8 ( /** 16-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -779,7 +825,7 @@ CpuMemWrite16 ( /** 32-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -801,7 +847,7 @@ CpuMemWrite32 ( /** 64-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -826,7 +872,7 @@ CpuMemWrite64 ( This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi. @param[in] FileHandle Pointer to image file handle. - @param[in] PeiServices Pointer to PEI Services Table + @param[in] PeiServices Pointer to PEI Services Table @retval EFI_SUCCESS CPU I/O PPI successfully installed @@ -844,21 +890,21 @@ CpuIoInitialize ( // Register so it will be automatically shadowed to memory // Status = PeiServicesRegisterForShadow (FileHandle); - + // // Make CpuIo pointer in PeiService table point to gCpuIoPpi // (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi; - + if (Status == EFI_ALREADY_STARTED) { // // Shadow completed and running from memory // - // DEBUG ((EFI_D_INFO, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi)); + DEBUG ((EFI_D_INFO, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi)); } else { Status = PeiServicesInstallPpi (&gPpiList); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); } - + return EFI_SUCCESS; } diff --git a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.h b/UefiCpuPkg/CpuIoPei/CpuIoPei.h similarity index 89% rename from CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.h rename to UefiCpuPkg/CpuIoPei/CpuIoPei.h index 052f0e3d0..e8676df90 100644 --- a/CloverEFI/UefiCpuPkg/CpuIoPei/CpuIoPei.h +++ b/UefiCpuPkg/CpuIoPei/CpuIoPei.h @@ -1,14 +1,8 @@ /** @file Internal include file for the CPU I/O PPI. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -40,7 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -69,7 +63,7 @@ CpuMemoryServiceRead ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -98,7 +92,7 @@ CpuMemoryServiceWrite ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -127,7 +121,7 @@ CpuIoServiceRead ( @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_UNSUPPORTED The address range specified by Address, Width, + @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ @@ -145,7 +139,7 @@ CpuIoServiceWrite ( /** 8-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -163,7 +157,7 @@ CpuIoRead8 ( /** 16-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -182,7 +176,7 @@ CpuIoRead16 ( /** 32-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -201,7 +195,7 @@ CpuIoRead32 ( /** 64-bit I/O read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -220,7 +214,7 @@ CpuIoRead64 ( /** 8-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -239,7 +233,7 @@ CpuIoWrite8 ( /** 16-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -258,7 +252,7 @@ CpuIoWrite16 ( /** 32-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -277,7 +271,7 @@ CpuIoWrite32 ( /** 64-bit I/O write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -296,7 +290,7 @@ CpuIoWrite64 ( /** 8-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -315,7 +309,7 @@ CpuMemRead8 ( /** 16-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -334,7 +328,7 @@ CpuMemRead16 ( /** 32-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -353,7 +347,7 @@ CpuMemRead32 ( /** 64-bit memory read operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -372,7 +366,7 @@ CpuMemRead64 ( /** 8-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -391,7 +385,7 @@ CpuMemWrite8 ( /** 16-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -410,7 +404,7 @@ CpuMemWrite16 ( /** 32-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -429,7 +423,7 @@ CpuMemWrite32 ( /** 64-bit memory write operations. - @param[in] PeiServices An indirect pointer to the PEI Services Table published + @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @@ -444,5 +438,5 @@ CpuMemWrite64 ( IN UINT64 Address, IN UINT64 Data ); - + #endif diff --git a/UefiCpuPkg/CpuIoPei/CpuIoPei.inf b/UefiCpuPkg/CpuIoPei/CpuIoPei.inf new file mode 100644 index 000000000..4d22a93e1 --- /dev/null +++ b/UefiCpuPkg/CpuIoPei/CpuIoPei.inf @@ -0,0 +1,45 @@ +## @file +# Produces the CPU I/O PPI by using the services of the I/O Library. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuIoPei + MODULE_UNI_FILE = CpuIoPei.uni + FILE_GUID = AE265864-CF5D-41a8-913D-71C155E76442 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = CpuIoInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + CpuIoPei.c + CpuIoPei.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + PeimEntryPoint + BaseLib + DebugLib + IoLib + PeiServicesLib + +[Ppis] + gEfiPeiCpuIoPpiInstalledGuid ## PRODUCES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuIoPeiExtra.uni diff --git a/UefiCpuPkg/CpuIoPei/CpuIoPei.uni b/UefiCpuPkg/CpuIoPei/CpuIoPei.uni new file mode 100644 index 000000000..40f444c0f --- /dev/null +++ b/UefiCpuPkg/CpuIoPei/CpuIoPei.uni @@ -0,0 +1,16 @@ +// /** @file +// Produces the CPU I/O PPI by using the services of the I/O Library. +// +// Produces the CPU I/O PPI by using the services of the I/O Library. +// +// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Produces the CPU I/O PPI by using the services of the I/O Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Produces the CPU I/O PPI by using the services of the I/O Library." + diff --git a/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni b/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni new file mode 100644 index 000000000..efabb477f --- /dev/null +++ b/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuIoPei Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU I/O PEI Module" + + diff --git a/UefiCpuPkg/CpuMpPei/CpuBist.c b/UefiCpuPkg/CpuMpPei/CpuBist.c new file mode 100644 index 000000000..159fa5cd1 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuBist.c @@ -0,0 +1,291 @@ +/** @file + Update and publish processors' BIST information. + + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuMpPei.h" + +EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = { + SecPlatformInformation2 +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformation2PpiGuid, + &mSecPlatformInformation2Ppi +}; + +/** + Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. + + @param PeiServices The pointer to the PEI Services Table. + @param StructureSize The pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to + hold the record is returned in StructureSize. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation2 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + VOID *DataInHob; + UINTN DataSize; + + GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid); + if (GuidHob == NULL) { + *StructureSize = 0; + return EFI_SUCCESS; + } + + DataInHob = GET_GUID_HOB_DATA (GuidHob); + DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + + // + // return the information from BistHob + // + if ((*StructureSize) < (UINT64) DataSize) { + *StructureSize = (UINT64) DataSize; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = (UINT64) DataSize; + CopyMem (PlatformInformationRecord2, DataInHob, DataSize); + return EFI_SUCCESS; +} + +/** + Worker function to get CPUs' BIST by calling SecPlatformInformationPpi + or SecPlatformInformation2Ppi. + + @param PeiServices Pointer to PEI Services Table + @param Guid PPI Guid + @param PpiDescriptor Return a pointer to instance of the + EFI_PEI_PPI_DESCRIPTOR + @param BistInformationData Pointer to BIST information data + @param BistInformationSize Return the size in bytes of BIST information + + @retval EFI_SUCCESS Retrieve of the BIST data successfully + @retval EFI_NOT_FOUND No sec platform information(2) ppi export + @retval EFI_DEVICE_ERROR Failed to get CPU Information + +**/ +EFI_STATUS +GetBistInfoFromPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_GUID *Guid, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + OUT VOID **BistInformationData, + OUT UINT64 *BistInformationSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi; + EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; + UINT64 InformationSize; + + Status = PeiServicesLocatePpi ( + Guid, // GUID + 0, // INSTANCE + PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&SecPlatformInformation2Ppi // PPI + ); + if (Status == EFI_NOT_FOUND) { + return EFI_NOT_FOUND; + } + + if (Status == EFI_SUCCESS) { + // + // Get the size of the sec platform information2(BSP/APs' BIST data) + // + InformationSize = 0; + SecPlatformInformation2 = NULL; + Status = SecPlatformInformation2Ppi->PlatformInformation2 ( + PeiServices, + &InformationSize, + SecPlatformInformation2 + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Status = PeiServicesAllocatePool ( + (UINTN) InformationSize, + (VOID **) &SecPlatformInformation2 + ); + if (Status == EFI_SUCCESS) { + // + // Retrieve BIST data + // + Status = SecPlatformInformation2Ppi->PlatformInformation2 ( + PeiServices, + &InformationSize, + SecPlatformInformation2 + ); + if (Status == EFI_SUCCESS) { + *BistInformationData = SecPlatformInformation2; + if (BistInformationSize != NULL) { + *BistInformationSize = InformationSize; + } + return EFI_SUCCESS; + } + } + } + } + + return EFI_DEVICE_ERROR; +} + +/** + Collects BIST data from PPI. + + This function collects BIST data from Sec Platform Information2 PPI + or SEC Platform Information PPI. + + @param PeiServices Pointer to PEI Services Table + +**/ +VOID +CollectBistDataFromPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor; + EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; + EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation; + UINTN NumberOfData; + EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance; + EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance; + UINTN ProcessorNumber; + UINTN CpuIndex; + EFI_PROCESSOR_INFORMATION ProcessorInfo; + EFI_HEALTH_FLAGS BistData; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + UINTN BistInformationSize; + EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2; + EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstanceInHob; + + + MpInitLibGetNumberOfProcessors(&NumberOfProcessors, &NumberOfEnabledProcessors); + + BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) + + sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors; + Status = PeiServicesAllocatePool ( + (UINTN) BistInformationSize, + (VOID **) &PlatformInformationRecord2 + ); + ASSERT_EFI_ERROR (Status); + PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors; + + SecPlatformInformation2 = NULL; + SecPlatformInformation = NULL; + NumberOfData = 0; + CpuInstance = NULL; + // + // Get BIST information from Sec Platform Information2 Ppi firstly + // + Status = GetBistInfoFromPpi ( + PeiServices, + &gEfiSecPlatformInformation2PpiGuid, + &SecInformationDescriptor, + (VOID *) &SecPlatformInformation2, + NULL + ); + if (Status == EFI_SUCCESS) { + // + // Sec Platform Information2 PPI includes BSP/APs' BIST information + // + NumberOfData = SecPlatformInformation2->NumberOfCpus; + CpuInstance = SecPlatformInformation2->CpuInstance; + } else { + // + // Otherwise, get BIST information from Sec Platform Information Ppi + // + Status = GetBistInfoFromPpi ( + PeiServices, + &gEfiSecPlatformInformationPpiGuid, + &SecInformationDescriptor, + (VOID *) &SecPlatformInformation, + NULL + ); + if (Status == EFI_SUCCESS) { + NumberOfData = 1; + // + // SEC Platform Information only includes BSP's BIST information + // and does not have BSP's APIC ID + // + BspCpuInstance.CpuLocation = GetInitialApicId (); + BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32; + CpuInstance = &BspCpuInstance; + } else { + DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n")); + } + } + for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber ++) { + MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData); + for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) { + ASSERT (CpuInstance != NULL); + if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) { + // + // Update processor's BIST data if it is already stored before + // + BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags; + } + } + if (BistData.Uint32 != 0) { + // + // Report Status Code that self test is failed + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST) + ); + } + DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n", + (UINT32) ProcessorInfo.ProcessorId, + BistData + )); + CpuInstanceInHob = PlatformInformationRecord2->CpuInstance; + CpuInstanceInHob[ProcessorNumber].CpuLocation = (UINT32) ProcessorInfo.ProcessorId; + CpuInstanceInHob[ProcessorNumber].InfoRecord.IA32HealthFlags = BistData; + } + + // + // Build SecPlatformInformation2 PPI GUIDed HOB that also could be consumed + // by CPU MP driver to get CPU BIST data + // + BuildGuidDataHob ( + &gEfiSecPlatformInformation2PpiGuid, + PlatformInformationRecord2, + (UINTN) BistInformationSize + ); + + if (SecPlatformInformation2 != NULL) { + if (NumberOfData < NumberOfProcessors) { + // + // Reinstall SecPlatformInformation2 PPI to include new BIST information + // + Status = PeiServicesReInstallPpi ( + SecInformationDescriptor, + &mPeiSecPlatformInformation2Ppi + ); + ASSERT_EFI_ERROR (Status); + } + } else { + // + // Install SecPlatformInformation2 PPI + // + Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi); + ASSERT_EFI_ERROR(Status); + } +} + diff --git a/UefiCpuPkg/CpuMpPei/CpuMp2Pei.c b/UefiCpuPkg/CpuMpPei/CpuMp2Pei.c new file mode 100644 index 000000000..c1116a5b7 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMp2Pei.c @@ -0,0 +1,417 @@ +/** @file + EDKII_PEI_MP_SERVICES2_PPI Implementation code. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuMpPei.h" + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Ppi provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] This Pointer to this instance of the PPI. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] NumberOfEnabledProcessors + Number of processors in the system that are enabled. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + NumberOfEnabledProcessors is NULL. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiGetNumberOfProcessors ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ) +{ + if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) { + return EFI_INVALID_PARAMETER; + } + + return MpInitLibGetNumberOfProcessors ( + NumberOfProcessors, + NumberOfEnabledProcessors + ); +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] This Pointer to this instance of the PPI. + @param[in] ProcessorNumber Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiGetProcessorInfo ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL); +} + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking requests only. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If the timeout specified by TimeoutInMicroSeconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EDKII_PEI_MP_SERVICES2_PPI.StartupAllAPs() + and EDKII_PEI_MP_SERVICES2_PPI.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EDKII_PEI_MP_SERVICES2_PPI.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Ppi does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. PEI services and Ppis may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroSeconds expires. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute the function + specified by Procedure one by one, in ascending order + of processor handle number. If FALSE, then all the + enabled APs execute the function specified by Procedure + simultaneously. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EDKII_PEI_MP_SERVICES2_PPI.StartupAllAPs() + or EDKII_PEI_MP_SERVICES2_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiStartupAllAPs ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return MpInitLibStartupAllAPs ( + Procedure, + SingleThread, + NULL, + TimeoutInMicroSeconds, + ProcedureArgument, + NULL + ); +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to wait for the completion + of the AP. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. + The execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSecondss expires. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EDKII_PEI_MP_SERVICES2_PPI.StartupAllAPs() and + EDKII_PEI_MP_SERVICES2_PPI.StartupThisAP(). + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EDKII_PEI_MP_SERVICES2_PPI.GetNumberOfProcessors(). + @param[in] TimeoutInMicroseconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EDKII_PEI_MP_SERVICES2_PPI.StartupAllAPs() + or EDKII_PEI_MP_SERVICES2_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before the + timeout expires. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the + specified AP has finished. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiStartupThisAP ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return MpInitLibStartupThisAP ( + Procedure, + ProcessorNumber, + NULL, + TimeoutInMicroseconds, + ProcedureArgument, + NULL + ); +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EDKII_PEI_MP_SERVICES2_PPI.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled + AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this + service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled + AP. + @retval EFI_NOT_READY The specified AP is busy. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiSwitchBSP ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP); +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EDKII_PEI_MP_SERVICES2_PPI.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for enabled, + FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies the + new health status of the AP. This flag corresponds to + StatusFlag defined in EDKII_PEI_MP_SERVICES2_PPI.GetProcessorInfo(). + Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter is + ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior + to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiEnableDisableAP ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag); +} + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EDKII_PEI_MP_SERVICES2_PPI.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EDKII_PEI_MP_SERVICES2_PPI.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned in + ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiWhoAmI ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + OUT UINTN *ProcessorNumber + ) +{ + return MpInitLibWhoAmI (ProcessorNumber); +} + +/** + This service executes a caller provided function on all enabled CPUs. CPUs can + run either simultaneously or one at a time in sequence. This service may only + be called from the BSP. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires in blocking + mode, BSP returns EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all CPUs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +EdkiiPeiStartupAllCPUs ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return MpInitLibStartupAllCPUs ( + Procedure, + TimeoutInMicroSeconds, + ProcedureArgument + ); +} + +// +// CPU MP2 PPI to be installed +// +EDKII_PEI_MP_SERVICES2_PPI mMpServices2Ppi = { + EdkiiPeiGetNumberOfProcessors, + EdkiiPeiGetProcessorInfo, + EdkiiPeiStartupAllAPs, + EdkiiPeiStartupThisAP, + EdkiiPeiSwitchBSP, + EdkiiPeiEnableDisableAP, + EdkiiPeiWhoAmI, + EdkiiPeiStartupAllCPUs +}; + diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c new file mode 100644 index 000000000..07ccbe7c6 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -0,0 +1,714 @@ +/** @file + CPU PEI Module installs CPU Multiple Processor PPI. + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuMpPei.h" + +extern EDKII_PEI_MP_SERVICES2_PPI mMpServices2Ppi; + +// +// CPU MP PPI to be installed +// +EFI_PEI_MP_SERVICES_PPI mMpServicesPpi = { + PeiGetNumberOfProcessors, + PeiGetProcessorInfo, + PeiStartupAllAPs, + PeiStartupThisAP, + PeiSwitchBSP, + PeiEnableDisableAP, + PeiWhoAmI, +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEdkiiPeiMpServices2PpiGuid, + &mMpServices2Ppi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMpServicesPpiGuid, + &mMpServicesPpi + } +}; + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Ppi provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This Pointer to this instance of the PPI. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] NumberOfEnabledProcessors + Number of processors in the system that are enabled. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + NumberOfEnabledProcessors is NULL. +**/ +EFI_STATUS +EFIAPI +PeiGetNumberOfProcessors ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ) +{ + if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) { + return EFI_INVALID_PARAMETER; + } + + return MpInitLibGetNumberOfProcessors ( + NumberOfProcessors, + NumberOfEnabledProcessors + ); +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This Pointer to this instance of the PPI. + @param[in] ProcessorNumber Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. +**/ +EFI_STATUS +EFIAPI +PeiGetProcessorInfo ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL); +} + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking requests only. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If the timeout specified by TimeoutInMicroSeconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Ppi does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. PEI services and Ppis may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroSeconds expires. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute the function + specified by Procedure one by one, in ascending order + of processor handle number. If FALSE, then all the + enabled APs execute the function specified by Procedure + simultaneously. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +PeiStartupAllAPs ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return MpInitLibStartupAllAPs ( + Procedure, + SingleThread, + NULL, + TimeoutInMicroSeconds, + ProcedureArgument, + NULL + ); +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to wait for the completion + of the AP. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. + The execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSecondss expires. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and + EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] TimeoutInMicroseconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before the + timeout expires. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the + specified AP has finished. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +PeiStartupThisAP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return MpInitLibStartupThisAP ( + Procedure, + ProcessorNumber, + NULL, + TimeoutInMicroseconds, + ProcedureArgument, + NULL + ); +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled + AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this + service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled + AP. + @retval EFI_NOT_READY The specified AP is busy. +**/ +EFI_STATUS +EFIAPI +PeiSwitchBSP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP); +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for enabled, + FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies the + new health status of the AP. This flag corresponds to + StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo(). + Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter is + ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior + to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. +**/ +EFI_STATUS +EFIAPI +PeiEnableDisableAP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag); +} + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned in + ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +**/ +EFI_STATUS +EFIAPI +PeiWhoAmI ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *ProcessorNumber + ) +{ + return MpInitLibWhoAmI (ProcessorNumber); +} + +/** + Get GDT register value. + + This function is mainly for AP purpose because AP may have different GDT + table than BSP. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +GetGdtr ( + IN OUT VOID *Buffer + ) +{ + AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer); +} + +/** + Initializes CPU exceptions handlers for the sake of stack switch requirement. + + This function is a wrapper of InitializeCpuExceptionHandlersEx. It's mainly + for the sake of AP's init because of EFI_AP_PROCEDURE API requirement. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +InitializeExceptionStackSwitchHandlers ( + IN OUT VOID *Buffer + ) +{ + CPU_EXCEPTION_INIT_DATA *EssData; + IA32_DESCRIPTOR Idtr; + EFI_STATUS Status; + + EssData = Buffer; + // + // We don't plan to replace IDT table with a new one, but we should not assume + // the AP's IDT is the same as BSP's IDT either. + // + AsmReadIdtr (&Idtr); + EssData->Ia32.IdtTable = (VOID *)Idtr.Base; + EssData->Ia32.IdtTableSize = Idtr.Limit + 1; + Status = InitializeCpuExceptionHandlersEx (NULL, EssData); + ASSERT_EFI_ERROR (Status); +} + +/** + Initializes MP exceptions handlers for the sake of stack switch requirement. + + This function will allocate required resources required to setup stack switch + and pass them through CPU_EXCEPTION_INIT_DATA to each logic processor. + +**/ +VOID +InitializeMpExceptionStackSwitchHandlers ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN Bsp; + UINTN ExceptionNumber; + UINTN OldGdtSize; + UINTN NewGdtSize; + UINTN NewStackSize; + IA32_DESCRIPTOR Gdtr; + CPU_EXCEPTION_INIT_DATA EssData; + UINT8 *GdtBuffer; + UINT8 *StackTop; + UINTN NumberOfProcessors; + + if (!PcdGetBool (PcdCpuStackGuard)) { + return; + } + + MpInitLibGetNumberOfProcessors(&NumberOfProcessors, NULL); + MpInitLibWhoAmI (&Bsp); + + ExceptionNumber = FixedPcdGetSize (PcdCpuStackSwitchExceptionList); + NewStackSize = FixedPcdGet32 (PcdCpuKnownGoodStackSize) * ExceptionNumber; + + Status = PeiServicesAllocatePool ( + NewStackSize * NumberOfProcessors, + (VOID **)&StackTop + ); + ASSERT(StackTop != NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + StackTop += NewStackSize * NumberOfProcessors; + + // + // The default exception handlers must have been initialized. Let's just skip + // it in this method. + // + EssData.Ia32.Revision = CPU_EXCEPTION_INIT_DATA_REV; + EssData.Ia32.InitDefaultHandlers = FALSE; + + EssData.Ia32.StackSwitchExceptions = FixedPcdGetPtr(PcdCpuStackSwitchExceptionList); + EssData.Ia32.StackSwitchExceptionNumber = ExceptionNumber; + EssData.Ia32.KnownGoodStackSize = FixedPcdGet32(PcdCpuKnownGoodStackSize); + + // + // Initialize Gdtr to suppress incorrect compiler/analyzer warnings. + // + Gdtr.Base = 0; + Gdtr.Limit = 0; + for (Index = 0; Index < NumberOfProcessors; ++Index) { + // + // To support stack switch, we need to re-construct GDT but not IDT. + // + if (Index == Bsp) { + GetGdtr(&Gdtr); + } else { + // + // AP might have different size of GDT from BSP. + // + MpInitLibStartupThisAP (GetGdtr, Index, NULL, 0, (VOID *)&Gdtr, NULL); + } + + // + // X64 needs only one TSS of current task working for all exceptions + // because of its IST feature. IA32 needs one TSS for each exception + // in addition to current task. Since AP is not supposed to allocate + // memory, we have to do it in BSP. To simplify the code, we allocate + // memory for IA32 case to cover both IA32 and X64 exception stack + // switch. + // + // Layout of memory to allocate for each processor: + // -------------------------------- + // | Alignment | (just in case) + // -------------------------------- + // | | + // | Original GDT | + // | | + // -------------------------------- + // | Current task descriptor | + // -------------------------------- + // | | + // | Exception task descriptors | X ExceptionNumber + // | | + // -------------------------------- + // | Current task-state segment | + // -------------------------------- + // | | + // | Exception task-state segment | X ExceptionNumber + // | | + // -------------------------------- + // + OldGdtSize = Gdtr.Limit + 1; + EssData.Ia32.ExceptionTssDescSize = sizeof (IA32_TSS_DESCRIPTOR) * + (ExceptionNumber + 1); + EssData.Ia32.ExceptionTssSize = sizeof (IA32_TASK_STATE_SEGMENT) * + (ExceptionNumber + 1); + NewGdtSize = sizeof (IA32_TSS_DESCRIPTOR) + + OldGdtSize + + EssData.Ia32.ExceptionTssDescSize + + EssData.Ia32.ExceptionTssSize; + + Status = PeiServicesAllocatePool ( + NewGdtSize, + (VOID **)&GdtBuffer + ); + ASSERT (GdtBuffer != NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + // + // Make sure GDT table alignment + // + EssData.Ia32.GdtTable = ALIGN_POINTER(GdtBuffer, sizeof (IA32_TSS_DESCRIPTOR)); + NewGdtSize -= ((UINT8 *)EssData.Ia32.GdtTable - GdtBuffer); + EssData.Ia32.GdtTableSize = NewGdtSize; + + EssData.Ia32.ExceptionTssDesc = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize); + EssData.Ia32.ExceptionTss = ((UINT8 *)EssData.Ia32.GdtTable + OldGdtSize + + EssData.Ia32.ExceptionTssDescSize); + + EssData.Ia32.KnownGoodStackTop = (UINTN)StackTop; + DEBUG ((DEBUG_INFO, + "Exception stack top[cpu%lu]: 0x%lX\n", + (UINT64)(UINTN)Index, + (UINT64)(UINTN)StackTop)); + + if (Index == Bsp) { + InitializeExceptionStackSwitchHandlers (&EssData); + } else { + MpInitLibStartupThisAP ( + InitializeExceptionStackSwitchHandlers, + Index, + NULL, + 0, + (VOID *)&EssData, + NULL + ); + } + + StackTop -= NewStackSize; + } +} + +/** + Initializes MP and exceptions handlers. + + @param PeiServices The pointer to the PEI Services Table. + + @retval EFI_SUCCESS MP was successfully initialized. + @retval others Error occurred in MP initialization. + +**/ +EFI_STATUS +InitializeCpuMpWorker ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_VECTOR_HANDOFF_INFO *VectorInfo; + EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; + + // + // Get Vector Hand-off Info PPI + // + VectorInfo = NULL; + Status = PeiServicesLocatePpi ( + &gEfiVectorHandoffInfoPpiGuid, + 0, + NULL, + (VOID **)&VectorHandoffInfoPpi + ); + if (Status == EFI_SUCCESS) { + VectorInfo = VectorHandoffInfoPpi->Info; + } + + // + // Initialize default handlers + // + Status = InitializeCpuExceptionHandlers (VectorInfo); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = MpInitLibInitialize (); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Special initialization for the sake of Stack Guard + // + InitializeMpExceptionStackSwitchHandlers (); + + // + // Update and publish CPU BIST information + // + CollectBistDataFromPpi (PeiServices); + + // + // Install CPU MP PPI + // + Status = PeiServicesInstallPpi(mPeiCpuMpPpiList); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + The Entry point of the MP CPU PEIM. + + This function will wakeup APs and collect CPU AP count and install the + Mp Service Ppi. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS MpServicePpi is installed successfully. + +**/ +EFI_STATUS +EFIAPI +CpuMpPeimInit ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + // + // For the sake of special initialization needing to be done right after + // memory discovery. + // + Status = PeiServicesNotifyPpi (&mPostMemNotifyList[0]); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h new file mode 100644 index 000000000..7d5c527d6 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -0,0 +1,437 @@ +/** @file + Definitions to install Multiple Processor PPI. + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_MP_PEI_H_ +#define _CPU_MP_PEI_H_ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc; + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Ppi provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This Pointer to this instance of the PPI. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] NumberOfEnabledProcessors + Number of processors in the system that are enabled. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + NumberOfEnabledProcessors is NULL. +**/ +EFI_STATUS +EFIAPI +PeiGetNumberOfProcessors ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This Pointer to this instance of the PPI. + @param[in] ProcessorNumber Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. +**/ +EFI_STATUS +EFIAPI +PeiGetProcessorInfo ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking requests only. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If the timeout specified by TimeoutInMicroSeconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Ppi does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. PEI services and Ppis may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroSeconds expires. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute the function + specified by Procedure one by one, in ascending order + of processor handle number. If FALSE, then all the + enabled APs execute the function specified by Procedure + simultaneously. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +PeiStartupAllAPs ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to wait for the completion + of the AP. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. + The execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSecondss expires. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and + EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] TimeoutInMicroseconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before the + timeout expires. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the + specified AP has finished. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +EFI_STATUS +EFIAPI +PeiStartupThisAP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled + AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this + service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled + AP. + @retval EFI_NOT_READY The specified AP is busy. +**/ +EFI_STATUS +EFIAPI +PeiSwitchBSP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for enabled, + FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies the + new health status of the AP. This flag corresponds to + StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo(). + Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter is + ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior + to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. +**/ +EFI_STATUS +EFIAPI +PeiEnableDisableAP ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned in + ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +**/ +EFI_STATUS +EFIAPI +PeiWhoAmI ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_MP_SERVICES_PPI *This, + OUT UINTN *ProcessorNumber + ); + +/** + Collects BIST data from PPI. + + This function collects BIST data from Sec Platform Information2 PPI + or SEC Platform Information PPI. + + @param PeiServices Pointer to PEI Services Table + +**/ +VOID +CollectBistDataFromPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. + + @param PeiServices The pointer to the PEI Services Table. + @param StructureSize The pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to + hold the record is returned in StructureSize. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation2 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 + ); + +/** + Initializes MP and exceptions handlers. + + @param PeiServices The pointer to the PEI Services Table. + + @retval EFI_SUCCESS MP was successfully initialized. + @retval others Error occurred in MP initialization. + +**/ +EFI_STATUS +InitializeCpuMpWorker ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE. + + Doing this in the memory-discovered callback is to make sure the Stack Guard + feature to cover as most PEI code as possible. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. + @retval others There's error in MP initialization. +**/ +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +extern EFI_PEI_NOTIFY_DESCRIPTOR mPostMemNotifyList[]; + +#endif diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf new file mode 100644 index 000000000..caead3ce3 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf @@ -0,0 +1,72 @@ +## @file +# CPU driver installs CPU PI Multi-processor PPI. +# +# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuMpPei + MODULE_UNI_FILE = CpuMpPei.uni + FILE_GUID = EDADEB9D-DDBA-48BD-9D22-C1C169C8C5C6 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = CpuMpPeimInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CpuMpPei.h + CpuMpPei.c + CpuBist.c + CpuPaging.c + CpuMp2Pei.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + HobLib + LocalApicLib + PeimEntryPoint + PeiServicesLib + ReportStatusCodeLib + CpuExceptionHandlerLib + MpInitLib + BaseMemoryLib + CpuLib + +[Ppis] + gEfiPeiMpServicesPpiGuid ## PRODUCES + gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES + ## SOMETIMES_CONSUMES + ## PRODUCES + ## UNDEFINED # HOB + gEfiSecPlatformInformation2PpiGuid + gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES + gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES + gEdkiiPeiMpServices2PpiGuid ## PRODUCES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + CpuMpPeiExtra.uni + diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.uni b/UefiCpuPkg/CpuMpPei/CpuMpPei.uni new file mode 100644 index 000000000..bbb395fd4 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU driver installs CPU PI Multi-processor PPI. +// +// CPU driver installs CPU PI Multi-processor PPI. +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Installs CPU PI Multi-processor PPI" + +#string STR_MODULE_DESCRIPTION #language en-US "CPU driver installs CPU PI Multi-processor PPI." + diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni b/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni new file mode 100644 index 000000000..f84e1841b --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuMpPei Localized Strings and Content +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"CPU Multi-processor PEIM Driver" + + diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c new file mode 100644 index 000000000..a462e7ee1 --- /dev/null +++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c @@ -0,0 +1,628 @@ +/** @file + Basic paging support for the CPU to enable Stack Guard. + +Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#include "CpuMpPei.h" + +#define IA32_PG_P BIT0 +#define IA32_PG_RW BIT1 +#define IA32_PG_U BIT2 +#define IA32_PG_A BIT5 +#define IA32_PG_D BIT6 +#define IA32_PG_PS BIT7 +#define IA32_PG_NX BIT63 + +#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P) +#define PAGE_PROGATE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_NX | IA32_PG_U |\ + PAGE_ATTRIBUTE_BITS) + +#define PAGING_PAE_INDEX_MASK 0x1FF +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull +#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull +#define PAGING_512G_ADDRESS_MASK_64 0x000FFF8000000000ull + +typedef enum { + PageNone = 0, + PageMin = 1, + Page4K = PageMin, + Page2M = 2, + Page1G = 3, + Page512G = 4, + PageMax = Page512G +} PAGE_ATTRIBUTE; + +typedef struct { + PAGE_ATTRIBUTE Attribute; + UINT64 Length; + UINT64 AddressMask; + UINTN AddressBitOffset; + UINTN AddressBitLength; +} PAGE_ATTRIBUTE_TABLE; + +PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { + {PageNone, 0, 0, 0, 0}, + {Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64, 12, 9}, + {Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64, 21, 9}, + {Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64, 30, 9}, + {Page512G, SIZE_512GB, PAGING_512G_ADDRESS_MASK_64, 39, 9}, +}; + +EFI_PEI_NOTIFY_DESCRIPTOR mPostMemNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + MemoryDiscoveredPpiNotifyCallback + } +}; + +/** + The function will check if IA32 PAE is supported. + + @retval TRUE IA32 PAE is supported. + @retval FALSE IA32 PAE is not supported. + +**/ +BOOLEAN +IsIa32PaeSupported ( + VOID + ) +{ + UINT32 RegEax; + CPUID_VERSION_INFO_EDX RegEdx; + + AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_VERSION_INFO) { + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx.Uint32); + if (RegEdx.Bits.PAE != 0) { + return TRUE; + } + } + + return FALSE; +} + +/** + This API provides a way to allocate memory for page table. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +AllocatePageTableMemory ( + IN UINTN Pages + ) +{ + VOID *Address; + + Address = AllocatePages(Pages); + if (Address != NULL) { + ZeroMem(Address, EFI_PAGES_TO_SIZE (Pages)); + } + + return Address; +} + +/** + Get the address width supported by current processor. + + @retval 32 If processor is in 32-bit mode. + @retval 36-48 If processor is in 64-bit mode. + +**/ +UINTN +GetPhysicalAddressWidth ( + VOID + ) +{ + UINT32 RegEax; + + if (sizeof(UINTN) == 4) { + return 32; + } + + 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); + RegEax &= 0xFF; + if (RegEax > 48) { + return 48; + } + + return (UINTN)RegEax; + } + + return 36; +} + +/** + Get the type of top level page table. + + @retval Page512G PML4 paging. + @retval Page1G PAE paing. + +**/ +PAGE_ATTRIBUTE +GetPageTableTopLevelType ( + VOID + ) +{ + MSR_IA32_EFER_REGISTER MsrEfer; + + MsrEfer.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_EFER); + + return (MsrEfer.Bits.LMA == 1) ? Page512G : Page1G; +} + +/** + Return page table entry matching the address. + + @param[in] Address The address to be checked. + @param[out] PageAttributes The page attribute of the page entry. + + @return The page entry. +**/ +VOID * +GetPageTableEntry ( + IN PHYSICAL_ADDRESS Address, + OUT PAGE_ATTRIBUTE *PageAttribute + ) +{ + INTN Level; + UINTN Index; + UINT64 *PageTable; + UINT64 AddressEncMask; + + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask); + PageTable = (UINT64 *)(UINTN)(AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64); + for (Level = (INTN)GetPageTableTopLevelType (); Level > 0; --Level) { + Index = (UINTN)RShiftU64 (Address, mPageAttributeTable[Level].AddressBitOffset); + Index &= PAGING_PAE_INDEX_MASK; + + // + // No mapping? + // + if (PageTable[Index] == 0) { + *PageAttribute = PageNone; + return NULL; + } + + // + // Page memory? + // + if ((PageTable[Index] & IA32_PG_PS) != 0 || Level == PageMin) { + *PageAttribute = (PAGE_ATTRIBUTE)Level; + return &PageTable[Index]; + } + + // + // Page directory or table + // + PageTable = (UINT64 *)(UINTN)(PageTable[Index] & + ~AddressEncMask & + PAGING_4K_ADDRESS_MASK_64); + } + + *PageAttribute = PageNone; + return NULL; +} + +/** + This function splits one page entry to smaller page entries. + + @param[in] PageEntry The page entry to be splitted. + @param[in] PageAttribute The page attribute of the page entry. + @param[in] SplitAttribute How to split the page entry. + @param[in] Recursively Do the split recursively or not. + + @retval RETURN_SUCCESS The page entry is splitted. + @retval RETURN_INVALID_PARAMETER If target page attribute is invalid + @retval RETURN_OUT_OF_RESOURCES No resource to split page entry. +**/ +RETURN_STATUS +SplitPage ( + IN UINT64 *PageEntry, + IN PAGE_ATTRIBUTE PageAttribute, + IN PAGE_ATTRIBUTE SplitAttribute, + IN BOOLEAN Recursively + ) +{ + UINT64 BaseAddress; + UINT64 *NewPageEntry; + UINTN Index; + UINT64 AddressEncMask; + PAGE_ATTRIBUTE SplitTo; + + if (SplitAttribute == PageNone || SplitAttribute >= PageAttribute) { + ASSERT (SplitAttribute != PageNone); + ASSERT (SplitAttribute < PageAttribute); + return RETURN_INVALID_PARAMETER; + } + + NewPageEntry = AllocatePageTableMemory (1); + if (NewPageEntry == NULL) { + ASSERT (NewPageEntry != NULL); + return RETURN_OUT_OF_RESOURCES; + } + + // + // One level down each step to achieve more compact page table. + // + SplitTo = PageAttribute - 1; + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & + mPageAttributeTable[SplitTo].AddressMask; + BaseAddress = *PageEntry & + ~PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & + mPageAttributeTable[PageAttribute].AddressMask; + for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { + NewPageEntry[Index] = BaseAddress | AddressEncMask | + ((*PageEntry) & PAGE_PROGATE_BITS); + + if (SplitTo != PageMin) { + NewPageEntry[Index] |= IA32_PG_PS; + } + + if (Recursively && SplitTo > SplitAttribute) { + SplitPage (&NewPageEntry[Index], SplitTo, SplitAttribute, Recursively); + } + + BaseAddress += mPageAttributeTable[SplitTo].Length; + } + + (*PageEntry) = (UINT64)(UINTN)NewPageEntry | AddressEncMask | PAGE_ATTRIBUTE_BITS; + + return RETURN_SUCCESS; +} + +/** + This function modifies the page attributes for the memory region specified + by BaseAddress and Length from their current attributes to the attributes + specified by Attributes. + + Caller should make sure BaseAddress and Length is at page boundary. + + @param[in] BaseAddress Start address of a memory region. + @param[in] Length Size in bytes of the memory region. + @param[in] Attributes Bit mask of attributes to modify. + + @retval RETURN_SUCCESS The attributes were modified for the memory + region. + @retval RETURN_INVALID_PARAMETER Length is zero; or, + Attributes specified an illegal combination + of attributes that cannot be set together; or + Addressis not 4KB aligned. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify + the attributes. + @retval RETURN_UNSUPPORTED Cannot modify the attributes of given memory. + +**/ +RETURN_STATUS +EFIAPI +ConvertMemoryPageAttributes ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + UINT64 *PageEntry; + PAGE_ATTRIBUTE PageAttribute; + RETURN_STATUS Status; + EFI_PHYSICAL_ADDRESS MaximumAddress; + + if (Length == 0 || + (BaseAddress & (SIZE_4KB - 1)) != 0 || + (Length & (SIZE_4KB - 1)) != 0) { + + ASSERT (Length > 0); + ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); + ASSERT ((Length & (SIZE_4KB - 1)) == 0); + + return RETURN_INVALID_PARAMETER; + } + + MaximumAddress = (EFI_PHYSICAL_ADDRESS)MAX_UINT32; + if (BaseAddress > MaximumAddress || + Length > MaximumAddress || + (BaseAddress > MaximumAddress - (Length - 1))) { + return RETURN_UNSUPPORTED; + } + + // + // Below logic is to check 2M/4K page to make sure we do not waste memory. + // + while (Length != 0) { + PageEntry = GetPageTableEntry (BaseAddress, &PageAttribute); + if (PageEntry == NULL) { + return RETURN_UNSUPPORTED; + } + + if (PageAttribute != Page4K) { + Status = SplitPage (PageEntry, PageAttribute, Page4K, FALSE); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Do it again until the page is 4K. + // + continue; + } + + // + // Just take care of 'present' bit for Stack Guard. + // + if ((Attributes & IA32_PG_P) != 0) { + *PageEntry |= (UINT64)IA32_PG_P; + } else { + *PageEntry &= ~((UINT64)IA32_PG_P); + } + + // + // Convert success, move to next + // + BaseAddress += SIZE_4KB; + Length -= SIZE_4KB; + } + + return RETURN_SUCCESS; +} + +/** + Get maximum size of page memory supported by current processor. + + @param[in] TopLevelType The type of top level page entry. + + @retval Page1G If processor supports 1G page and PML4. + @retval Page2M For all other situations. + +**/ +PAGE_ATTRIBUTE +GetMaxMemoryPage ( + IN PAGE_ATTRIBUTE TopLevelType + ) +{ + UINT32 RegEax; + UINT32 RegEdx; + + if (TopLevelType == Page512G) { + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + return Page1G; + } + } + } + + return Page2M; +} + +/** + Create PML4 or PAE page table. + + @return The address of page table. + +**/ +UINTN +CreatePageTable ( + VOID + ) +{ + RETURN_STATUS Status; + UINTN PhysicalAddressBits; + UINTN NumberOfEntries; + PAGE_ATTRIBUTE TopLevelPageAttr; + UINTN PageTable; + PAGE_ATTRIBUTE MaxMemoryPage; + UINTN Index; + UINT64 AddressEncMask; + UINT64 *PageEntry; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + + TopLevelPageAttr = (PAGE_ATTRIBUTE)GetPageTableTopLevelType (); + PhysicalAddressBits = GetPhysicalAddressWidth (); + NumberOfEntries = (UINTN)1 << (PhysicalAddressBits - + mPageAttributeTable[TopLevelPageAttr].AddressBitOffset); + + PageTable = (UINTN) AllocatePageTableMemory (1); + if (PageTable == 0) { + return 0; + } + + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask); + AddressEncMask &= mPageAttributeTable[TopLevelPageAttr].AddressMask; + MaxMemoryPage = GetMaxMemoryPage (TopLevelPageAttr); + PageEntry = (UINT64 *)PageTable; + + PhysicalAddress = 0; + for (Index = 0; Index < NumberOfEntries; ++Index) { + *PageEntry = PhysicalAddress | AddressEncMask | PAGE_ATTRIBUTE_BITS; + + // + // Split the top page table down to the maximum page size supported + // + if (MaxMemoryPage < TopLevelPageAttr) { + Status = SplitPage(PageEntry, TopLevelPageAttr, MaxMemoryPage, TRUE); + ASSERT_EFI_ERROR (Status); + } + + if (TopLevelPageAttr == Page1G) { + // + // PDPTE[2:1] (PAE Paging) must be 0. SplitPage() might change them to 1. + // + *PageEntry &= ~(UINT64)(IA32_PG_RW | IA32_PG_U); + } + + PageEntry += 1; + PhysicalAddress += mPageAttributeTable[TopLevelPageAttr].Length; + } + + + return PageTable; +} + +/** + Setup page tables and make them work. + +**/ +VOID +EnablePaging ( + VOID + ) +{ + UINTN PageTable; + + PageTable = CreatePageTable (); + ASSERT (PageTable != 0); + if (PageTable != 0) { + AsmWriteCr3(PageTable); + AsmWriteCr4 (AsmReadCr4 () | BIT5); // CR4.PAE + AsmWriteCr0 (AsmReadCr0 () | BIT31); // CR0.PG + } +} + +/** + Get the base address of current AP's stack. + + This function is called in AP's context and assumes that whole calling stacks + (till this function) consumed by AP's wakeup procedure will not exceed 4KB. + + PcdCpuApStackSize must be configured with value taking the Guard page into + account. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +GetStackBase ( + IN OUT VOID *Buffer + ) +{ + EFI_PHYSICAL_ADDRESS StackBase; + + StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)&StackBase; + StackBase += BASE_4KB; + StackBase &= ~((EFI_PHYSICAL_ADDRESS)BASE_4KB - 1); + StackBase -= PcdGet32(PcdCpuApStackSize); + + *(EFI_PHYSICAL_ADDRESS *)Buffer = StackBase; +} + +/** + Setup stack Guard page at the stack base of each processor. BSP and APs have + different way to get stack base address. + +**/ +VOID +SetupStackGuardPage ( + VOID + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PHYSICAL_ADDRESS StackBase; + UINTN NumberOfProcessors; + UINTN Bsp; + UINTN Index; + + // + // One extra page at the bottom of the stack is needed for Guard page. + // + if (PcdGet32(PcdCpuApStackSize) <= EFI_PAGE_SIZE) { + DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n")); + ASSERT (FALSE); + } + + MpInitLibGetNumberOfProcessors(&NumberOfProcessors, NULL); + MpInitLibWhoAmI (&Bsp); + for (Index = 0; Index < NumberOfProcessors; ++Index) { + StackBase = 0; + + if (Index == Bsp) { + Hob.Raw = GetHobList (); + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { + if (CompareGuid (&gEfiHobMemoryAllocStackGuid, + &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { + StackBase = Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress; + break; + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + } else { + // + // Ask AP to return is stack base address. + // + MpInitLibStartupThisAP(GetStackBase, Index, NULL, 0, (VOID *)&StackBase, NULL); + } + ASSERT (StackBase != 0); + // + // Set Guard page at stack base address. + // + ConvertMemoryPageAttributes(StackBase, EFI_PAGE_SIZE, 0); + DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n", + (UINT64)StackBase, (UINT64)Index)); + } + + // + // Publish the changes of page table. + // + CpuFlushTlb (); +} + +/** + Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE. + + Doing this in the memory-discovered callback is to make sure the Stack Guard + feature to cover as most PEI code as possible. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. + @retval others There's error in MP initialization. +**/ +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + BOOLEAN InitStackGuard; + + // + // Paging must be setup first. Otherwise the exception TSS setup during MP + // initialization later will not contain paging information and then fail + // the task switch (for the sake of stack switch). + // + InitStackGuard = FALSE; + if (IsIa32PaeSupported () && PcdGetBool (PcdCpuStackGuard)) { + EnablePaging (); + InitStackGuard = TRUE; + } + + Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices); + ASSERT_EFI_ERROR (Status); + + if (InitStackGuard) { + SetupStackGuardPage (); + } + + return Status; +} + diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c new file mode 100644 index 000000000..2be335d91 --- /dev/null +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c @@ -0,0 +1,309 @@ +/** @file +ACPI CPU Data initialization module + +This module initializes the ACPI_CPU_DATA structure and registers the address +of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple +version of this module. It does not provide a machine check handler or CPU +register initialization tables for ACPI S3 resume. It also only supports the +number of CPUs reported by the MP Services Protocol, so this module does not +support hot plug CPUs. This module can be copied into a CPU specific package +and customized if these additional features are required. + +Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2015, Red Hat, Inc. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +// +// Data structure used to allocate ACPI_CPU_DATA and its supporting structures +// +typedef struct { + ACPI_CPU_DATA AcpiCpuData; + MTRR_SETTINGS MtrrTable; + IA32_DESCRIPTOR GdtrProfile; + IA32_DESCRIPTOR IdtrProfile; +} ACPI_CPU_DATA_EX; + +/** + Allocate EfiACPIMemoryNVS memory. + + @param[in] Size Size of memory to allocate. + + @return Allocated address for output. + +**/ +VOID * +AllocateAcpiNvsMemory ( + IN UINTN Size + ) +{ + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + VOID *Buffer; + + Status = gBS->AllocatePages ( + AllocateAnyPages, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (Size), + &Address + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Address; + ZeroMem (Buffer, Size); + + return Buffer; +} + +/** + Allocate memory and clean it with zero. + + @param[in] Size Size of memory to allocate. + + @return Allocated address for output. + +**/ +VOID * +AllocateZeroPages ( + IN UINTN Size + ) +{ + VOID *Buffer; + + Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Size)); + if (Buffer != NULL) { + ZeroMem (Buffer, Size); + } + + return Buffer; +} +/** + Callback function executed when the EndOfDxe event group is signaled. + + We delay allocating StartupVector and saving the MTRR settings until BDS signals EndOfDxe. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the MTRR_SETTINGS buffer to fill in. +**/ +VOID +EFIAPI +CpuS3DataOnEndOfDxe ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_STATUS Status; + ACPI_CPU_DATA_EX *AcpiCpuDataEx; + + AcpiCpuDataEx = (ACPI_CPU_DATA_EX *) Context; + // + // Allocate a 4KB reserved page below 1MB + // + AcpiCpuDataEx->AcpiCpuData.StartupVector = BASE_1MB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + 1, + &AcpiCpuDataEx->AcpiCpuData.StartupVector + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_VERBOSE, "%a\n", __FUNCTION__)); + MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable); + + // + // Close event, so it will not be invoked again. + // + gBS->CloseEvent (Event); +} + +/** + The entry function of the CpuS3Data driver. + + Allocate and initialize all fields of the ACPI_CPU_DATA structure except the + MTRR settings. Register an event notification on gEfiEndOfDxeEventGroupGuid + to capture the ACPI_CPU_DATA MTRR settings. The PcdCpuS3DataAddress is set + to the address that ACPI_CPU_DATA is allocated at. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval EFI_UNSUPPORTED Do not support ACPI S3. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +CpuS3DataInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + ACPI_CPU_DATA_EX *AcpiCpuDataEx; + ACPI_CPU_DATA *AcpiCpuData; + EFI_MP_SERVICES_PROTOCOL *MpServices; + UINTN NumberOfCpus; + UINTN NumberOfEnabledProcessors; + VOID *Stack; + UINTN TableSize; + CPU_REGISTER_TABLE *RegisterTable; + UINTN Index; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + UINTN GdtSize; + UINTN IdtSize; + VOID *Gdt; + VOID *Idt; + EFI_EVENT Event; + ACPI_CPU_DATA *OldAcpiCpuData; + + if (!PcdGetBool (PcdAcpiS3Enable)) { + return EFI_UNSUPPORTED; + } + + // + // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure + // + OldAcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress); + + AcpiCpuDataEx = AllocateZeroPages (sizeof (ACPI_CPU_DATA_EX)); + ASSERT (AcpiCpuDataEx != NULL); + AcpiCpuData = &AcpiCpuDataEx->AcpiCpuData; + + // + // Get MP Services Protocol + // + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **)&MpServices + ); + ASSERT_EFI_ERROR (Status); + + // + // Get the number of CPUs + // + Status = MpServices->GetNumberOfProcessors ( + MpServices, + &NumberOfCpus, + &NumberOfEnabledProcessors + ); + ASSERT_EFI_ERROR (Status); + AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus; + + // + // Initialize ACPI_CPU_DATA fields + // + AcpiCpuData->StackSize = PcdGet32 (PcdCpuApStackSize); + AcpiCpuData->ApMachineCheckHandlerBase = 0; + AcpiCpuData->ApMachineCheckHandlerSize = 0; + AcpiCpuData->GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->GdtrProfile; + AcpiCpuData->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->IdtrProfile; + AcpiCpuData->MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->MtrrTable; + + // + // Allocate stack space for all CPUs. + // Use ACPI NVS memory type because this data will be directly used by APs + // in S3 resume phase in long mode. Also during S3 resume, the stack buffer + // will only be used as scratch space. i.e. we won't read anything from it + // before we write to it, in PiSmmCpuDxeSmm. + // + Stack = AllocateAcpiNvsMemory (NumberOfCpus * AcpiCpuData->StackSize); + ASSERT (Stack != NULL); + AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Stack; + + // + // Get the boot processor's GDT and IDT + // + AsmReadGdtr (&AcpiCpuDataEx->GdtrProfile); + AsmReadIdtr (&AcpiCpuDataEx->IdtrProfile); + + // + // Allocate GDT and IDT and copy current GDT and IDT contents + // + GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1; + IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1; + Gdt = AllocateZeroPages (GdtSize + IdtSize); + ASSERT (Gdt != NULL); + Idt = (VOID *)((UINTN)Gdt + GdtSize); + CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize); + CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize); + AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt; + AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt; + + if (OldAcpiCpuData != NULL) { + AcpiCpuData->RegisterTable = OldAcpiCpuData->RegisterTable; + AcpiCpuData->PreSmmInitRegisterTable = OldAcpiCpuData->PreSmmInitRegisterTable; + AcpiCpuData->ApLocation = OldAcpiCpuData->ApLocation; + CopyMem (&AcpiCpuData->CpuStatus, &OldAcpiCpuData->CpuStatus, sizeof (CPU_STATUS_INFORMATION)); + } else { + // + // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs + // + TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE); + RegisterTable = (CPU_REGISTER_TABLE *)AllocateZeroPages (TableSize); + ASSERT (RegisterTable != NULL); + + for (Index = 0; Index < NumberOfCpus; Index++) { + Status = MpServices->GetProcessorInfo ( + MpServices, + Index, + &ProcessorInfoBuffer + ); + ASSERT_EFI_ERROR (Status); + + RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId; + RegisterTable[Index].TableLength = 0; + RegisterTable[Index].AllocatedSize = 0; + RegisterTable[Index].RegisterTableEntry = 0; + + RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId; + RegisterTable[NumberOfCpus + Index].TableLength = 0; + RegisterTable[NumberOfCpus + Index].AllocatedSize = 0; + RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0; + } + AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable; + AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus); + } + + // + // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure + // + Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData); + ASSERT_EFI_ERROR (Status); + + // + // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event. + // The notification function allocates StartupVector and saves MTRRs for ACPI_CPU_DATA + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + CpuS3DataOnEndOfDxe, + AcpiCpuData, + &gEfiEndOfDxeEventGroupGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf new file mode 100644 index 000000000..510133a61 --- /dev/null +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf @@ -0,0 +1,65 @@ +## @file +# ACPI CPU Data initialization module +# +# This module initializes the ACPI_CPU_DATA structure and registers the address +# of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple +# version of this module. It does not provide a machine check handler or CPU +# register initialization tables for ACPI S3 resume. It also only supports the +# number of CPUs reported by the MP Services Protocol, so this module does not +# support hot plug CPUs. This module can be copied into a CPU specific package +# and customized if these additional features are required. +# +# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2015, Red Hat, Inc. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuS3DataDxe + MODULE_UNI_FILE = CpuS3DataDxe.uni + FILE_GUID = 4D2E57EE-0E3F-44DD-93C4-D3B57E96945D + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = CpuS3DataInitialize + +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 + +[Sources] + CpuS3Data.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + BaseLib + MtrrLib + MemoryAllocationLib + +[Guids] + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + +[Protocols] + gEfiMpServiceProtocolGuid ## CONSUMES + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES + +[Depex] + gEfiMpServiceProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + CpuS3DataDxeExtra.uni diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni new file mode 100644 index 000000000..d16c03fc7 --- /dev/null +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni @@ -0,0 +1,34 @@ +// /** @file +// ACPI CPU Data initialization module +// +// This module initializes the ACPI_CPU_DATA structure and registers the address +// of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple +// version of this module. It does not provide a machine check handler or CPU +// register initialization tables for ACPI S3 resume. It also only supports the +// number of CPUs reported by the MP Services Protocol, so this module does not +// support hot plug CPUs. This module can be copied into a CPU specific package +// and customized if these additional features are required. +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// Copyright (c) 2015, Red Hat, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT +#language en-US +"ACPI CPU Data initialization module" + +#string STR_MODULE_DESCRIPTION +#language en-US +"This module initializes the ACPI_CPU_DATA structure and registers the address " +"of this structure in the PcdCpuS3DataAddress PCD. This is a generic/simple " +"version of this module. It does not provide a machine check handler or CPU " +"register initialization tables for ACPI S3 resume. It also only supports the " +"number of CPUs reported by the MP Services Protocol, so this module does not " +"support hot plug CPUs. This module can be copied into a CPU specific package " +"and customized if these additional features are required." + + diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni new file mode 100644 index 000000000..42653f20b --- /dev/null +++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// CpuS3DataDxe Localized Strings and Content +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// Copyright (c) 2015, Red Hat, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME #language en-US "CpuS3DataDxe module" + + diff --git a/UefiCpuPkg/Include/AcpiCpuData.h b/UefiCpuPkg/Include/AcpiCpuData.h new file mode 100644 index 000000000..77da5d445 --- /dev/null +++ b/UefiCpuPkg/Include/AcpiCpuData.h @@ -0,0 +1,212 @@ +/** @file +Definitions for CPU S3 data. + +Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _ACPI_CPU_DATA_H_ +#define _ACPI_CPU_DATA_H_ + +// +// Register types in register table +// +typedef enum { + Msr, + ControlRegister, + MemoryMapped, + CacheControl, + + // + // Semaphore type used to control the execute sequence of the Msr. + // It will be insert between two Msr which has execute dependence. + // + Semaphore, + InvalidReg +} REGISTER_TYPE; + +// +// Describe the dependency type for different features. +// The value set to CPU_REGISTER_TABLE_ENTRY.Value when the REGISTER_TYPE is Semaphore. +// +typedef enum { + NoneDepType, + ThreadDepType, + CoreDepType, + PackageDepType, + InvalidDepType +} CPU_FEATURE_DEPENDENCE_TYPE; + +// +// CPU information. +// +typedef struct { + // + // Record the package count in this CPU. + // + UINT32 PackageCount; + // + // Record the max core count in this CPU. + // Different packages may have different core count, this value + // save the max core count in all the packages. + // + UINT32 MaxCoreCount; + // + // Record the max thread count in this CPU. + // Different cores may have different thread count, this value + // save the max thread count in all the cores. + // + UINT32 MaxThreadCount; + // + // This field points to an array. + // This array saves valid core count (type UINT32) of each package. + // The array has PackageCount elements. + // + // If the platform does not support MSR setting at S3 resume, and + // therefore it doesn't need the dependency semaphores, it should set + // this field to 0. + // + EFI_PHYSICAL_ADDRESS ValidCoreCountPerPackage; +} CPU_STATUS_INFORMATION; + +// +// Element of register table entry +// +typedef struct { + REGISTER_TYPE RegisterType; // offset 0 - 3 + UINT32 Index; // offset 4 - 7 + UINT8 ValidBitStart; // offset 8 + UINT8 ValidBitLength; // offset 9 + BOOLEAN TestThenWrite; // offset 10 + UINT8 Reserved1; // offset 11 + UINT32 HighIndex; // offset 12-15, only valid for MemoryMapped + UINT64 Value; // offset 16-23 +} CPU_REGISTER_TABLE_ENTRY; + +// +// Register table definition, including current table length, +// allocated size of this table, and pointer to the list of table entries. +// +typedef struct { + // + // The number of valid entries in the RegisterTableEntry buffer + // + UINT32 TableLength; + UINT32 NumberBeforeReset; + // + // The size, in bytes, of the RegisterTableEntry buffer + // + UINT32 AllocatedSize; + // + // The initial APIC ID of the CPU this register table applies to + // + UINT32 InitialApicId; + // + // Physical address of CPU_REGISTER_TABLE_ENTRY structures. + // + EFI_PHYSICAL_ADDRESS RegisterTableEntry; +} CPU_REGISTER_TABLE; + +// +// Data structure that is required for ACPI S3 resume. The PCD +// PcdCpuS3DataAddress must be set to the physical address where this structure +// is allocated +// +typedef struct { + // + // Physical address of 4KB buffer allocated below 1MB from memory of type + // EfiReservedMemoryType. The buffer is not required to be initialized, but + // it is recommended that the buffer be zero-filled. This buffer is used to + // wake APs during an ACPI S3 resume. + // + EFI_PHYSICAL_ADDRESS StartupVector; + // + // Physical address of structure of type IA32_DESCRIPTOR. The + // IA32_DESCRIPTOR structure provides the base address and length of a GDT + // The GDT must be filled in with the GDT contents that are + // used during an ACPI S3 resume. This is typically the contents of the GDT + // used by the boot processor when the platform is booted. + // + EFI_PHYSICAL_ADDRESS GdtrProfile; + // + // Physical address of structure of type IA32_DESCRIPTOR. The + // IA32_DESCRIPTOR structure provides the base address and length of an IDT. + // The IDT must be filled in with the IDT contents that are + // used during an ACPI S3 resume. This is typically the contents of the IDT + // used by the boot processor when the platform is booted. + // + EFI_PHYSICAL_ADDRESS IdtrProfile; + // + // Physical address of a buffer that is used as stacks during ACPI S3 resume. + // The total size of this buffer, in bytes, is NumberOfCpus * StackSize. This + // structure must be allocated from memory of type EfiACPIMemoryNVS. + // + EFI_PHYSICAL_ADDRESS StackAddress; + // + // The size, in bytes, of the stack provided to each CPU during ACPI S3 resume. + // + UINT32 StackSize; + // + // The number of CPUs. If a platform does not support hot plug CPUs, then + // this is the number of CPUs detected when the platform is booted, regardless + // of being enabled or disabled. If a platform does support hot plug CPUs, + // then this is the maximum number of CPUs that the platform supports. + // + UINT32 NumberOfCpus; + // + // Physical address of structure of type MTRR_SETTINGS that contains a copy + // of the MTRR settings that are compatible with the MTRR settings used by + // the boot processor when the platform was booted. These MTRR settings are + // used during an ACPI S3 resume. + // + EFI_PHYSICAL_ADDRESS MtrrTable; + // + // Physical address of an array of CPU_REGISTER_TABLE structures, with + // NumberOfCpus entries. If a register table is not required, then the + // TableLength and AllocatedSize fields of CPU_REGISTER_TABLE are set to 0. + // If TableLength is > 0, then elements of RegisterTableEntry are used to + // initialize the CPU that matches InitialApicId, during an ACPI S3 resume, + // before SMBASE relocation is performed. + // + EFI_PHYSICAL_ADDRESS PreSmmInitRegisterTable; + // + // Physical address of an array of CPU_REGISTER_TABLE structures, with + // NumberOfCpus entries. If a register table is not required, then the + // TableLength and AllocatedSize fields of CPU_REGISTER_TABLE are set to 0. + // If TableLength is > 0, then elements of RegisterTableEntry are used to + // initialize the CPU that matches InitialApicId, during an ACPI S3 resume, + // after SMBASE relocation is performed. + // + EFI_PHYSICAL_ADDRESS RegisterTable; + // + // Physical address of a buffer that contains the machine check handler that + // is used during an ACPI S3 Resume. In order for this machine check + // handler to be active on an AP during an ACPI S3 resume, the machine check + // vector in the IDT provided by IdtrProfile must be initialized to transfer + // control to this physical address. + // + EFI_PHYSICAL_ADDRESS ApMachineCheckHandlerBase; + // + // The size, in bytes, of the machine check handler that is used during an + // ACPI S3 Resume. If this field is 0, then a machine check handler is not + // provided. + // + UINT32 ApMachineCheckHandlerSize; + // + // CPU information which is required when set the register table. + // + CPU_STATUS_INFORMATION CpuStatus; + // + // Location info for each AP. + // It points to an array which saves all APs location info. + // The array count is the AP count in this CPU. + // + // If the platform does not support MSR setting at S3 resume, and + // therefore it doesn't need the dependency semaphores, it should set + // this field to 0. + // + EFI_PHYSICAL_ADDRESS ApLocation; +} ACPI_CPU_DATA; + +#endif diff --git a/UefiCpuPkg/Include/CpuHotPlugData.h b/UefiCpuPkg/Include/CpuHotPlugData.h new file mode 100644 index 000000000..6321a149f --- /dev/null +++ b/UefiCpuPkg/Include/CpuHotPlugData.h @@ -0,0 +1,27 @@ +/** @file +Definition for a structure sharing information for CPU hot plug. + +Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_HOT_PLUG_DATA_H_ +#define _CPU_HOT_PLUG_DATA_H_ + +#define CPU_HOT_PLUG_DATA_REVISION_1 0x00000001 + +typedef struct { + UINT32 Revision; // Used for version identification for this structure + UINT32 ArrayLength; // The entries number of the following ApicId array and SmBase array + // + // Data required for SMBASE relocation + // + UINT64 *ApicId; // Pointer to ApicId array + UINTN *SmBase; // Pointer to SmBase array + UINT32 Reserved; + UINT32 SmrrBase; + UINT32 SmrrSize; +} CPU_HOT_PLUG_DATA; + +#endif diff --git a/UefiCpuPkg/Include/Guid/CpuFeaturesInitDone.h b/UefiCpuPkg/Include/Guid/CpuFeaturesInitDone.h new file mode 100644 index 000000000..81c8ff63d --- /dev/null +++ b/UefiCpuPkg/Include/Guid/CpuFeaturesInitDone.h @@ -0,0 +1,20 @@ +/** @file + CPU Features Init Done PPI/Protocol should be installed after CPU features + are initialized. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_FEATURES_INIT_DONE_H_ +#define _CPU_FEATURES_INIT_DONE_H_ + +#define EDKII_CPU_FEATURES_INIT_DONE_GUID \ + { \ + { 0xc77c3a41, 0x61ab, 0x4143, { 0x98, 0x3e, 0x33, 0x39, 0x28, 0x6, 0x28, 0xe5 } \ + } + +extern EFI_GUID gEdkiiCpuFeaturesInitDoneGuid; + +#endif diff --git a/UefiCpuPkg/Include/Guid/CpuFeaturesSetDone.h b/UefiCpuPkg/Include/Guid/CpuFeaturesSetDone.h new file mode 100644 index 000000000..a005a51fd --- /dev/null +++ b/UefiCpuPkg/Include/Guid/CpuFeaturesSetDone.h @@ -0,0 +1,20 @@ +/** @file + CPU Features Set Done PPI/Protocol should be installed after CPU features + configuration are set. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_FEATURES_INIT_DONE_H_ +#define _CPU_FEATURES_INIT_DONE_H_ + +#define EDKII_CPU_FEATURES_SET_DONE_GUID \ + { \ + { 0xa82485ce, 0xad6b, 0x4101, { 0x99, 0xd3, 0xe1, 0x35, 0x8c, 0x9e, 0x7e, 0x37 } \ + } + +extern EFI_GUID gEdkiiCpuFeaturesSetDoneGuid; + +#endif diff --git a/UefiCpuPkg/Include/Guid/MicrocodePatchHob.h b/UefiCpuPkg/Include/Guid/MicrocodePatchHob.h new file mode 100644 index 000000000..2d307fbff --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MicrocodePatchHob.h @@ -0,0 +1,44 @@ +/** @file + The microcode patch HOB is used to store the information of: + A. Base address and size of the loaded microcode patches data; + B. Detected microcode patch for each processor within system. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MICROCODE_PATCH_HOB_H_ +#define _MICROCODE_PATCH_HOB_H_ + +extern EFI_GUID gEdkiiMicrocodePatchHobGuid; + +// +// The EDKII microcode patch HOB will be produced by MpInitLib and it can be +// consumed by modules that want to detect/apply microcode patches. +// +typedef struct { + // + // The base address of the microcode patches data after being loaded into + // memory. + // + UINT64 MicrocodePatchAddress; + // + // The total size of the loaded microcode patches. + // + UINT64 MicrocodePatchRegionSize; + // + // The number of processors within the system. + // + UINT32 ProcessorCount; + // + // An array with 'ProcessorCount' elements that stores the offset (with + // regard to 'MicrocodePatchAddress') of the detected microcode patch + // (including the CPU_MICROCODE_HEADER data structure) for each processor. + // If no microcode patch is detected for certain processor, the relating + // element will be set to MAX_UINT64. + // + UINT64 ProcessorSpecificPatchOffset[0]; +} EDKII_MICROCODE_PATCH_HOB; + +#endif diff --git a/UefiCpuPkg/Include/Guid/MsegSmram.h b/UefiCpuPkg/Include/Guid/MsegSmram.h new file mode 100644 index 000000000..01001c473 --- /dev/null +++ b/UefiCpuPkg/Include/Guid/MsegSmram.h @@ -0,0 +1,24 @@ +/** @file + + Defines the HOB GUID used to describe the MSEG memory region allocated in PEI. + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MSEG_SMRAM_H_ +#define _MSEG_SMRAM_H_ + +#define MSEG_SMRAM_GUID \ + { \ + 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 } \ + } + +extern EFI_GUID gMsegSmramGuid; + +// +// The data portion of this HOB is type EFI_SMRAM_DESCRIPTOR +// + +#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Library/LocalApicLib.h b/UefiCpuPkg/Include/Library/LocalApicLib.h similarity index 70% rename from CloverEFI/UefiCpuPkg/Include/Library/LocalApicLib.h rename to UefiCpuPkg/Include/Library/LocalApicLib.h index 52914fa9b..96b93aa34 100644 --- a/CloverEFI/UefiCpuPkg/Include/Library/LocalApicLib.h +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h @@ -4,14 +4,8 @@ Local APIC library assumes local APIC is enabled. It does not handles cases where local APIC is disabled. - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -21,6 +15,32 @@ #define LOCAL_APIC_MODE_XAPIC 0x1 ///< xAPIC mode. #define LOCAL_APIC_MODE_X2APIC 0x2 ///< x2APIC mode. +/** + Retrieve the base address of local APIC. + + @return The base address of local APIC. + +**/ +UINTN +EFIAPI +GetLocalApicBaseAddress ( + VOID + ); + +/** + Set the base address of local APIC. + + If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). + + @param[in] BaseAddress Local APIC base address to be set. + +**/ +VOID +EFIAPI +SetLocalApicBaseAddress ( + IN UINTN BaseAddress + ); + /** Get the current local APIC mode. @@ -42,6 +62,9 @@ GetApicMode ( If the specified local APIC mode can't be set as current, then ASSERT. @param ApicMode APIC mode to be set. + + @note This API must not be called from an interrupt handler or SMI handler. + It may result in unpredictable behavior. **/ VOID EFIAPI @@ -52,8 +75,8 @@ SetApicMode ( /** Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. - In xAPIC mode, the initial local APIC ID is 8-bit, and may be different from current APIC ID. - In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, + In xAPIC mode, the initial local APIC ID may be different from current APIC ID. + In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, the 32-bit local APIC ID is returned as initial APIC ID. @return 32-bit initial local APIC ID of the executing processor. @@ -89,7 +112,7 @@ GetApicVersion ( /** Send a Fixed IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId The local APIC ID of the target processor. @param Vector The vector number of the interrupt being sent. @@ -104,7 +127,7 @@ SendFixedIpi ( /** Send a Fixed IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. @param Vector The vector number of the interrupt being sent. **/ @@ -117,7 +140,7 @@ SendFixedIpiAllExcludingSelf ( /** Send a SMI IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId Specify the local APIC ID of the target processor. **/ @@ -130,7 +153,7 @@ SendSmiIpi ( /** Send a SMI IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. **/ VOID EFIAPI @@ -141,7 +164,7 @@ SendSmiIpiAllExcludingSelf ( /** Send an INIT IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId Specify the local APIC ID of the target processor. **/ @@ -154,7 +177,7 @@ SendInitIpi ( /** Send an INIT IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. **/ VOID EFIAPI @@ -165,7 +188,7 @@ SendInitIpiAllExcludingSelf ( /** Send an INIT-Start-up-Start-up IPI sequence to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. if StartupRoutine >= 1M, then ASSERT. if StartupRoutine is not multiple of 4K, then ASSERT. @@ -184,7 +207,7 @@ SendInitSipiSipi ( /** Send an INIT-Start-up-Start-up IPI sequence to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. if StartupRoutine >= 1M, then ASSERT. if StartupRoutine is not multiple of 4K, then ASSERT. @@ -198,6 +221,20 @@ SendInitSipiSipiAllExcludingSelf ( IN UINT32 StartupRoutine ); +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ); + /** Programming Virtual Wire Mode. @@ -320,27 +357,27 @@ SendApicEoi ( ); /** - Get the 32-bit address that a device should use to send a Message Signaled + Get the 32-bit address that a device should use to send a Message Signaled Interrupt (MSI) to the Local APIC of the currently executing processor. @return 32-bit address used to send an MSI to the Local APIC. **/ UINT32 -EFIAPI +EFIAPI GetApicMsiAddress ( VOID ); - + /** - Get the 64-bit data value that a device should use to send a Message Signaled + Get the 64-bit data value that a device should use to send a Message Signaled Interrupt (MSI) to the Local APIC of the currently executing processor. If Vector is not in range 0x10..0xFE, then ASSERT(). If DeliveryMode is not supported, then ASSERT(). - - @param Vector The 8-bit interrupt vector associated with the MSI. + + @param Vector The 8-bit interrupt vector associated with the MSI. Must be in the range 0x10..0xFE - @param DeliveryMode A 3-bit value that specifies how the recept of the MSI + @param DeliveryMode A 3-bit value that specifies how the recept of the MSI is handled. The only supported values are: 0: LOCAL_APIC_DELIVERY_MODE_FIXED 1: LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY @@ -348,25 +385,73 @@ GetApicMsiAddress ( 4: LOCAL_APIC_DELIVERY_MODE_NMI 5: LOCAL_APIC_DELIVERY_MODE_INIT 7: LOCAL_APIC_DELIVERY_MODE_EXTINT - - @param LevelTriggered TRUE specifies a level triggered interrupt. + + @param LevelTriggered TRUE specifies a level triggered interrupt. FALSE specifies an edge triggered interrupt. @param AssertionLevel Ignored if LevelTriggered is FALSE. - TRUE specifies a level triggered interrupt that active + TRUE specifies a level triggered interrupt that active when the interrupt line is asserted. - FALSE specifies a level triggered interrupt that active + FALSE specifies a level triggered interrupt that active when the interrupt line is deasserted. @return 64-bit data value used to send an MSI to the Local APIC. **/ UINT64 -EFIAPI +EFIAPI GetApicMsiValue ( IN UINT8 Vector, IN UINTN DeliveryMode, IN BOOLEAN LevelTriggered, IN BOOLEAN AssertionLevel ); - + +/** + Get Package ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of logical processors + per package, number of cores per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocationByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ); + +/** + Get Package ID/Module ID/Tile ID/Die ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per tile, number of tiles per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns the processor tile ID. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ); #endif diff --git a/UefiCpuPkg/Include/Library/MpInitLib.h b/UefiCpuPkg/Include/Library/MpInitLib.h new file mode 100644 index 000000000..31eb227f1 --- /dev/null +++ b/UefiCpuPkg/Include/Library/MpInitLib.h @@ -0,0 +1,381 @@ +/** @file + Multiple-Processor initialization Library. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MP_INIT_LIB_H__ +#define __MP_INIT_LIB_H__ + +#include +#include + +/** + MP Initialize Library initialization. + + This service will allocate AP reset vector and wakeup all APs to do APs + initialization. + + This service must be invoked before all other MP Initialize Library + service are invoked. + + @retval EFI_SUCCESS MP initialization succeeds. + @retval Others MP initialization fails. + +**/ +EFI_STATUS +EFIAPI +MpInitLibInitialize ( + VOID + ); + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ); + +/** + This service executes a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by MpInitLibStartupAllAPs() or + MPInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Initialization + library, and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllAPs ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by MpInitLibStartupAllAPs() or + MpInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupThisAP ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibSwitchBSP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibEnableDisableAP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibWhoAmI ( + OUT UINTN *ProcessorNumber + ); + +/** + This service executes a caller provided function on all enabled CPUs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. TimeoutInMicroseconds is ignored + for BSP. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + + @retval EFI_SUCCESS In blocking mode, all CPUs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled CPUs. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllCPUs ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +#endif diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h b/UefiCpuPkg/Include/Library/MtrrLib.h new file mode 100644 index 000000000..95ffbc8bf --- /dev/null +++ b/UefiCpuPkg/Include/Library/MtrrLib.h @@ -0,0 +1,409 @@ +/** @file + MTRR setting library + + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MTRR_LIB_H_ +#define _MTRR_LIB_H_ + +// +// According to IA32 SDM, MTRRs number and MSR offset are always consistent +// for IA32 processor family +// + +// +// The semantics of below macro is MAX_MTRR_NUMBER_OF_VARIABLE_MTRR, the real number can be read out from MTRR_CAP register. +// +#define MTRR_NUMBER_OF_VARIABLE_MTRR 32 +// +// Firmware need reserve 2 MTRR for OS +// Note: It is replaced by PCD PcdCpuNumberOfReservedVariableMtrrs +// +#define RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER 2 + +#define MTRR_NUMBER_OF_FIXED_MTRR 11 + +// +// Structure to describe a fixed MTRR +// +typedef struct { + UINT32 Msr; + UINT32 BaseAddress; + UINT32 Length; +} FIXED_MTRR; + +// +// Structure to describe a variable MTRR +// +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + UINT64 Type; + UINT32 Msr; + BOOLEAN Valid; + BOOLEAN Used; +} VARIABLE_MTRR; + +// +// Structure to hold base and mask pair for variable MTRR register +// +typedef struct _MTRR_VARIABLE_SETTING_ { + UINT64 Base; + UINT64 Mask; +} MTRR_VARIABLE_SETTING; + +// +// Array for variable MTRRs +// +typedef struct _MTRR_VARIABLE_SETTINGS_ { + MTRR_VARIABLE_SETTING Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; +} MTRR_VARIABLE_SETTINGS; + +// +// Array for fixed MTRRs +// +typedef struct _MTRR_FIXED_SETTINGS_ { + UINT64 Mtrr[MTRR_NUMBER_OF_FIXED_MTRR]; +} MTRR_FIXED_SETTINGS; + +// +// Structure to hold all MTRRs +// +typedef struct _MTRR_SETTINGS_ { + MTRR_FIXED_SETTINGS Fixed; + MTRR_VARIABLE_SETTINGS Variables; + UINT64 MtrrDefType; +} MTRR_SETTINGS; + +// +// Memory cache types +// +typedef enum { + CacheUncacheable = 0, + CacheWriteCombining = 1, + CacheWriteThrough = 4, + CacheWriteProtected = 5, + CacheWriteBack = 6, + CacheInvalid = 7 +} MTRR_MEMORY_CACHE_TYPE; + +#define MTRR_CACHE_UNCACHEABLE 0 +#define MTRR_CACHE_WRITE_COMBINING 1 +#define MTRR_CACHE_WRITE_THROUGH 4 +#define MTRR_CACHE_WRITE_PROTECTED 5 +#define MTRR_CACHE_WRITE_BACK 6 +#define MTRR_CACHE_INVALID_TYPE 7 + +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + MTRR_MEMORY_CACHE_TYPE Type; +} MTRR_MEMORY_RANGE; + +/** + Returns the variable MTRR count for the CPU. + + @return Variable MTRR count + +**/ +UINT32 +EFIAPI +GetVariableMtrrCount ( + VOID + ); + +/** + Returns the firmware usable variable MTRR count for the CPU. + + @return Firmware usable variable MTRR count + +**/ +UINT32 +EFIAPI +GetFirmwareVariableMtrrCount ( + VOID + ); + +/** + This function attempts to set the attributes for a memory range. + + @param[in] BaseAddress The physical address that is the start + address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attribute The bit mask of attributes to set for the + memory region. + + @retval RETURN_SUCCESS The attributes were set for the memory + region. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or + more bytes of the memory resource range + specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support + for the memory resource range specified + by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource + range specified by BaseAddress and Length + cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to + modify the attributes of the memory + resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttribute ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ); + + +/** + This function will get the memory cache type of the specific address. + This function is mainly for debugging purposes. + + @param[in] Address The specific address + + @return The memory cache type of the specific address + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetMemoryAttribute ( + IN PHYSICAL_ADDRESS Address + ); + + +/** + This function will get the raw value in variable MTRRs + + @param[out] VariableSettings A buffer to hold variable MTRRs content. + + @return The buffer point to MTRR_VARIABLE_SETTINGS in which holds the content of the variable MTRR + +**/ +MTRR_VARIABLE_SETTINGS* +EFIAPI +MtrrGetVariableMtrr ( + OUT MTRR_VARIABLE_SETTINGS *VariableSettings + ); + + +/** + This function sets variable MTRRs + + @param[in] VariableSettings A buffer to hold variable MTRRs content. + + @return The pointer of VariableSettings + +**/ +MTRR_VARIABLE_SETTINGS* +EFIAPI +MtrrSetVariableMtrr ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings + ); + + +/** + This function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @return The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrGetFixedMtrr ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ); + + +/** + This function sets fixed MTRRs + + @param[in] FixedSettings A buffer holding fixed MTRRs content. + + @return The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrSetFixedMtrr ( + IN MTRR_FIXED_SETTINGS *FixedSettings + ); + + +/** + This function gets the content in all MTRRs (variable and fixed) + + @param[out] MtrrSetting A buffer to hold all MTRRs content. + + @return The pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrGetAllMtrrs ( + OUT MTRR_SETTINGS *MtrrSetting + ); + + +/** + This function sets all MTRRs (variable and fixed) + + @param[in] MtrrSetting A buffer to hold all MTRRs content. + + @return The pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrSetAllMtrrs ( + IN MTRR_SETTINGS *MtrrSetting + ); + + +/** + Get the attribute of variable MTRRs. + + This function shadows the content of variable MTRRs into + an internal array: VariableMtrr + + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR since the base address in + MTRR must align to 4K, so valid address mask equal to + MtrrValidBitsMask & 0xfffffffffffff000ULL + @param[out] VariableMtrr The array to shadow variable MTRRs content + + @return The return value of this parameter indicates the number of + MTRRs which has been used. +**/ +UINT32 +EFIAPI +MtrrGetMemoryAttributeInVariableMtrr ( + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT VARIABLE_MTRR *VariableMtrr + ); + + +/** + This function prints all MTRRs for debugging. +**/ +VOID +EFIAPI +MtrrDebugPrintAllMtrrs ( + VOID + ); + +/** + Checks if MTRR is supported. + + @retval TRUE MTRR is supported. + @retval FALSE MTRR is not supported. + +**/ +BOOLEAN +EFIAPI +IsMtrrSupported ( + VOID + ); + +/** + Returns the default MTRR cache type for the system. + + @return The default MTRR cache type. + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetDefaultMemoryType ( + VOID + ); + +/** + This function attempts to set the attributes into MTRR setting buffer for a memory range. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] BaseAddress The physical address that is the start address + of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attribute The bit mask of attributes to set for the + memory region. + + @retval RETURN_SUCCESS The attributes were set for the memory region. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributeInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ); + +/** + This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] Scratch A temporary scratch buffer that is used to perform the calculation. + @param[in, out] ScratchSize Pointer to the size in bytes of the scratch buffer. + It may be updated to the actual required size when the calculation + needs more scratch buffer. + @param[in] Ranges Pointer to an array of MTRR_MEMORY_RANGE. + When range overlap happens, the last one takes higher priority. + When the function returns, either all the attributes are set successfully, + or none of them is set. + @param[in] RangeCount Count of MTRR_MEMORY_RANGE. + + @retval RETURN_SUCCESS The attributes were set for all the memory ranges. + @retval RETURN_INVALID_PARAMETER Length in any range is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length in any range. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length in any range. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource ranges. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributesInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN VOID *Scratch, + IN OUT UINTN *ScratchSize, + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount + ); +#endif // _MTRR_LIB_H_ diff --git a/UefiCpuPkg/Include/Library/PlatformSecLib.h b/UefiCpuPkg/Include/Library/PlatformSecLib.h new file mode 100644 index 000000000..c27ecfaf9 --- /dev/null +++ b/UefiCpuPkg/Include/Library/PlatformSecLib.h @@ -0,0 +1,64 @@ +/** @file +This library class defines interface for platform to perform platform +specific initialization in SEC phase. + +Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PLATFORM_SEC_LIB_H__ +#define __PLATFORM_SEC_LIB_H__ + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ); + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param PeiServices Pointer to the PEI Services Table. + @param StructureSize Pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + This interface disables temporary memory in SEC Phase. +**/ +VOID +EFIAPI +SecPlatformDisableTemporaryMemory ( + VOID + ); + +#endif diff --git a/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h new file mode 100644 index 000000000..27bd2f6b4 --- /dev/null +++ b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h @@ -0,0 +1,611 @@ +/** @file + Register CPU Features Library to register and manage CPU features. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __REGISTER_CPU_FEATURES_LIB_H__ +#define __REGISTER_CPU_FEATURES_LIB_H__ + +#include +#include +#include + +/// +/// Defines used to identify a CPU feature. The lower 16-bits are used to +/// identify a unique CPU feature and the value represents a bit number in +/// a bit mask. The upper 16-bits are bit mask values that are used as +/// modifiers of a CPU feature. When used in a list, the define value +/// CPU_FEATURE_END is used to terminate a list of CPU feature values. +/// @{ +#define CPU_FEATURE_AESNI 0 +#define CPU_FEATURE_TURBO_MODE 1 +#define CPU_FEATURE_MWAIT 2 +#define CPU_FEATURE_ACPI 3 +#define CPU_FEATURE_EIST 4 +#define CPU_FEATURE_RESERVED_5 5 +#define CPU_FEATURE_FASTSTRINGS 6 +#define CPU_FEATURE_VMX 7 +#define CPU_FEATURE_SMX 8 +#define CPU_FEATURE_LMCE 9 +#define CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER 10 +#define CPU_FEATURE_LIMIT_CPUID_MAX_VAL 11 +#define CPU_FEATURE_MCE 12 +#define CPU_FEATURE_MCA 13 +#define CPU_FEATURE_MCG_CTL 14 +#define CPU_FEATURE_PENDING_BREAK 15 +#define CPU_FEATURE_C1E 16 +#define CPU_FEATURE_C1_AUTO_DEMOTION 17 +#define CPU_FEATURE_C3_AUTO_DEMOTION 18 +#define CPU_FEATURE_C1_UNDEMOTION 19 +#define CPU_FEATURE_C3_UNDEMOTION 20 +#define CPU_FEATURE_C_STATE 21 +#define CPU_FEATURE_TM 22 +#define CPU_FEATURE_TM2 23 +#define CPU_FEATURE_X2APIC 24 +#define CPU_FEATURE_RESERVED_25 25 +#define CPU_FEATURE_RESERVED_26 26 +#define CPU_FEATURE_RESERVED_27 27 +#define CPU_FEATURE_RESERVED_28 28 +#define CPU_FEATURE_RESERVED_29 29 +#define CPU_FEATURE_RESERVED_30 30 +#define CPU_FEATURE_RESERVED_31 31 + +#define CPU_FEATURE_L2_PREFETCHER (32+0) +#define CPU_FEATURE_L1_DATA_PREFETCHER (32+1) +#define CPU_FEATURE_HARDWARE_PREFETCHER (32+2) +#define CPU_FEATURE_ADJACENT_CACHE_LINE_PREFETCH (32+3) +#define CPU_FEATURE_DCU_PREFETCHER (32+4) +#define CPU_FEATURE_IP_PREFETCHER (32+5) +#define CPU_FEATURE_MLC_STREAMER_PREFETCHER (32+6) +#define CPU_FEATURE_MLC_SPATIAL_PREFETCHER (32+7) +#define CPU_FEATURE_THREE_STRIKE_COUNTER (32+8) +#define CPU_FEATURE_APIC_TPR_UPDATE_MESSAGE (32+9) +#define CPU_FEATURE_ENERGY_PERFORMANCE_BIAS (32+10) +#define CPU_FEATURE_PPIN (32+11) +#define CPU_FEATURE_PROC_TRACE (32+12) + +#define CPU_FEATURE_BEFORE_ALL BIT23 +#define CPU_FEATURE_AFTER_ALL BIT24 +#define CPU_FEATURE_THREAD_BEFORE BIT25 +#define CPU_FEATURE_THREAD_AFTER BIT26 +#define CPU_FEATURE_CORE_BEFORE BIT27 +#define CPU_FEATURE_CORE_AFTER BIT28 +#define CPU_FEATURE_PACKAGE_BEFORE BIT29 +#define CPU_FEATURE_PACKAGE_AFTER BIT30 +#define CPU_FEATURE_END MAX_UINT32 +/// @} + +/// +/// The bit field to indicate whether the processor is the first in its parent scope. +/// +typedef struct { + // + // Set to 1 when current processor is the first thread in the core it resides in. + // + UINT32 Thread : 1; + // + // Set to 1 when current processor is a thread of the first core in the module it resides in. + // + UINT32 Core : 1; + // + // Set to 1 when current processor is a thread of the first module in the tile it resides in. + // + UINT32 Module : 1; + // + // Set to 1 when current processor is a thread of the first tile in the die it resides in. + // + UINT32 Tile : 1; + // + // Set to 1 when current processor is a thread of the first die in the package it resides in. + // + UINT32 Die : 1; + // + // Set to 1 when current processor is a thread of the first package in the system. + // + UINT32 Package : 1; + UINT32 Reserved : 26; +} REGISTER_CPU_FEATURE_FIRST_PROCESSOR; + +/// +/// CPU Information passed into the SupportFunc and InitializeFunc of the +/// RegisterCpuFeature() library function. This structure contains information +/// that is commonly used during CPU feature detection and initialization. +/// +typedef struct { + /// + /// The package that the CPU resides + /// + EFI_PROCESSOR_INFORMATION ProcessorInfo; + + /// + /// The bit flag indicating whether the CPU is the first Thread/Core/Module/Tile/Die/Package in its parent scope. + /// + REGISTER_CPU_FEATURE_FIRST_PROCESSOR First; + /// + /// The Display Family of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 DisplayFamily; + /// + /// The Display Model of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 DisplayModel; + /// + /// The Stepping ID of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 SteppingId; + /// + /// The Processor Type of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 ProcessorType; + /// + /// Bit field structured returned in ECX from CPUID leaf CPUID_VERSION_INFO + /// + CPUID_VERSION_INFO_ECX CpuIdVersionInfoEcx; + /// + /// Bit field structured returned in EDX from CPUID leaf CPUID_VERSION_INFO + /// + CPUID_VERSION_INFO_EDX CpuIdVersionInfoEdx; +} REGISTER_CPU_FEATURE_INFORMATION; + +/** + Determines if a CPU feature is enabled in PcdCpuFeaturesSupport bit mask. + If a CPU feature is disabled in PcdCpuFeaturesSupport then all the code/data + associated with that feature should be optimized away if compiler + optimizations are enabled. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSupport. + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSupport. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSupport. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureSupported ( + IN UINT32 Feature + ); + +/** + Determines if a CPU feature is set in PcdCpuFeaturesSetting bit mask. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSetting. + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSetting. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSetting. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureInSetting ( + IN UINT32 Feature + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +typedef +VOID * +(EFIAPI *CPU_FEATURE_GET_CONFIG_DATA)( + IN UINTN NumberOfProcessors + ); + +/** + Detects if CPU feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE CPU feature is supported. + @retval FALSE CPU feature is not supported. + + @note This service could be called by BSP/APs. +**/ +typedef +BOOLEAN +(EFIAPI *CPU_FEATURE_SUPPORT)( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes CPU feature to specific state. + + This service does not initialize hardware and only produces entries in the + Register Table for specified processor. Hardware initialization on BSP/APs + will be done in CpuFeaturesInitialize(). + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the CPU feature must be enabled. + If FALSE, then the CPU feature must be disabled. + + @retval RETURN_SUCCESS CPU feature is initialized. + + @note This service could be called by BSP only. +**/ +typedef +RETURN_STATUS +(EFIAPI *CPU_FEATURE_INITIALIZE)( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Registers a CPU Feature. + + @param[in] FeatureName A Null-terminated Ascii string indicates CPU feature + name. + @param[in] GetConfigDataFunc CPU feature get configuration data function. This + is an optional parameter that may be NULL. If NULL, + then the most recently registered function for the + CPU feature is used. If no functions are registered + for a CPU feature, then the CPU configuration data + for the registered feature is NULL. + @param[in] SupportFunc CPU feature support function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature is assumed to be + supported by all CPUs. + @param[in] InitializeFunc CPU feature initialize function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature initialization is + skipped. + @param[in] ... Variable argument list of UINT32 CPU feature value. + Values with no modifiers are the features provided + by the registered functions. + Values with CPU_FEATURE_BEFORE modifier are features + that must be initialized after the features provided + by the registered functions are used. + Values with CPU_FEATURE_AFTER modifier are features + that must be initialized before the features provided + by the registered functions are used. + The last argument in this variable argument list must + always be CPU_FEATURE_END. + + @retval RETURN_SUCCESS The CPU feature was successfully registered. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to register + the CPU feature. + @retval RETURN_UNSUPPORTED Registration of the CPU feature is not + supported due to a circular dependency between + BEFORE and AFTER features. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +RegisterCpuFeature ( + IN CHAR8 *FeatureName, OPTIONAL + IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc, OPTIONAL + IN CPU_FEATURE_SUPPORT SupportFunc, OPTIONAL + IN CPU_FEATURE_INITIALIZE InitializeFunc, OPTIONAL + ... + ); + +/** + Performs CPU features detection. + + This service will invoke MP service to check CPU features' + capabilities on BSP/APs. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesDetect ( + VOID + ); + +/** + Performs CPU features Initialization. + + This service will invoke MP service to perform CPU features + initialization on BSP/APs per user configuration. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesInitialize ( + VOID + ); + +/** + Switches to assigned BSP after CPU features initialization. + + @param[in] ProcessorNumber The index of the CPU executing this function. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +SwitchBspAfterFeaturesInitialize ( + IN UINTN ProcessorNumber + ); + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableTestThenWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds an entry in specified Pre-SMM register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +PreSmmCpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +#endif diff --git a/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h b/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h new file mode 100644 index 000000000..dbcd57e0a --- /dev/null +++ b/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h @@ -0,0 +1,414 @@ +/** @file +Library that provides CPU specific functions to support the PiSmmCpuDxeSmm module. + +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMM_FEATURES_LIB_H__ +#define __SMM_FEATURES_LIB_H__ + +#include +#include +#include +#include + +/// +/// Enumeration of SMM registers that are accessed using the library functions +/// SmmCpuFeaturesIsSmmRegisterSupported (), SmmCpuFeaturesGetSmmRegister (), +/// and SmmCpuFeaturesSetSmmRegister (). +/// +typedef enum { + /// + /// Read-write register to provides access to MSR_SMM_FEATURE_CONTROL if the + /// CPU supports this MSR. + /// + SmmRegFeatureControl, + /// + /// Read-only register that returns a non-zero value if the CPU is able to + /// respond to SMIs. + /// + SmmRegSmmEnable, + /// + /// Read-only register that returns a non-zero value if the CPU is able to + /// respond to SMIs, but is busy with other actions that are causing a delay + /// in responding to an SMI. This register abstracts access to MSR_SMM_DELAYED + /// if the CPU supports this MSR. + /// + SmmRegSmmDelayed, + /// + /// Read-only register that returns a non-zero value if the CPU is able to + /// respond to SMIs, but is busy with other actions that are blocking its + /// ability to respond to an SMI. This register abstracts access to + /// MSR_SMM_BLOCKED if the CPU supports this MSR. + /// + SmmRegSmmBlocked +} SMM_REG_NAME; + +/** + Called during the very first SMI into System Management Mode to initialize + CPU features, including SMBASE, for the currently executing CPU. Since this + is the first SMI, the SMRAM Save State Map is at the default address of + SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The currently executing + CPU is specified by CpuIndex and CpuIndex can be used to access information + about the currently executing CPU in the ProcessorInfo array and the + HotPlugCpuData data structure. + + @param[in] CpuIndex The index of the CPU to initialize. The value + must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU that + was elected as monarch during System Management + Mode initialization. + FALSE if the CpuIndex is not the index of the CPU + that was elected as monarch during System + Management Mode initialization. + @param[in] ProcessorInfo Pointer to an array of EFI_PROCESSOR_INFORMATION + structures. ProcessorInfo[CpuIndex] contains the + information for the currently executing CPU. + @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA structure that + contains the ApidId and SmBase arrays. +**/ +VOID +EFIAPI +SmmCpuFeaturesInitializeProcessor ( + IN UINTN CpuIndex, + IN BOOLEAN IsMonarch, + IN EFI_PROCESSOR_INFORMATION *ProcessorInfo, + IN CPU_HOT_PLUG_DATA *CpuHotPlugData + ); + +/** + This function updates the SMRAM save state on the currently executing CPU + to resume execution at a specific address after an RSM instruction. This + function must evaluate the SMRAM save state to determine the execution mode + the RSM instruction resumes and update the resume execution address with + either NewInstructionPointer32 or NewInstructionPoint. The auto HALT restart + flag in the SMRAM save state must always be cleared. This function returns + the value of the instruction pointer from the SMRAM save state that was + replaced. If this function returns 0, then the SMRAM save state was not + modified. + + This function is called during the very first SMI on each CPU after + SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode + to signal that the SMBASE of each CPU has been updated before the default + SMBASE address is used for the first SMI to the next CPU. + + @param[in] CpuIndex The index of the CPU to hook. The value + must be between 0 and the NumberOfCpus + field in the System Management System Table + (SMST). + @param[in] CpuState Pointer to SMRAM Save State Map for the + currently executing CPU. + @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to + 32-bit execution mode from 64-bit SMM. + @param[in] NewInstructionPointer Instruction pointer to use if resuming to + same execution mode as SMM. + + @retval 0 This function did modify the SMRAM save state. + @retval > 0 The original instruction pointer value from the SMRAM save state + before it was replaced. +**/ +UINT64 +EFIAPI +SmmCpuFeaturesHookReturnFromSmm ( + IN UINTN CpuIndex, + IN SMRAM_SAVE_STATE_MAP *CpuState, + IN UINT64 NewInstructionPointer32, + IN UINT64 NewInstructionPointer + ); + +/** + Hook point in normal execution mode that allows the one CPU that was elected + as monarch during System Management Mode initialization to perform additional + initialization actions immediately after all of the CPUs have processed their + first SMI and called SmmCpuFeaturesInitializeProcessor() relocating SMBASE + into a buffer in SMRAM and called SmmCpuFeaturesHookReturnFromSmm(). +**/ +VOID +EFIAPI +SmmCpuFeaturesSmmRelocationComplete ( + VOID + ); + +/** + Return the size, in bytes, of a custom SMI Handler in bytes. If 0 is + returned, then a custom SMI handler is not provided by this library, + and the default SMI handler must be used. + + @retval 0 Use the default SMI handler. + @retval > 0 Use the SMI handler installed by SmmCpuFeaturesInstallSmiHandler() + The caller is required to allocate enough SMRAM for each CPU to + support the size of the custom SMI handler. +**/ +UINTN +EFIAPI +SmmCpuFeaturesGetSmiHandlerSize ( + VOID + ); + +/** + Install a custom SMI handler for the CPU specified by CpuIndex. This function + is only called if SmmCpuFeaturesGetSmiHandlerSize() returns a size is greater + than zero and is called by the CPU that was elected as monarch during System + Management Mode initialization. + + // + // Append Shadow Stack after normal stack + // + // |= SmiStack + // +--------------------------------------------------+---------------------------------------------------------------+ + // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack | + // +--------------------------------------------------+---------------------------------------------------------------+ + // | |PcdCpuSmmStackSize| |PcdCpuSmmShadowStackSize| + // |<-------------------- StackSize ----------------->|<------------------------- ShadowStackSize ------------------->| + // | | + // |<-------------------------------------------- Processor N ------------------------------------------------------->| + // | low address (bottom) high address (top) | + // + + @param[in] CpuIndex The index of the CPU to install the custom SMI handler. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. + @param[in] SmiStack The bottom of stack to use when an SMI is processed by the + the CPU specified by CpuIndex. + @param[in] StackSize The size, in bytes, if the stack used when an SMI is + processed by the CPU specified by CpuIndex. + StackSize should be PcdCpuSmmStackSize, with 2 more pages + if PcdCpuSmmStackGuard is true. + If ShadowStack is enabled, the shadow stack is allocated + after the normal Stack. The size is PcdCpuSmmShadowStackSize. + with 2 more pages if PcdCpuSmmStackGuard is true. + @param[in] GdtBase The base address of the GDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtBase The base address of the IDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] Cr3 The base address of the page tables to use when an SMI + is processed by the CPU specified by CpuIndex. +**/ +VOID +EFIAPI +SmmCpuFeaturesInstallSmiHandler ( + IN UINTN CpuIndex, + IN UINT32 SmBase, + IN VOID *SmiStack, + IN UINTN StackSize, + IN UINTN GdtBase, + IN UINTN GdtSize, + IN UINTN IdtBase, + IN UINTN IdtSize, + IN UINT32 Cr3 + ); + +/** + Determines if MTRR registers must be configured to set SMRAM cache-ability + when executing in System Management Mode. + + @retval TRUE MTRR registers must be configured to set SMRAM cache-ability. + @retval FALSE MTRR registers do not need to be configured to set SMRAM + cache-ability. +**/ +BOOLEAN +EFIAPI +SmmCpuFeaturesNeedConfigureMtrrs ( + VOID + ); + +/** + Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs() + returns TRUE. +**/ +VOID +EFIAPI +SmmCpuFeaturesDisableSmrr ( + VOID + ); + +/** + Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs() + returns TRUE. +**/ +VOID +EFIAPI +SmmCpuFeaturesReenableSmrr ( + VOID + ); + +/** + Processor specific hook point each time a CPU enters System Management Mode. + + @param[in] CpuIndex The index of the CPU that has entered SMM. The value + must be between 0 and the NumberOfCpus field in the + System Management System Table (SMST). +**/ +VOID +EFIAPI +SmmCpuFeaturesRendezvousEntry ( + IN UINTN CpuIndex + ); + +/** + Processor specific hook point each time a CPU exits System Management Mode. + + @param[in] CpuIndex The index of the CPU that is exiting SMM. The value must + be between 0 and the NumberOfCpus field in the System + Management System Table (SMST). +**/ +VOID +EFIAPI +SmmCpuFeaturesRendezvousExit ( + IN UINTN CpuIndex + ); + +/** + Check to see if an SMM register is supported by a specified CPU. + + @param[in] CpuIndex The index of the CPU to check for SMM register support. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to check for support. + + @retval TRUE The SMM register specified by RegName is supported by the CPU + specified by CpuIndex. + @retval FALSE The SMM register specified by RegName is not supported by the + CPU specified by CpuIndex. +**/ +BOOLEAN +EFIAPI +SmmCpuFeaturesIsSmmRegisterSupported ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName + ); + +/** + Returns the current value of the SMM register for the specified CPU. + If the SMM register is not supported, then 0 is returned. + + @param[in] CpuIndex The index of the CPU to read the SMM register. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to read. + + @return The value of the SMM register specified by RegName from the CPU + specified by CpuIndex. +**/ +UINT64 +EFIAPI +SmmCpuFeaturesGetSmmRegister ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName + ); + +/** + Sets the value of an SMM register on a specified CPU. + If the SMM register is not supported, then no action is performed. + + @param[in] CpuIndex The index of the CPU to write the SMM register. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to write. + registers are read-only. + @param[in] Value The value to write to the SMM register. +**/ +VOID +EFIAPI +SmmCpuFeaturesSetSmmRegister ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName, + IN UINT64 Value + ); + +/** + Read an SMM Save State register on the target processor. If this function + returns EFI_UNSUPPORTED, then the caller is responsible for reading the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to read the SMM Save State. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to read. + @param[in] Width The number of bytes to read from the CPU save state. + @param[out] 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_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support reading Register. + +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesReadSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + OUT VOID *Buffer + ); + +/** + Writes an SMM Save State register on the target processor. If this function + returns EFI_UNSUPPORTED, then the caller is responsible for writing the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to write the SMM Save State. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to write. + @param[in] Width The number of bytes to write to the CPU save state. + @param[in] Buffer Upon entry, this holds the new CPU register value. + + @retval EFI_SUCCESS The register was written to Save State. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support writing Register. +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesWriteSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + IN CONST VOID *Buffer + ); + +/** + This function is hook point called after the gEfiSmmReadyToLockProtocolGuid + notification is completely processed. +**/ +VOID +EFIAPI +SmmCpuFeaturesCompleteSmmReadyToLock ( + VOID + ); + +/** + This API provides a method for a CPU to allocate a specific region for storing page tables. + + This API can be called more once to allocate memory for page tables. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + This function can also return NULL if there is no preference on where the page tables are allocated in SMRAM. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer for page tables. + @retval NULL Fail to allocate a specific region for storing page tables, + Or there is no preference on where the page tables are allocated in SMRAM. + +**/ +VOID * +EFIAPI +SmmCpuFeaturesAllocatePageTableMemory ( + IN UINTN Pages + ); + +#endif diff --git a/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h b/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h new file mode 100644 index 000000000..fdb756de9 --- /dev/null +++ b/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h @@ -0,0 +1,103 @@ +/** @file + Public include file for the SMM CPU Platform Hook Library. + + Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMM_CPU_PLATFORM_HOOK_LIB_H__ +#define __SMM_CPU_PLATFORM_HOOK_LIB_H__ + +/// +/// SMM Page Size Type +/// +typedef enum { + SmmPageSize4K, + SmmPageSize2M, + SmmPageSize1G, + MaxSmmPageSizeType +} SMM_PAGE_SIZE_TYPE; + +/** + Checks if platform produces a valid SMI. + + This function checks if platform produces a valid SMI. This function is + called at SMM entry to detect if this is a spurious SMI. This function + must be implemented in an MP safe way because it is called by multiple CPU + threads. + + @retval TRUE There is a valid SMI + @retval FALSE There is no valid SMI + +**/ +BOOLEAN +EFIAPI +PlatformValidSmi ( + VOID + ); + +/** + Clears platform top level SMI status bit. + + This function clears platform top level SMI status bit. + + @retval TRUE The platform top level SMI status is cleared. + @retval FALSE The platform top level SMI status cannot be cleared. + +**/ +BOOLEAN +EFIAPI +ClearTopLevelSmiStatus ( + VOID + ); + +/** + Performs platform specific way of SMM BSP election. + + This function performs platform specific way of SMM BSP election. + + @param IsBsp Output parameter. TRUE: the CPU this function executes + on is elected to be the SMM BSP. FALSE: the CPU this + function executes on is to be SMM AP. + + @retval EFI_SUCCESS The function executes successfully. + @retval EFI_NOT_READY The function does not determine whether this CPU should be + BSP or AP. This may occur if hardware init sequence to + enable the determination is yet to be done, or the function + chooses not to do BSP election and will let SMM CPU driver to + use its default BSP election process. + @retval EFI_DEVICE_ERROR The function cannot determine whether this CPU should be + BSP or AP due to hardware error. + +**/ +EFI_STATUS +EFIAPI +PlatformSmmBspElection ( + OUT BOOLEAN *IsBsp + ); + +/** + Get platform page table attribute . + + This function gets page table attribute of platform. + + @param Address Input parameter. Obtain the page table entries attribute on this address. + @param PageSize Output parameter. The size of the page. + @param NumOfPages Output parameter. Number of page. + @param PageAttribute Output parameter. Paging Attributes (WB, UC, etc). + + @retval EFI_SUCCESS The platform page table attribute from the address is determined. + @retval EFI_UNSUPPORTED The platform does not support getting page table attribute for the address. + +**/ +EFI_STATUS +EFIAPI +GetPlatformPageTableAttribute ( + IN UINT64 Address, + OUT SMM_PAGE_SIZE_TYPE *PageSize, + OUT UINTN *NumOfPages, + OUT UINTN *PageAttribute + ); + +#endif diff --git a/CloverEFI/UefiCpuPkg/Include/Library/UefiCpuLib.h b/UefiCpuPkg/Include/Library/UefiCpuLib.h similarity index 61% rename from CloverEFI/UefiCpuPkg/Include/Library/UefiCpuLib.h rename to UefiCpuPkg/Include/Library/UefiCpuLib.h index 561d57996..82e53bab3 100644 --- a/CloverEFI/UefiCpuPkg/Include/Library/UefiCpuLib.h +++ b/UefiCpuPkg/Include/Library/UefiCpuLib.h @@ -5,13 +5,7 @@ to be UEFI specification compliant. Copyright (c) 2009, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ diff --git a/UefiCpuPkg/Include/Ppi/MpServices2.h b/UefiCpuPkg/Include/Ppi/MpServices2.h new file mode 100644 index 000000000..3e224ed99 --- /dev/null +++ b/UefiCpuPkg/Include/Ppi/MpServices2.h @@ -0,0 +1,279 @@ +/** @file + This file declares EDKII Multi-processor service PPI. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EDKII_PEI_MP_SERVICES2_PPI_H__ +#define __EDKII_PEI_MP_SERVICES2_PPI_H__ + +#include + +#define EDKII_PEI_MP_SERVICES2_PPI_GUID \ + { \ + 0x5cb9cb3d, 0x31a4, 0x480c, { 0x94, 0x98, 0x29, 0xd2, 0x69, 0xba, 0xcf, 0xba} \ + } + +typedef struct _EDKII_PEI_MP_SERVICES2_PPI EDKII_PEI_MP_SERVICES2_PPI; + +/** + Get the number of CPU's. + + @param[in] This Pointer to this instance of the PPI. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] NumberOfEnabledProcessors + Number of processors in the system that are enabled. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + NumberOfEnabledProcessors is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ); + +/** + Get information on a specific CPU. + + @param[in] This Pointer to this instance of the PPI. + @param[in] ProcessorNumber Pointer to the total number of logical processors in + the system, including the BSP and disabled APs. + @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_GET_PROCESSOR_INFO) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + Activate all of the application proessors. + + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute the function + specified by Procedure one by one, in ascending order + of processor handle number. If FALSE, then all the + enabled APs execute the function specified by Procedure + simultaneously. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_STARTUP_ALL_APS) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +/** + Activate a specific application processor. + + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires before all APs + return from Procedure, then Procedure on the failed APs + is terminated. All enabled APs are available for next + function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() + or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the + timeout expires in blocking mode, BSP returns + EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all APs. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before the + timeout expires. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the + specified AP has finished. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_STARTUP_THIS_AP) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +/** + Switch the boot strap processor. + + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled + AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this + service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled + AP. + @retval EFI_NOT_READY The specified AP is busy. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_SWITCH_BSP) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + Enable or disable an application processor. + + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for enabled, + FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies the + new health status of the AP. This flag corresponds to + StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo(). + Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter is + ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior + to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_ENABLEDISABLEAP) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + Identify the currently executing processor. + + @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance. + @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the + total number of logical processors minus 1. The total + number of logical processors can be retrieved by + EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned in + ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_WHOAMI) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + OUT UINTN *ProcessorNumber + ); + + +/** + Activate all of the application proessors. + + @param[in] This A pointer to the EDKII_PEI_MP_SERVICES2_PPI instance. + @param[in] Procedure A pointer to the function to be run on enabled APs of + the system. + @param[in] TimeoutInMicroSeconds + Indicates the time limit in microseconds for APs to + return from Procedure, for blocking mode only. Zero + means infinity. If the timeout expires in blocking + mode, BSP returns EFI_TIMEOUT. + @param[in] ProcedureArgument The parameter passed into Procedure for all CPUs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before the + timeout expired. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before all + enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_MP_SERVICES_STARTUP_ALL_CPUS) ( + IN EDKII_PEI_MP_SERVICES2_PPI *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +struct _EDKII_PEI_MP_SERVICES2_PPI { + EDKII_PEI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors; + EDKII_PEI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo; + EDKII_PEI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs; + EDKII_PEI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP; + EDKII_PEI_MP_SERVICES_SWITCH_BSP SwitchBSP; + EDKII_PEI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP; + EDKII_PEI_MP_SERVICES_WHOAMI WhoAmI; + EDKII_PEI_MP_SERVICES_STARTUP_ALL_CPUS StartupAllCPUs; +}; + +extern EFI_GUID gEdkiiPeiMpServices2PpiGuid; + +#endif diff --git a/UefiCpuPkg/Include/Ppi/ShadowMicrocode.h b/UefiCpuPkg/Include/Ppi/ShadowMicrocode.h new file mode 100644 index 000000000..be4896542 --- /dev/null +++ b/UefiCpuPkg/Include/Ppi/ShadowMicrocode.h @@ -0,0 +1,66 @@ +/** @file + This file declares EDKII Shadow Microcode PPI. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PPI_SHADOW_MICROCODE_H__ +#define __PPI_SHADOW_MICROCODE_H__ + +#define EDKII_PEI_SHADOW_MICROCODE_PPI_GUID \ + { \ + 0x430f6965, 0x9a69, 0x41c5, { 0x93, 0xed, 0x8b, 0xf0, 0x64, 0x35, 0xc1, 0xc6 } \ + } + +typedef struct _EDKII_PEI_SHADOW_MICROCODE_PPI EDKII_PEI_SHADOW_MICROCODE_PPI; + +typedef struct { + UINT32 ProcessorSignature; + UINT8 PlatformId; +} EDKII_PEI_MICROCODE_CPU_ID; + +/** + Shadow microcode update patches to memory. + + The function is used for shadowing microcode update patches to a continuous memory. + It shall allocate memory buffer and only shadow the microcode patches for those + processors specified by MicrocodeCpuId array. The checksum verification may be + skiped in this function so the caller must perform checksum verification before + using the microcode patches in returned memory buffer. + + @param[in] This The PPI instance pointer. + @param[in] CpuIdCount Number of elements in MicrocodeCpuId array. + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MICROCODE_CPU_ID + structures. + @param[out] BufferSize Pointer to receive the total size of Buffer. + @param[out] Buffer Pointer to receive address of allocated memory + with microcode patches data in it. + + @retval EFI_SUCCESS The microcode has been shadowed to memory. + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_PEI_SHADOW_MICROCODE) ( + IN EDKII_PEI_SHADOW_MICROCODE_PPI *This, + IN UINTN CpuIdCount, + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, + OUT UINTN *BufferSize, + OUT VOID **Buffer + ); + +/// +/// This PPI is installed by some platform or chipset-specific PEIM that +/// abstracts handling microcode shadow support. +/// +struct _EDKII_PEI_SHADOW_MICROCODE_PPI { + EDKII_PEI_SHADOW_MICROCODE ShadowMicrocode; +}; + +extern EFI_GUID gEdkiiPeiShadowMicrocodePpiGuid; + +#endif + diff --git a/UefiCpuPkg/Include/Protocol/SmMonitorInit.h b/UefiCpuPkg/Include/Protocol/SmMonitorInit.h new file mode 100644 index 000000000..db2ce11f1 --- /dev/null +++ b/UefiCpuPkg/Include/Protocol/SmMonitorInit.h @@ -0,0 +1,135 @@ +/** @file + STM service protocol definition + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SM_MONITOR_INIT_PROTOCOL_H_ +#define _SM_MONITOR_INIT_PROTOCOL_H_ + +#include +#include + +#define EFI_SM_MONITOR_INIT_PROTOCOL_GUID \ + { 0x228f344d, 0xb3de, 0x43bb, 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82} + +// +// STM service +// + +/** + + Load STM image to MSEG. + + @param StmImage STM image + @param StmImageSize STM image size + + @retval EFI_SUCCESS Load STM to MSEG successfully + @retval EFI_ALREADY_STARTED STM image is already loaded to MSEG + @retval EFI_BUFFER_TOO_SMALL MSEG is smaller than minimal requirement of STM image + @retval EFI_UNSUPPORTED MSEG is not enabled + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SM_MONITOR_LOAD_MONITOR) ( + IN EFI_PHYSICAL_ADDRESS StmImage, + IN UINTN StmImageSize + ); + +/** + + Add resources in list to database. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are added + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + @retval EFI_OUT_OF_RESOURCES If nested procedure returned it and we cannot allocate more areas. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SM_MONITOR_ADD_PI_RESOURCE) ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ); + +/** + + Delete resources in list to database. + + @param ResourceList A pointer to resource list to be deleted + NULL means delete all resources. + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are deleted + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SM_MONITOR_DELETE_PI_RESOURCE) ( + IN STM_RSC *ResourceList OPTIONAL, + IN UINT32 NumEntries OPTIONAL + ); + +/** + + Get BIOS resources. + + @param ResourceList A pointer to resource list to be filled + @param ResourceSize On input it means size of resource list input. + On output it means size of resource list filled, + or the size of resource list to be filled if size of too small. + + @retval EFI_SUCCESS If resources are returned. + @retval EFI_BUFFER_TOO_SMALL If resource list buffer is too small to hold the whole resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SM_MONITOR_GET_PI_RESOURCE) ( + OUT STM_RSC *ResourceList, + IN OUT UINT32 *ResourceSize + ); + +typedef UINT32 EFI_SM_MONITOR_STATE; +#define EFI_SM_MONITOR_STATE_ENABLED 0x1 +#define EFI_SM_MONITOR_STATE_ACTIVATED 0x2 + +/** + + Get STM state + + @return STM state + +**/ +typedef +EFI_SM_MONITOR_STATE +(EFIAPI *EFI_SM_MONITOR_GET_MONITOR_STATE) ( + VOID + ); + +typedef struct _EFI_SM_MONITOR_INIT_PROTOCOL { + // + // Valid at boot-time only + // + EFI_SM_MONITOR_LOAD_MONITOR LoadMonitor; + EFI_SM_MONITOR_ADD_PI_RESOURCE AddPiResource; + EFI_SM_MONITOR_DELETE_PI_RESOURCE DeletePiResource; + EFI_SM_MONITOR_GET_PI_RESOURCE GetPiResource; + // + // Valid at runtime + // + EFI_SM_MONITOR_GET_MONITOR_STATE GetMonitorState; +} EFI_SM_MONITOR_INIT_PROTOCOL; + +extern EFI_GUID gEfiSmMonitorInitProtocolGuid; + +#endif diff --git a/UefiCpuPkg/Include/Protocol/SmmCpuService.h b/UefiCpuPkg/Include/Protocol/SmmCpuService.h new file mode 100644 index 000000000..13ba1feeb --- /dev/null +++ b/UefiCpuPkg/Include/Protocol/SmmCpuService.h @@ -0,0 +1,203 @@ +/** @file +SMM CPU Service protocol definition. + +Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_CPU_SERVICE_PROTOCOL_H_ +#define _SMM_CPU_SERVICE_PROTOCOL_H_ + +// +// Share some definitions with MP Services and CPU Arch Protocol +// +#include +#include + +#define EFI_SMM_CPU_SERVICE_PROTOCOL_GUID \ + { \ + 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 } \ + } + +typedef struct _EFI_SMM_CPU_SERVICE_PROTOCOL EFI_SMM_CPU_SERVICE_PROTOCOL; + +// +// Protocol functions +// + +/** + Gets processor information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL + instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_SMM_GET_PROCESSOR_INFO) ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_SUCCESS The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_SMM_SWITCH_BSP) ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ); + +/** + Notify that a new processor has been added to the system. + + The SMM CPU driver should add the processor to the SMM CPU list. + + If the processor is disabled it won't participate any SMI handler during subsequent SMIs. + + @param This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param ProcessorId The hardware ID of the processor. + @param ProcessorNumber The handle number of processor. + @param ProcessorResource A pointer to EFI_SMM_PROCESSOR_RESOURCE which holds the assigned resources. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ALREADY_STARTED Processor already present. + @retval EFI_NOT_READY Space for a new handle could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SMM_ADD_PROCESSOR) ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINT64 ProcessorId, + OUT UINTN *ProcessorNumber + ); + +/** + Notify that a processor is hot-removed. + + Remove a processor from the CPU list of the SMM CPU driver. After this API is called, the removed processor + must not respond to SMIs in the coherence domain. + + @param This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param ProcessorId The hardware ID of the processor. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND Processor with the hardware ID specified by ProcessorId does not exist. + @retval EFI_NOT_READY Specified AP is busy. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SMM_REMOVE_PROCESSOR) ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. This service may be called from the BSP and APs. + If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_SMM_WHOAMI) ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ); + +/** + Register exception handler. + + @param This A pointer to the SMM_CPU_SERVICE_PROTOCOL instance. + @param ExceptionType Defines which interrupt or exception to hook. Type EFI_EXCEPTION_TYPE and + the valid values for this parameter are defined in EFI_DEBUG_SUPPORT_PROTOCOL + of the UEFI 2.0 specification. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER + that is called when a processor interrupt occurs. + If this parameter is NULL, then the handler will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SMM_REGISTER_EXCEPTION_HANDLER) ( + IN EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +// +// This protocol provides CPU services from SMM. +// +struct _EFI_SMM_CPU_SERVICE_PROTOCOL { + EFI_SMM_GET_PROCESSOR_INFO GetProcessorInfo; + EFI_SMM_SWITCH_BSP SwitchBsp; + EFI_SMM_ADD_PROCESSOR AddProcessor; + EFI_SMM_REMOVE_PROCESSOR RemoveProcessor; + EFI_SMM_WHOAMI WhoAmI; + EFI_SMM_REGISTER_EXCEPTION_HANDLER RegisterExceptionHandler; +}; + +extern EFI_GUID gEfiSmmCpuServiceProtocolGuid; + +#endif diff --git a/UefiCpuPkg/Include/Register/ArchitecturalMsr.h b/UefiCpuPkg/Include/Register/ArchitecturalMsr.h new file mode 100644 index 000000000..15f8094a6 --- /dev/null +++ b/UefiCpuPkg/Include/Register/ArchitecturalMsr.h @@ -0,0 +1,13 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __ARCHITECTURAL_MSR_H__ +#define __ARCHITECTURAL_MSR_H__ + +#include + +#endif diff --git a/UefiCpuPkg/Include/Register/Cpuid.h b/UefiCpuPkg/Include/Register/Cpuid.h new file mode 100644 index 000000000..3c3468041 --- /dev/null +++ b/UefiCpuPkg/Include/Register/Cpuid.h @@ -0,0 +1,13 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __CPUID_H__ +#define __CPUID_H__ + +#include + +#endif diff --git a/UefiCpuPkg/Include/Register/LocalApic.h b/UefiCpuPkg/Include/Register/LocalApic.h new file mode 100644 index 000000000..689c82577 --- /dev/null +++ b/UefiCpuPkg/Include/Register/LocalApic.h @@ -0,0 +1,14 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __LOCAL_APIC_H__ +#define __LOCAL_APIC_H__ + +#include + +#endif + diff --git a/UefiCpuPkg/Include/Register/Microcode.h b/UefiCpuPkg/Include/Register/Microcode.h new file mode 100644 index 000000000..48e2dcd1b --- /dev/null +++ b/UefiCpuPkg/Include/Register/Microcode.h @@ -0,0 +1,13 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __MICROCODE_H__ +#define __MICROCODE_H__ + +#include + +#endif diff --git a/UefiCpuPkg/Include/Register/Msr.h b/UefiCpuPkg/Include/Register/Msr.h new file mode 100644 index 000000000..79830fa15 --- /dev/null +++ b/UefiCpuPkg/Include/Register/Msr.h @@ -0,0 +1,14 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MSR_H__ +#define __MSR_H__ + +#include + +#endif diff --git a/UefiCpuPkg/Include/Register/SmramSaveStateMap.h b/UefiCpuPkg/Include/Register/SmramSaveStateMap.h new file mode 100644 index 000000000..003304330 --- /dev/null +++ b/UefiCpuPkg/Include/Register/SmramSaveStateMap.h @@ -0,0 +1,13 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SMRAM_SAVE_STATE_MAP_H__ +#define __SMRAM_SAVE_STATE_MAP_H__ + +#include + +#endif diff --git a/UefiCpuPkg/Include/Register/StmApi.h b/UefiCpuPkg/Include/Register/StmApi.h new file mode 100644 index 000000000..1fa58aa9f --- /dev/null +++ b/UefiCpuPkg/Include/Register/StmApi.h @@ -0,0 +1,13 @@ +/** @file + Wrapper header file to include in MdePkg. + + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _STM_API_H_ +#define _STM_API_H_ + +#include + +#endif diff --git a/UefiCpuPkg/Include/StuffRsbNasm.inc b/UefiCpuPkg/Include/StuffRsbNasm.inc new file mode 100644 index 000000000..f3ba22546 --- /dev/null +++ b/UefiCpuPkg/Include/StuffRsbNasm.inc @@ -0,0 +1,50 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Abstract: +; +; This file provides macro definitions for stuffing the Return Stack Buffer (RSB) +; for NASM files. +; +;------------------------------------------------------------------------------ + +%define RSB_STUFF_ENTRIES 0x20 + +; +; parameters: +; @param 1: register to use as counter (e.g. IA32:eax, X64:rax) +; @param 2: stack pointer to restore (IA32:esp, X64:rsp) +; @param 3: the size of a stack frame (IA32:4, X64:8) +; +%macro StuffRsb 3 + mov %1, RSB_STUFF_ENTRIES / 2 + %%Unroll1: + call %%Unroll2 + %%SpecTrap1: + pause + lfence + jmp %%SpecTrap1 + %%Unroll2: + call %%StuffLoop + %%SpecTrap2: + pause + lfence + jmp %%SpecTrap2 + %%StuffLoop: + dec %1 + jnz %%Unroll1 + add %2, RSB_STUFF_ENTRIES * %3 ; Restore the stack pointer +%endmacro + +; +; RSB stuffing macros for IA32 and X64 +; +%macro StuffRsb32 0 + StuffRsb eax, esp, 4 +%endmacro + +%macro StuffRsb64 0 + StuffRsb rax, rsp, 8 +%endmacro diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf new file mode 100644 index 000000000..006b7acbf --- /dev/null +++ b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf @@ -0,0 +1,34 @@ +## @file +# This library defines some routines that are generic for IA32 family CPU. +# +# The library routines are UEFI specification compliant. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseUefiCpuLib + MODULE_UNI_FILE = BaseUefiCpuLib.uni + FILE_GUID = 34C24FD7-7A90-45c2-89FD-946473D9CE98 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiCpuLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32] + Ia32/InitializeFpu.nasm + +[Sources.X64] + X64/InitializeFpu.nasm + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni new file mode 100644 index 000000000..83c96cea6 --- /dev/null +++ b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni @@ -0,0 +1,16 @@ +// /** @file +// This library defines some routines that are generic for IA32 family CPU. +// +// The library routines are UEFI specification compliant. +// +// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Defines generic routines for IA32 family CPUs." + +#string STR_MODULE_DESCRIPTION #language en-US "The library routines comply with the UEFI Specification." + diff --git a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm b/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.nasm similarity index 57% rename from CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm rename to UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.nasm index 3c31da98f..5e27cc325 100644 --- a/CloverEFI/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm +++ b/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.nasm @@ -1,34 +1,25 @@ ;------------------------------------------------------------------------------ ;* -;* Copyright (c) 2009, Intel Corporation. All rights reserved.
-;* This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php +;* Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent ;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ;* -;* ;------------------------------------------------------------------------------ + SECTION .rodata - .686 - .model flat,C - .const ; -; Float control word initial value: +; Float control word initial value: ; all exceptions masked, double-precision, round-to-nearest ; -mFpuControlWord DW 027Fh +mFpuControlWord: DW 0x27F ; ; Multimedia-extensions control word: ; all exceptions masked, round-to-nearest, flush to zero for masked underflow ; -mMmxControlWord DD 01F80h +mMmxControlWord: DD 0x1F80 - .xmm - .code + SECTION .text ; ; Initializes floating point units for requirement of UEFI specification. @@ -38,7 +29,8 @@ mMmxControlWord DD 01F80h ; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero ; for masked underflow). ; -InitializeFloatingPointUnits PROC PUBLIC +global ASM_PFX(InitializeFloatingPointUnits) +ASM_PFX(InitializeFloatingPointUnits): push ebx @@ -46,8 +38,8 @@ InitializeFloatingPointUnits PROC PUBLIC ; Initialize floating point units ; finit - fldcw mFpuControlWord - + fldcw [mFpuControlWord] + ; ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test ; whether the processor supports SSE instruction. @@ -56,24 +48,21 @@ InitializeFloatingPointUnits PROC PUBLIC cpuid bt edx, 25 jnc Done - + ; ; Set OSFXSR bit 9 in CR4 ; mov eax, cr4 or eax, BIT9 mov cr4, eax - + ; ; The processor should support SSE instruction and we can use ; ldmxcsr instruction ; - ldmxcsr mMmxControlWord + ldmxcsr [mMmxControlWord] Done: pop ebx ret -InitializeFloatingPointUnits ENDP - -END diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.nasm b/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.nasm new file mode 100644 index 000000000..8485b4713 --- /dev/null +++ b/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.nasm @@ -0,0 +1,51 @@ +;------------------------------------------------------------------------------ +;* +;* Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* +;------------------------------------------------------------------------------ + + SECTION .rodata +; +; Float control word initial value: +; all exceptions masked, double-extended-precision, round-to-nearest +; +mFpuControlWord: DW 0x37F +; +; Multimedia-extensions control word: +; all exceptions masked, round-to-nearest, flush to zero for masked underflow +; +mMmxControlWord: DD 0x1F80 + +DEFAULT REL +SECTION .text + +; +; Initializes floating point units for requirement of UEFI specification. +; +; This function initializes floating-point control word to 0x027F (all exceptions +; masked,double-precision, round-to-nearest) and multimedia-extensions control word +; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero +; for masked underflow). +; +global ASM_PFX(InitializeFloatingPointUnits) +ASM_PFX(InitializeFloatingPointUnits): + + ; + ; Initialize floating point units + ; + finit + fldcw [mFpuControlWord] + + ; + ; Set OSFXSR bit 9 in CR4 + ; + mov rax, cr4 + or rax, BIT9 + mov cr4, rax + + ldmxcsr [mMmxControlWord] + + ret + diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c new file mode 100644 index 000000000..33ea15ca2 --- /dev/null +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -0,0 +1,1275 @@ +/** @file + Local APIC Library. + + This local APIC library instance supports xAPIC mode only. + + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// +// Library internal functions +// + +/** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +/** + Determine if the CPU supports the Local APIC Base Address MSR. + + @retval TRUE The CPU supports the Local APIC Base Address MSR. + @retval FALSE The CPU does not support the Local APIC Base Address MSR. + +**/ +BOOLEAN +LocalApicBaseAddressMsrSupported ( + VOID + ) +{ + UINT32 RegEax; + UINTN FamilyId; + + AsmCpuid (1, &RegEax, NULL, NULL, NULL); + FamilyId = BitFieldRead32 (RegEax, 8, 11); + if (FamilyId == 0x04 || FamilyId == 0x05) { + // + // CPUs with a FamilyId of 0x04 or 0x05 do not support the + // Local APIC Base Address MSR + // + return FALSE; + } + return TRUE; +} + +/** + Retrieve the base address of local APIC. + + @return The base address of local APIC. + +**/ +UINTN +EFIAPI +GetLocalApicBaseAddress ( + VOID + ) +{ + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + if (!LocalApicBaseAddressMsrSupported ()) { + // + // If CPU does not support Local APIC Base Address MSR, then retrieve + // Local APIC Base Address from PCD + // + return PcdGet32 (PcdCpuLocalApicBaseAddress); + } + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + + return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHi, 32)) + + (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12); +} + +/** + Set the base address of local APIC. + + If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). + + @param[in] BaseAddress Local APIC base address to be set. + +**/ +VOID +EFIAPI +SetLocalApicBaseAddress ( + IN UINTN BaseAddress + ) +{ + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); + + if (!LocalApicBaseAddressMsrSupported ()) { + // + // Ignore set request if the CPU does not support APIC Base Address MSR + // + return; + } + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + + ApicBaseMsr.Bits.ApicBase = (UINT32) (BaseAddress >> 12); + ApicBaseMsr.Bits.ApicBaseHi = (UINT32) (RShiftU64((UINT64) BaseAddress, 32)); + + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); +} + +/** + Read from a local APIC register. + + This function reads from a local APIC register either in xAPIC or x2APIC mode. + It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be + accessed using multiple 32-bit loads or stores, so this function only performs + 32-bit read. + + @param MmioOffset The MMIO offset of the local APIC register in xAPIC mode. + It must be 16-byte aligned. + + @return 32-bit Value read from the register. +**/ +UINT32 +EFIAPI +ReadLocalApicReg ( + IN UINTN MmioOffset + ) +{ + ASSERT ((MmioOffset & 0xf) == 0); + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); + + return MmioRead32 (GetLocalApicBaseAddress() + MmioOffset); +} + +/** + Write to a local APIC register. + + This function writes to a local APIC register either in xAPIC or x2APIC mode. + It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be + accessed using multiple 32-bit loads or stores, so this function only performs + 32-bit write. + + if the register index is invalid or unsupported in current APIC mode, then ASSERT. + + @param MmioOffset The MMIO offset of the local APIC register in xAPIC mode. + It must be 16-byte aligned. + @param Value Value to be written to the register. +**/ +VOID +EFIAPI +WriteLocalApicReg ( + IN UINTN MmioOffset, + IN UINT32 Value + ) +{ + ASSERT ((MmioOffset & 0xf) == 0); + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); + + MmioWrite32 (GetLocalApicBaseAddress() + MmioOffset, Value); +} + +/** + Send an IPI by writing to ICR. + + This function returns after the IPI has been accepted by the target processor. + + @param IcrLow 32-bit value to be written to the low half of ICR. + @param ApicId APIC ID of the target processor if this IPI is targeted for a specific processor. +**/ +VOID +SendIpi ( + IN UINT32 IcrLow, + IN UINT32 ApicId + ) +{ + LOCAL_APIC_ICR_LOW IcrLowReg; + UINT32 IcrHigh; + BOOLEAN InterruptState; + + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); + ASSERT (ApicId <= 0xff); + + InterruptState = SaveAndDisableInterrupts (); + + // + // Save existing contents of ICR high 32 bits + // + IcrHigh = ReadLocalApicReg (XAPIC_ICR_HIGH_OFFSET); + + // + // Wait for DeliveryStatus clear in case a previous IPI + // is still being sent + // + do { + IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET); + } while (IcrLowReg.Bits.DeliveryStatus != 0); + + // + // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. + // + WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, ApicId << 24); + WriteLocalApicReg (XAPIC_ICR_LOW_OFFSET, IcrLow); + + // + // Wait for DeliveryStatus clear again + // + do { + IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET); + } while (IcrLowReg.Bits.DeliveryStatus != 0); + + // + // And restore old contents of ICR high + // + WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, IcrHigh); + + SetInterruptState (InterruptState); + +} + +// +// Library API implementation functions +// + +/** + Get the current local APIC mode. + + If local APIC is disabled, then ASSERT. + + @retval LOCAL_APIC_MODE_XAPIC current APIC mode is xAPIC. + @retval LOCAL_APIC_MODE_X2APIC current APIC mode is x2APIC. +**/ +UINTN +EFIAPI +GetApicMode ( + VOID + ) +{ + DEBUG_CODE ( + { + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + // + // Check to see if the CPU supports the APIC Base Address MSR + // + if (LocalApicBaseAddressMsrSupported ()) { + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + // + // Local APIC should have been enabled + // + ASSERT (ApicBaseMsr.Bits.EN != 0); + ASSERT (ApicBaseMsr.Bits.EXTD == 0); + } + } + ); + return LOCAL_APIC_MODE_XAPIC; +} + +/** + Set the current local APIC mode. + + If the specified local APIC mode is not valid, then ASSERT. + If the specified local APIC mode can't be set as current, then ASSERT. + + @param ApicMode APIC mode to be set. + + @note This API must not be called from an interrupt handler or SMI handler. + It may result in unpredictable behavior. +**/ +VOID +EFIAPI +SetApicMode ( + IN UINTN ApicMode + ) +{ + ASSERT (ApicMode == LOCAL_APIC_MODE_XAPIC); + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); +} + +/** + Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. + + In xAPIC mode, the initial local APIC ID may be different from current APIC ID. + In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, + the 32-bit local APIC ID is returned as initial APIC ID. + + @return 32-bit initial local APIC ID of the executing processor. +**/ +UINT32 +EFIAPI +GetInitialApicId ( + VOID + ) +{ + UINT32 ApicId; + UINT32 MaxCpuIdIndex; + UINT32 RegEbx; + + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); + + // + // Get the max index of basic CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + + // + // If CPUID Leaf B is supported, + // And CPUID.0BH:EBX[15:0] reports a non-zero value, + // Then the initial 32-bit APIC ID = CPUID.0BH:EDX + // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24] + // + if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &RegEbx, NULL, &ApicId); + if ((RegEbx & (BIT16 - 1)) != 0) { + return ApicId; + } + } + + AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); + return RegEbx >> 24; +} + +/** + Get the local APIC ID of the executing processor. + + @return 32-bit local APIC ID of the executing processor. +**/ +UINT32 +EFIAPI +GetApicId ( + VOID + ) +{ + UINT32 ApicId; + + ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC); + + if ((ApicId = GetInitialApicId ()) < 0x100) { + // + // If the initial local APIC ID is less 0x100, read APIC ID from + // XAPIC_ID_OFFSET, otherwise return the initial local APIC ID. + // + ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); + ApicId >>= 24; + } + return ApicId; +} + +/** + Get the value of the local APIC version register. + + @return the value of the local APIC version register. +**/ +UINT32 +EFIAPI +GetApicVersion ( + VOID + ) +{ + return ReadLocalApicReg (XAPIC_VERSION_OFFSET); +} + +/** + Send a Fixed IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId The local APIC ID of the target processor. + @param Vector The vector number of the interrupt being sent. +**/ +VOID +EFIAPI +SendFixedIpi ( + IN UINT32 ApicId, + IN UINT8 Vector + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED; + IcrLow.Bits.Level = 1; + IcrLow.Bits.Vector = Vector; + SendIpi (IcrLow.Uint32, ApicId); +} + +/** + Send a Fixed IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. + + @param Vector The vector number of the interrupt being sent. +**/ +VOID +EFIAPI +SendFixedIpiAllExcludingSelf ( + IN UINT8 Vector + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED; + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + IcrLow.Bits.Vector = Vector; + SendIpi (IcrLow.Uint32, 0); +} + +/** + Send a SMI IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId Specify the local APIC ID of the target processor. +**/ +VOID +EFIAPI +SendSmiIpi ( + IN UINT32 ApicId + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +} + +/** + Send a SMI IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. +**/ +VOID +EFIAPI +SendSmiIpiAllExcludingSelf ( + VOID + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI; + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +} + +/** + Send an INIT IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId Specify the local APIC ID of the target processor. +**/ +VOID +EFIAPI +SendInitIpi ( + IN UINT32 ApicId + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +} + +/** + Send an INIT IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. +**/ +VOID +EFIAPI +SendInitIpiAllExcludingSelf ( + VOID + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + IcrLow.Uint32 = 0; + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT; + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +} + +/** + Send an INIT-Start-up-Start-up IPI sequence to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + if StartupRoutine >= 1M, then ASSERT. + if StartupRoutine is not multiple of 4K, then ASSERT. + + @param ApicId Specify the local APIC ID of the target processor. + @param StartupRoutine Points to a start-up routine which is below 1M physical + address and 4K aligned. +**/ +VOID +EFIAPI +SendInitSipiSipi ( + IN UINT32 ApicId, + IN UINT32 StartupRoutine + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + ASSERT (StartupRoutine < 0x100000); + ASSERT ((StartupRoutine & 0xfff) == 0); + + SendInitIpi (ApicId); + MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); + IcrLow.Uint32 = 0; + IcrLow.Bits.Vector = (StartupRoutine >> 12); + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); + if (!StandardSignatureIsAuthenticAMD ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } +} + +/** + Send an INIT-Start-up-Start-up IPI sequence to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. + + if StartupRoutine >= 1M, then ASSERT. + if StartupRoutine is not multiple of 4K, then ASSERT. + + @param StartupRoutine Points to a start-up routine which is below 1M physical + address and 4K aligned. +**/ +VOID +EFIAPI +SendInitSipiSipiAllExcludingSelf ( + IN UINT32 StartupRoutine + ) +{ + LOCAL_APIC_ICR_LOW IcrLow; + + ASSERT (StartupRoutine < 0x100000); + ASSERT ((StartupRoutine & 0xfff) == 0); + + SendInitIpiAllExcludingSelf (); + MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); + IcrLow.Uint32 = 0; + IcrLow.Bits.Vector = (StartupRoutine >> 12); + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); + if (!StandardSignatureIsAuthenticAMD ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +} + +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ) +{ + LOCAL_APIC_SVR Svr; + + // + // Set local APIC software-enabled bit. + // + Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); + if (Enable) { + if (Svr.Bits.SoftwareEnable == 0) { + Svr.Bits.SoftwareEnable = 1; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } else { + if (Svr.Bits.SoftwareEnable == 1) { + Svr.Bits.SoftwareEnable = 0; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } +} + +/** + Programming Virtual Wire Mode. + + This function programs the local APIC for virtual wire mode following + the example described in chapter A.3 of the MP 1.4 spec. + + IOxAPIC is not involved in this type of virtual wire mode. +**/ +VOID +EFIAPI +ProgramVirtualWireMode ( + VOID + ) +{ + LOCAL_APIC_SVR Svr; + LOCAL_APIC_LVT_LINT Lint; + + // + // Enable the APIC via SVR and set the spurious interrupt to use Int 00F. + // + Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); + Svr.Bits.SpuriousVector = 0xf; + Svr.Bits.SoftwareEnable = 1; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + + // + // Program the LINT0 vector entry as ExtInt. Not masked, edge, active high. + // + Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET); + Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT; + Lint.Bits.InputPinPolarity = 0; + Lint.Bits.TriggerMode = 0; + Lint.Bits.Mask = 0; + WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32); + + // + // Program the LINT0 vector entry as NMI. Not masked, edge, active high. + // + Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET); + Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI; + Lint.Bits.InputPinPolarity = 0; + Lint.Bits.TriggerMode = 0; + Lint.Bits.Mask = 0; + WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32); +} + +/** + Disable LINT0 & LINT1 interrupts. + + This function sets the mask flag in the LVT LINT0 & LINT1 registers. +**/ +VOID +EFIAPI +DisableLvtInterrupts ( + VOID + ) +{ + LOCAL_APIC_LVT_LINT LvtLint; + + LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET); + LvtLint.Bits.Mask = 1; + WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, LvtLint.Uint32); + + LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET); + LvtLint.Bits.Mask = 1; + WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, LvtLint.Uint32); +} + +/** + Read the initial count value from the init-count register. + + @return The initial count value read from the init-count register. +**/ +UINT32 +EFIAPI +GetApicTimerInitCount ( + VOID + ) +{ + return ReadLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET); +} + +/** + Read the current count value from the current-count register. + + @return The current count value read from the current-count register. +**/ +UINT32 +EFIAPI +GetApicTimerCurrentCount ( + VOID + ) +{ + return ReadLocalApicReg (XAPIC_TIMER_CURRENT_COUNT_OFFSET); +} + +/** + Initialize the local APIC timer. + + The local APIC timer is initialized and enabled. + + @param DivideValue The divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. + If it is 0, then use the current divide value in the DCR. + @param InitCount The initial count value. + @param PeriodicMode If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. + @param Vector The timer interrupt vector number. +**/ +VOID +EFIAPI +InitializeApicTimer ( + IN UINTN DivideValue, + IN UINT32 InitCount, + IN BOOLEAN PeriodicMode, + IN UINT8 Vector + ) +{ + LOCAL_APIC_DCR Dcr; + LOCAL_APIC_LVT_TIMER LvtTimer; + UINT32 Divisor; + + // + // Ensure local APIC is in software-enabled state. + // + InitializeLocalApicSoftwareEnable (TRUE); + + // + // Program init-count register. + // + WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount); + + if (DivideValue != 0) { + ASSERT (DivideValue <= 128); + ASSERT (DivideValue == GetPowerOfTwo32((UINT32)DivideValue)); + Divisor = (UINT32)((HighBitSet32 ((UINT32)DivideValue) - 1) & 0x7); + + Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); + Dcr.Bits.DivideValue1 = (Divisor & 0x3); + Dcr.Bits.DivideValue2 = (Divisor >> 2); + WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32); + } + + // + // Enable APIC timer interrupt with specified timer mode. + // + LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); + if (PeriodicMode) { + LvtTimer.Bits.TimerMode = 1; + } else { + LvtTimer.Bits.TimerMode = 0; + } + LvtTimer.Bits.Mask = 0; + LvtTimer.Bits.Vector = Vector; + WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); +} + +/** + Get the state of the local APIC timer. + + This function will ASSERT if the local APIC is not software enabled. + + @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. + @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. + @param Vector Return the timer interrupt vector number. +**/ +VOID +EFIAPI +GetApicTimerState ( + OUT UINTN *DivideValue OPTIONAL, + OUT BOOLEAN *PeriodicMode OPTIONAL, + OUT UINT8 *Vector OPTIONAL + ) +{ + UINT32 Divisor; + LOCAL_APIC_DCR Dcr; + LOCAL_APIC_LVT_TIMER LvtTimer; + + // + // Check the APIC Software Enable/Disable bit (bit 8) in Spurious-Interrupt + // Vector Register. + // This bit will be 1, if local APIC is software enabled. + // + ASSERT ((ReadLocalApicReg(XAPIC_SPURIOUS_VECTOR_OFFSET) & BIT8) != 0); + + if (DivideValue != NULL) { + Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); + Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2); + Divisor = (Divisor + 1) & 0x7; + *DivideValue = ((UINTN)1) << Divisor; + } + + if (PeriodicMode != NULL || Vector != NULL) { + LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); + if (PeriodicMode != NULL) { + if (LvtTimer.Bits.TimerMode == 1) { + *PeriodicMode = TRUE; + } else { + *PeriodicMode = FALSE; + } + } + if (Vector != NULL) { + *Vector = (UINT8) LvtTimer.Bits.Vector; + } + } +} + +/** + Enable the local APIC timer interrupt. +**/ +VOID +EFIAPI +EnableApicTimerInterrupt ( + VOID + ) +{ + LOCAL_APIC_LVT_TIMER LvtTimer; + + LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); + LvtTimer.Bits.Mask = 0; + WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); +} + +/** + Disable the local APIC timer interrupt. +**/ +VOID +EFIAPI +DisableApicTimerInterrupt ( + VOID + ) +{ + LOCAL_APIC_LVT_TIMER LvtTimer; + + LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); + LvtTimer.Bits.Mask = 1; + WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32); +} + +/** + Get the local APIC timer interrupt state. + + @retval TRUE The local APIC timer interrupt is enabled. + @retval FALSE The local APIC timer interrupt is disabled. +**/ +BOOLEAN +EFIAPI +GetApicTimerInterruptState ( + VOID + ) +{ + LOCAL_APIC_LVT_TIMER LvtTimer; + + LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET); + return (BOOLEAN)(LvtTimer.Bits.Mask == 0); +} + +/** + Send EOI to the local APIC. +**/ +VOID +EFIAPI +SendApicEoi ( + VOID + ) +{ + WriteLocalApicReg (XAPIC_EOI_OFFSET, 0); +} + +/** + Get the 32-bit address that a device should use to send a Message Signaled + Interrupt (MSI) to the Local APIC of the currently executing processor. + + @return 32-bit address used to send an MSI to the Local APIC. +**/ +UINT32 +EFIAPI +GetApicMsiAddress ( + VOID + ) +{ + LOCAL_APIC_MSI_ADDRESS MsiAddress; + + // + // Return address for an MSI interrupt to be delivered only to the APIC ID + // of the currently executing processor. + // + MsiAddress.Uint32 = 0; + MsiAddress.Bits.BaseAddress = 0xFEE; + MsiAddress.Bits.DestinationId = GetApicId (); + return MsiAddress.Uint32; +} + +/** + Get the 64-bit data value that a device should use to send a Message Signaled + Interrupt (MSI) to the Local APIC of the currently executing processor. + + If Vector is not in range 0x10..0xFE, then ASSERT(). + If DeliveryMode is not supported, then ASSERT(). + + @param Vector The 8-bit interrupt vector associated with the MSI. + Must be in the range 0x10..0xFE + @param DeliveryMode A 3-bit value that specifies how the recept of the MSI + is handled. The only supported values are: + 0: LOCAL_APIC_DELIVERY_MODE_FIXED + 1: LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY + 2: LOCAL_APIC_DELIVERY_MODE_SMI + 4: LOCAL_APIC_DELIVERY_MODE_NMI + 5: LOCAL_APIC_DELIVERY_MODE_INIT + 7: LOCAL_APIC_DELIVERY_MODE_EXTINT + + @param LevelTriggered TRUE specifies a level triggered interrupt. + FALSE specifies an edge triggered interrupt. + @param AssertionLevel Ignored if LevelTriggered is FALSE. + TRUE specifies a level triggered interrupt that active + when the interrupt line is asserted. + FALSE specifies a level triggered interrupt that active + when the interrupt line is deasserted. + + @return 64-bit data value used to send an MSI to the Local APIC. +**/ +UINT64 +EFIAPI +GetApicMsiValue ( + IN UINT8 Vector, + IN UINTN DeliveryMode, + IN BOOLEAN LevelTriggered, + IN BOOLEAN AssertionLevel + ) +{ + LOCAL_APIC_MSI_DATA MsiData; + + ASSERT (Vector >= 0x10 && Vector <= 0xFE); + ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3); + + MsiData.Uint64 = 0; + MsiData.Bits.Vector = Vector; + MsiData.Bits.DeliveryMode = (UINT32)DeliveryMode; + if (LevelTriggered) { + MsiData.Bits.TriggerMode = 1; + if (AssertionLevel) { + MsiData.Bits.Level = 1; + } + } + return MsiData.Uint64; +} + +/** + Get Package ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of logical processors + per package, number of cores per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocationByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + BOOLEAN TopologyLeafSupported; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx; + CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx; + CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 MaxExtendedCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + UINTN ThreadBits; + UINTN CoreBits; + + // + // Check if the processor is capable of supporting more than one logical processor. + // + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.HTT == 0) { + if (Thread != NULL) { + *Thread = 0; + } + if (Core != NULL) { + *Core = 0; + } + if (Package != NULL) { + *Package = 0; + } + return; + } + + // + // Assume three-level mapping of APIC ID: Package|Core|Thread. + // + ThreadBits = 0; + CoreBits = 0; + + // + // Get max index of CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + + // + // If the extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + TopologyLeafSupported = FALSE; + if (MaxStandardCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + 0, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + // + // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for + // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not + // supported on that processor. + // + if (ExtendedTopologyEbx.Uint32 != 0) { + TopologyLeafSupported = TRUE; + + // + // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract + // the SMT sub-field of x2APIC ID. + // + LevelType = ExtendedTopologyEcx.Bits.LevelType; + ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); + ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift; + + // + // Software must not assume any "level type" encoding + // value to be related to any sub-leaf index, except sub-leaf 0. + // + SubIndex = 1; + do { + AsmCpuidEx ( + CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + LevelType = ExtendedTopologyEcx.Bits.LevelType; + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { + CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits; + break; + } + SubIndex++; + } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + } + } + + if (!TopologyLeafSupported) { + // + // Get logical processor count + // + AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL); + MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors; + + // + // Assume single-core processor + // + MaxCoresPerPackage = 1; + + // + // Check for topology extensions on AMD processor + // + if (StandardSignatureIsAuthenticAMD()) { + if (MaxExtendedCpuIdIndex >= CPUID_AMD_PROCESSOR_TOPOLOGY) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL); + if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions != 0) { + // + // Account for max possible thread count to decode ApicId + // + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddressSizeEcx.Uint32, NULL); + MaxLogicProcessorsPerPackage = 1 << AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize; + + // + // Get cores per processor package + // + AsmCpuid (CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopologyEbx.Uint32, NULL, NULL); + MaxCoresPerPackage = MaxLogicProcessorsPerPackage / (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1); + } + } + } + else { + // + // Extract core count based on CACHE information + // + if (MaxStandardCpuIdIndex >= CPUID_CACHE_PARAMS) { + AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL); + if (CacheParamsEax.Uint32 != 0) { + MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; + } + } + } + + ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); + CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } + + if (Thread != NULL) { + *Thread = InitialApicId & ((1 << ThreadBits) - 1); + } + if (Core != NULL) { + *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + } + if (Package != NULL) { + *Package = (InitialApicId >> (ThreadBits + CoreBits)); + } +} + +/** + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per tile, number of tiles per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns the processor tile ID. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 Index; + UINTN LevelType; + UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + + for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { + Bits[LevelType] = 0; + } + + // + // Get max index of CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { + if (Die != NULL) { + *Die = 0; + } + if (Tile != NULL) { + *Tile = 0; + } + if (Module != NULL) { + *Module = 0; + } + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + return; + } + + // + // If the V2 extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + for (Index = 0; ; Index++) { + AsmCpuidEx( + CPUID_V2_EXTENDED_TOPOLOGY, + Index, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + LevelType = ExtendedTopologyEcx.Bits.LevelType; + + // + // first level reported should be SMT. + // + ASSERT ((Index != 0) || (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + break; + } + ASSERT (LevelType < ARRAY_SIZE (Bits)); + Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift; + } + + for (LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; LevelType < ARRAY_SIZE (Bits); LevelType++) { + // + // If there are more levels between level-1 (low-level) and level-2 (high-level), the unknown levels will be ignored + // and treated as an extension of the last known level (i.e., level-1 in this case). + // + if (Bits[LevelType] == 0) { + Bits[LevelType] = Bits[LevelType - 1]; + } + } + + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] = Die; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] = Tile; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] = Module; + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] = Core; + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] = Thread; + + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32; + + for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT + ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 + ; LevelType ++ + ) { + if (Location[LevelType] != NULL) { + // + // Bits[i] holds the number of bits to shift right on x2APIC ID to get a unique + // topology ID of the next level type. + // + *Location[LevelType] = InitialApicId >> Bits[LevelType - 1]; + + // + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level type. + // + *Location[LevelType] &= (1 << (Bits[LevelType] - Bits[LevelType - 1])) - 1; + } + } +} diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf new file mode 100644 index 000000000..bdb2ff372 --- /dev/null +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf @@ -0,0 +1,43 @@ +## @file +# The Local Apic library supports xAPIC mode only. +# +# Note: Local APIC library assumes local APIC is enabled. It does not handle cases +# where local APIC is disabled. +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseXApicLib + MODULE_UNI_FILE = BaseXApicLib.uni + FILE_GUID = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = LocalApicLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + BaseXApicLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + TimerLib + IoLib + PcdLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni new file mode 100644 index 000000000..1e645f598 --- /dev/null +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni @@ -0,0 +1,17 @@ +// /** @file +// The Local Apic library supports xAPIC mode only. +// +// Note: Local APIC library assumes local APIC is enabled. It does not handle cases +// where local APIC is disabled. +// +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Supports xAPIC mode only" + +#string STR_MODULE_DESCRIPTION #language en-US "Note: Local APIC library assumes local APIC is enabled. It does not handle cases where local APIC is disabled." + diff --git a/CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c similarity index 50% rename from CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c rename to UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index 62201cd24..d0f92b33d 100644 --- a/CloverEFI/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -4,18 +4,17 @@ This local APIC library instance supports x2APIC capable processors which have xAPIC and x2APIC modes. - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include +#include +#include +#include +#include #include #include @@ -28,6 +27,116 @@ // Library internal functions // +/** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +/** + Determine if the CPU supports the Local APIC Base Address MSR. + + @retval TRUE The CPU supports the Local APIC Base Address MSR. + @retval FALSE The CPU does not support the Local APIC Base Address MSR. + +**/ +BOOLEAN +LocalApicBaseAddressMsrSupported ( + VOID + ) +{ + UINT32 RegEax; + UINTN FamilyId; + + AsmCpuid (1, &RegEax, NULL, NULL, NULL); + FamilyId = BitFieldRead32 (RegEax, 8, 11); + if (FamilyId == 0x04 || FamilyId == 0x05) { + // + // CPUs with a FamilyId of 0x04 or 0x05 do not support the + // Local APIC Base Address MSR + // + return FALSE; + } + return TRUE; +} + +/** + Retrieve the base address of local APIC. + + @return The base address of local APIC. + +**/ +UINTN +EFIAPI +GetLocalApicBaseAddress ( + VOID + ) +{ + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + if (!LocalApicBaseAddressMsrSupported ()) { + // + // If CPU does not support Local APIC Base Address MSR, then retrieve + // Local APIC Base Address from PCD + // + return PcdGet32 (PcdCpuLocalApicBaseAddress); + } + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + + return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHi, 32)) + + (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12); +} + +/** + Set the base address of local APIC. + + If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). + + @param[in] BaseAddress Local APIC base address to be set. + +**/ +VOID +EFIAPI +SetLocalApicBaseAddress ( + IN UINTN BaseAddress + ) +{ + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); + + if (!LocalApicBaseAddressMsrSupported ()) { + // + // Ignore set request of the CPU does not support APIC Base Address MSR + // + return; + } + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + + ApicBaseMsr.Bits.ApicBase = (UINT32) (BaseAddress >> 12); + ApicBaseMsr.Bits.ApicBaseHi = (UINT32) (RShiftU64((UINT64) BaseAddress, 32)); + + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); +} + /** Read from a local APIC register. @@ -52,7 +161,7 @@ ReadLocalApicReg ( ASSERT ((MmioOffset & 0xf) == 0); if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { - return MmioRead32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset); + return MmioRead32 (GetLocalApicBaseAddress() + MmioOffset); } else { // // DFR is not supported in x2APIC mode. @@ -95,7 +204,7 @@ WriteLocalApicReg ( ASSERT ((MmioOffset & 0xf) == 0); if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { - MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + MmioOffset, Value); + MmioWrite32 (GetLocalApicBaseAddress() + MmioOffset, Value); } else { // // DFR is not supported in x2APIC mode. @@ -121,7 +230,7 @@ WriteLocalApicReg ( /** Send an IPI by writing to ICR. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param IcrLow 32-bit value to be written to the low half of ICR. @param ApicId APIC ID of the target processor if this IPI is targeted for a specific processor. @@ -134,21 +243,59 @@ SendIpi ( { UINT64 MsrValue; LOCAL_APIC_ICR_LOW IcrLowReg; + UINTN LocalApciBaseAddress; + UINT32 IcrHigh; + BOOLEAN InterruptState; + // + // Legacy APIC or X2APIC? + // if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { ASSERT (ApicId <= 0xff); + InterruptState = SaveAndDisableInterrupts (); + + // + // Get base address of this LAPIC + // + LocalApciBaseAddress = GetLocalApicBaseAddress(); + + // + // Save existing contents of ICR high 32 bits + // + IcrHigh = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET); + + // + // Wait for DeliveryStatus clear in case a previous IPI + // is still being sent + // + do { + IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET); + } while (IcrLowReg.Bits.DeliveryStatus != 0); + // // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent. // - MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + XAPIC_ICR_HIGH_OFFSET, ApicId << 24); - MmioWrite32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + XAPIC_ICR_LOW_OFFSET, IcrLow); + MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, ApicId << 24); + MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET, IcrLow); + + // + // Wait for DeliveryStatus clear again + // do { - IcrLowReg.Uint32 = MmioRead32 (PcdGet32 (PcdCpuLocalApicBaseAddress) + XAPIC_ICR_LOW_OFFSET); + IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET); } while (IcrLowReg.Bits.DeliveryStatus != 0); + + // + // And restore old contents of ICR high + // + MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, IcrHigh); + + SetInterruptState (InterruptState); + } else { // - // For x2APIC, A single MSR write to the Interrupt Command Register is required for dispatching an + // For x2APIC, A single MSR write to the Interrupt Command Register is required for dispatching an // interrupt in x2APIC mode. // MsrValue = LShiftU64 ((UINT64) ApicId, 32) | IcrLow; @@ -174,14 +321,21 @@ GetApicMode ( VOID ) { - MSR_IA32_APIC_BASE ApicBaseMsr; + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); + if (!LocalApicBaseAddressMsrSupported ()) { + // + // If CPU does not support APIC Base Address MSR, then return XAPIC mode + // + return LOCAL_APIC_MODE_XAPIC; + } + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); // // Local APIC should have been enabled // - ASSERT (ApicBaseMsr.Bits.En != 0); - if (ApicBaseMsr.Bits.Extd != 0) { + ASSERT (ApicBaseMsr.Bits.EN != 0); + if (ApicBaseMsr.Bits.EXTD != 0) { return LOCAL_APIC_MODE_X2APIC; } else { return LOCAL_APIC_MODE_XAPIC; @@ -195,6 +349,9 @@ GetApicMode ( If the specified local APIC mode can't be set as current, then ASSERT. @param ApicMode APIC mode to be set. + + @note This API must not be called from an interrupt handler or SMI handler. + It may result in unpredictable behavior. **/ VOID EFIAPI @@ -202,8 +359,15 @@ SetApicMode ( IN UINTN ApicMode ) { - UINTN CurrentMode; - MSR_IA32_APIC_BASE ApicBaseMsr; + UINTN CurrentMode; + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + + if (!LocalApicBaseAddressMsrSupported ()) { + // + // Ignore set request if the CPU does not support APIC Base Address MSR + // + return; + } CurrentMode = GetApicMode (); if (CurrentMode == LOCAL_APIC_MODE_XAPIC) { @@ -211,9 +375,9 @@ SetApicMode ( case LOCAL_APIC_MODE_XAPIC: break; case LOCAL_APIC_MODE_X2APIC: - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); - ApicBaseMsr.Bits.Extd = 1; - AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64); + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Bits.EXTD = 1; + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); break; default: ASSERT (FALSE); @@ -225,12 +389,12 @@ SetApicMode ( // Transition from x2APIC mode to xAPIC mode is a two-step process: // x2APIC -> Local APIC disabled -> xAPIC // - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS); - ApicBaseMsr.Bits.Extd = 0; - ApicBaseMsr.Bits.En = 0; - AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64); - ApicBaseMsr.Bits.En = 1; - AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64); + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Bits.EXTD = 0; + ApicBaseMsr.Bits.EN = 0; + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + ApicBaseMsr.Bits.EN = 1; + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); break; case LOCAL_APIC_MODE_X2APIC: break; @@ -243,8 +407,8 @@ SetApicMode ( /** Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. - In xAPIC mode, the initial local APIC ID is 8-bit, and may be different from current APIC ID. - In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, + In xAPIC mode, the initial local APIC ID may be different from current APIC ID. + In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, the 32-bit local APIC ID is returned as initial APIC ID. @return 32-bit initial local APIC ID of the executing processor. @@ -255,9 +419,27 @@ GetInitialApicId ( VOID ) { + UINT32 ApicId; + UINT32 MaxCpuIdIndex; UINT32 RegEbx; if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { + // + // Get the max index of basic CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + // + // If CPUID Leaf B is supported, + // And CPUID.0BH:EBX[15:0] reports a non-zero value, + // Then the initial 32-bit APIC ID = CPUID.0BH:EDX + // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24] + // + if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &RegEbx, NULL, &ApicId); + if ((RegEbx & (BIT16 - 1)) != 0) { + return ApicId; + } + } AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); return RegEbx >> 24; } else { @@ -277,11 +459,13 @@ GetApicId ( ) { UINT32 ApicId; + UINT32 InitApicId; ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET); if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) { - ApicId >>= 24; + ApicId = ((InitApicId = GetInitialApicId ()) < 0x100) ? (ApicId >> 24) : InitApicId; } + return ApicId; } @@ -302,7 +486,7 @@ GetApicVersion ( /** Send a Fixed IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId The local APIC ID of the target processor. @param Vector The vector number of the interrupt being sent. @@ -326,7 +510,7 @@ SendFixedIpi ( /** Send a Fixed IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. @param Vector The vector number of the interrupt being sent. **/ @@ -349,7 +533,7 @@ SendFixedIpiAllExcludingSelf ( /** Send a SMI IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId Specify the local APIC ID of the target processor. **/ @@ -370,7 +554,7 @@ SendSmiIpi ( /** Send a SMI IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. **/ VOID EFIAPI @@ -390,7 +574,7 @@ SendSmiIpiAllExcludingSelf ( /** Send an INIT IPI to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. @param ApicId Specify the local APIC ID of the target processor. **/ @@ -411,7 +595,7 @@ SendInitIpi ( /** Send an INIT IPI to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. **/ VOID EFIAPI @@ -431,7 +615,7 @@ SendInitIpiAllExcludingSelf ( /** Send an INIT-Start-up-Start-up IPI sequence to a specified target processor. - This function returns after the IPI has been accepted by the target processor. + This function returns after the IPI has been accepted by the target processor. if StartupRoutine >= 1M, then ASSERT. if StartupRoutine is not multiple of 4K, then ASSERT. @@ -453,20 +637,22 @@ SendInitSipiSipi ( ASSERT ((StartupRoutine & 0xfff) == 0); SendInitIpi (ApicId); - MicroSecondDelay (10); + MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); IcrLow.Uint32 = 0; IcrLow.Bits.Vector = (StartupRoutine >> 12); IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; IcrLow.Bits.Level = 1; SendIpi (IcrLow.Uint32, ApicId); - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, ApicId); + if (!StandardSignatureIsAuthenticAMD ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } } /** Send an INIT-Start-up-Start-up IPI sequence to all processors excluding self. - This function returns after the IPI has been accepted by the target processors. + This function returns after the IPI has been accepted by the target processors. if StartupRoutine >= 1M, then ASSERT. if StartupRoutine is not multiple of 4K, then ASSERT. @@ -486,15 +672,50 @@ SendInitSipiSipiAllExcludingSelf ( ASSERT ((StartupRoutine & 0xfff) == 0); SendInitIpiAllExcludingSelf (); - MicroSecondDelay (10); + MicroSecondDelay (PcdGet32(PcdCpuInitIpiDelayInMicroSeconds)); IcrLow.Uint32 = 0; IcrLow.Bits.Vector = (StartupRoutine >> 12); IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; IcrLow.Bits.Level = 1; IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; SendIpi (IcrLow.Uint32, 0); - MicroSecondDelay (200); - SendIpi (IcrLow.Uint32, 0); + if (!StandardSignatureIsAuthenticAMD ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +} + +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ) +{ + LOCAL_APIC_SVR Svr; + + // + // Set local APIC software-enabled bit. + // + Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); + if (Enable) { + if (Svr.Bits.SoftwareEnable == 0) { + Svr.Bits.SoftwareEnable = 1; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } else { + if (Svr.Bits.SoftwareEnable == 1) { + Svr.Bits.SoftwareEnable = 0; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } } /** @@ -613,7 +834,6 @@ InitializeApicTimer ( IN UINT8 Vector ) { - LOCAL_APIC_SVR Svr; LOCAL_APIC_DCR Dcr; LOCAL_APIC_LVT_TIMER LvtTimer; UINT32 Divisor; @@ -621,9 +841,7 @@ InitializeApicTimer ( // // Ensure local APIC is in software-enabled state. // - Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); - Svr.Bits.SoftwareEnable = 1; - WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + InitializeLocalApicSoftwareEnable (TRUE); // // Program init-count register. @@ -638,7 +856,7 @@ InitializeApicTimer ( Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); Dcr.Bits.DivideValue1 = (Divisor & 0x3); Dcr.Bits.DivideValue2 = (Divisor >> 2); - WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32); + WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32); } // @@ -658,6 +876,8 @@ InitializeApicTimer ( /** Get the state of the local APIC timer. + This function will ASSERT if the local APIC is not software enabled. + @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. @param Vector Return the timer interrupt vector number. @@ -674,6 +894,13 @@ GetApicTimerState ( LOCAL_APIC_DCR Dcr; LOCAL_APIC_LVT_TIMER LvtTimer; + // + // Check the APIC Software Enable/Disable bit (bit 8) in Spurious-Interrupt + // Vector Register. + // This bit will be 1, if local APIC is software enabled. + // + ASSERT ((ReadLocalApicReg(XAPIC_SPURIOUS_VECTOR_OFFSET) & BIT8) != 0); + if (DivideValue != NULL) { Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET); Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2); @@ -759,13 +986,13 @@ SendApicEoi ( } /** - Get the 32-bit address that a device should use to send a Message Signaled + Get the 32-bit address that a device should use to send a Message Signaled Interrupt (MSI) to the Local APIC of the currently executing processor. @return 32-bit address used to send an MSI to the Local APIC. **/ UINT32 -EFIAPI +EFIAPI GetApicMsiAddress ( VOID ) @@ -773,7 +1000,7 @@ GetApicMsiAddress ( LOCAL_APIC_MSI_ADDRESS MsiAddress; // - // Return address for an MSI interrupt to be delivered only to the APIC ID + // Return address for an MSI interrupt to be delivered only to the APIC ID // of the currently executing processor. // MsiAddress.Uint32 = 0; @@ -781,17 +1008,17 @@ GetApicMsiAddress ( MsiAddress.Bits.DestinationId = GetApicId (); return MsiAddress.Uint32; } - + /** - Get the 64-bit data value that a device should use to send a Message Signaled + Get the 64-bit data value that a device should use to send a Message Signaled Interrupt (MSI) to the Local APIC of the currently executing processor. If Vector is not in range 0x10..0xFE, then ASSERT(). If DeliveryMode is not supported, then ASSERT(). - - @param Vector The 8-bit interrupt vector associated with the MSI. + + @param Vector The 8-bit interrupt vector associated with the MSI. Must be in the range 0x10..0xFE - @param DeliveryMode A 3-bit value that specifies how the recept of the MSI + @param DeliveryMode A 3-bit value that specifies how the recept of the MSI is handled. The only supported values are: 0: LOCAL_APIC_DELIVERY_MODE_FIXED 1: LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY @@ -799,19 +1026,19 @@ GetApicMsiAddress ( 4: LOCAL_APIC_DELIVERY_MODE_NMI 5: LOCAL_APIC_DELIVERY_MODE_INIT 7: LOCAL_APIC_DELIVERY_MODE_EXTINT - - @param LevelTriggered TRUE specifies a level triggered interrupt. + + @param LevelTriggered TRUE specifies a level triggered interrupt. FALSE specifies an edge triggered interrupt. @param AssertionLevel Ignored if LevelTriggered is FALSE. - TRUE specifies a level triggered interrupt that active + TRUE specifies a level triggered interrupt that active when the interrupt line is asserted. - FALSE specifies a level triggered interrupt that active + FALSE specifies a level triggered interrupt that active when the interrupt line is deasserted. @return 64-bit data value used to send an MSI to the Local APIC. **/ UINT64 -EFIAPI +EFIAPI GetApicMsiValue ( IN UINT8 Vector, IN UINTN DeliveryMode, @@ -823,7 +1050,7 @@ GetApicMsiValue ( ASSERT (Vector >= 0x10 && Vector <= 0xFE); ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3); - + MsiData.Uint64 = 0; MsiData.Bits.Vector = Vector; MsiData.Bits.DeliveryMode = (UINT32)DeliveryMode; @@ -835,3 +1062,309 @@ GetApicMsiValue ( } return MsiData.Uint64; } + +/** + Get Package ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of logical processors + per package, number of cores per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocationByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + BOOLEAN TopologyLeafSupported; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx; + CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx; + CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 MaxExtendedCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + UINTN ThreadBits; + UINTN CoreBits; + + // + // Check if the processor is capable of supporting more than one logical processor. + // + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.HTT == 0) { + if (Thread != NULL) { + *Thread = 0; + } + if (Core != NULL) { + *Core = 0; + } + if (Package != NULL) { + *Package = 0; + } + return; + } + + // + // Assume three-level mapping of APIC ID: Package|Core|Thread. + // + ThreadBits = 0; + CoreBits = 0; + + // + // Get max index of CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + + // + // If the extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + TopologyLeafSupported = FALSE; + if (MaxStandardCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + 0, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + // + // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for + // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not + // supported on that processor. + // + if (ExtendedTopologyEbx.Uint32 != 0) { + TopologyLeafSupported = TRUE; + + // + // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract + // the SMT sub-field of x2APIC ID. + // + LevelType = ExtendedTopologyEcx.Bits.LevelType; + ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); + ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift; + + // + // Software must not assume any "level type" encoding + // value to be related to any sub-leaf index, except sub-leaf 0. + // + SubIndex = 1; + do { + AsmCpuidEx ( + CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + LevelType = ExtendedTopologyEcx.Bits.LevelType; + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { + CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits; + break; + } + SubIndex++; + } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + } + } + + if (!TopologyLeafSupported) { + // + // Get logical processor count + // + AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL); + MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors; + + // + // Assume single-core processor + // + MaxCoresPerPackage = 1; + + // + // Check for topology extensions on AMD processor + // + if (StandardSignatureIsAuthenticAMD()) { + if (MaxExtendedCpuIdIndex >= CPUID_AMD_PROCESSOR_TOPOLOGY) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL); + if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions != 0) { + // + // Account for max possible thread count to decode ApicId + // + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddressSizeEcx.Uint32, NULL); + MaxLogicProcessorsPerPackage = 1 << AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize; + + // + // Get cores per processor package + // + AsmCpuid (CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopologyEbx.Uint32, NULL, NULL); + MaxCoresPerPackage = MaxLogicProcessorsPerPackage / (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1); + } + } + } + else { + // + // Extract core count based on CACHE information + // + if (MaxStandardCpuIdIndex >= CPUID_CACHE_PARAMS) { + AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL); + if (CacheParamsEax.Uint32 != 0) { + MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; + } + } + } + + ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); + CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } + + if (Thread != NULL) { + *Thread = InitialApicId & ((1 << ThreadBits) - 1); + } + if (Core != NULL) { + *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + } + if (Package != NULL) { + *Package = (InitialApicId >> (ThreadBits + CoreBits)); + } +} + +/** + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per tile, number of tiles per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns the processor tile ID. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 Index; + UINTN LevelType; + UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + + for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { + Bits[LevelType] = 0; + } + + // + // Get max index of CPUID + // + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { + if (Die != NULL) { + *Die = 0; + } + if (Tile != NULL) { + *Tile = 0; + } + if (Module != NULL) { + *Module = 0; + } + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + return; + } + + // + // If the V2 extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + for (Index = 0; ; Index++) { + AsmCpuidEx( + CPUID_V2_EXTENDED_TOPOLOGY, + Index, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + LevelType = ExtendedTopologyEcx.Bits.LevelType; + + // + // first level reported should be SMT. + // + ASSERT ((Index != 0) || (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + break; + } + ASSERT (LevelType < ARRAY_SIZE (Bits)); + Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift; + } + + for (LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; LevelType < ARRAY_SIZE (Bits); LevelType++) { + // + // If there are more levels between level-1 (low-level) and level-2 (high-level), the unknown levels will be ignored + // and treated as an extension of the last known level (i.e., level-1 in this case). + // + if (Bits[LevelType] == 0) { + Bits[LevelType] = Bits[LevelType - 1]; + } + } + + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] = Die; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] = Tile; + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] = Module; + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] = Core; + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] = Thread; + + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32; + + for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT + ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 + ; LevelType ++ + ) { + if (Location[LevelType] != NULL) { + // + // Bits[i] holds the number of bits to shift right on x2APIC ID to get a unique + // topology ID of the next level type. + // + *Location[LevelType] = InitialApicId >> Bits[LevelType - 1]; + + // + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level type. + // + *Location[LevelType] &= (1 << (Bits[LevelType] - Bits[LevelType - 1])) - 1; + } + } +} diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf new file mode 100644 index 000000000..ac1e0a1c9 --- /dev/null +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf @@ -0,0 +1,43 @@ +## @file +# The Local Apic library supports x2APIC capable processors which have xAPIC and x2APIC modes. +# +# Note: Local APIC library assumes local APIC is enabled. It does not handle cases +# where local APIC is disabled. +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseXApicX2ApicLib + MODULE_UNI_FILE = BaseXApicX2ApicLib.uni + FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = LocalApicLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + BaseXApicX2ApicLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + TimerLib + IoLib + PcdLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni new file mode 100644 index 000000000..e614c938d --- /dev/null +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni @@ -0,0 +1,17 @@ +// /** @file +// The Local Apic library supports x2APIC capable processors which have xAPIC and x2APIC modes. +// +// Note: Local APIC library assumes local APIC is enabled. It does not handle cases +// where local APIC is disabled. +// +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Supports x2APIC capable processors that have xAPIC and x2APIC modes" + +#string STR_MODULE_DESCRIPTION #language en-US "Note: Local APIC library assumes local APIC is enabled. It does not handle cases where local APIC is disabled." + diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/Aesni.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Aesni.c new file mode 100644 index 000000000..4a56eec1b --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Aesni.c @@ -0,0 +1,119 @@ +/** @file + AESNI feature. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +AesniGetConfigData ( + IN UINTN NumberOfProcessors + ) +{ + UINT64 *ConfigData; + + ConfigData = AllocateZeroPool (sizeof (UINT64) * NumberOfProcessors); + ASSERT (ConfigData != NULL); + return ConfigData; +} + +/** + Detects if AESNI feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE AESNI feature is supported. + @retval FALSE AESNI feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +AesniSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *MsrFeatureConfig; + + if (CpuInfo->CpuIdVersionInfoEcx.Bits.AESNI == 1) { + MsrFeatureConfig = (MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *) ConfigData; + ASSERT (MsrFeatureConfig != NULL); + MsrFeatureConfig[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_FEATURE_CONFIG); + return TRUE; + } + return FALSE; +} + +/** + Initializes AESNI feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the AESNI feature must be enabled. + If FALSE, then the AESNI feature must be disabled. + + @retval RETURN_SUCCESS AESNI feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +AesniInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *MsrFeatureConfig; + + // + // SANDY_BRIDGE, SILVERMONT, XEON_5600, XEON_7, and XEON_PHI have the same MSR index, + // Simply use MSR_SANDY_BRIDGE_FEATURE_CONFIG here + // + // The scope of the MSR_SANDY_BRIDGE_FEATURE_CONFIG is Core, only program MSR_FEATURE_CONFIG for thread 0 + // of each core. Otherwise, once a thread in the core disabled AES, the other thread will cause GP when + // programming it. + // + if (CpuInfo->ProcessorInfo.Location.Thread == 0) { + MsrFeatureConfig = (MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *) ConfigData; + ASSERT (MsrFeatureConfig != NULL); + if ((MsrFeatureConfig[ProcessorNumber].Bits.AESConfiguration & BIT0) == 0) { + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_SANDY_BRIDGE_FEATURE_CONFIG, + MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER, + Bits.AESConfiguration, + BIT0 | ((State) ? 0 : BIT1) + ); + } + } + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/C1e.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/C1e.c new file mode 100644 index 000000000..e6e5db759 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/C1e.c @@ -0,0 +1,81 @@ +/** @file + C1E feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if C1E feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE C1E feature is supported. + @retval FALSE C1E feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +C1eSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return IS_NEHALEM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel); +} + +/** + Initializes C1E feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the C1E feature must be enabled. + If FALSE, then the C1E feature must be disabled. + + @retval RETURN_SUCCESS C1E feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +C1eInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of C1EEnable bit in the MSR_NEHALEM_POWER_CTL is Package, only program + // MSR_FEATURE_CONFIG for thread 0 core 0 in each package. + // + if ((CpuInfo->ProcessorInfo.Location.Thread != 0) || (CpuInfo->ProcessorInfo.Location.Core != 0)) { + return RETURN_SUCCESS; + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_NEHALEM_POWER_CTL, + MSR_NEHALEM_POWER_CTL_REGISTER, + Bits.C1EEnable, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ClockModulation.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ClockModulation.c new file mode 100644 index 000000000..b1c6bf614 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ClockModulation.c @@ -0,0 +1,131 @@ +/** @file + Clock Modulation feature. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +typedef struct { + CPUID_THERMAL_POWER_MANAGEMENT_EAX ThermalPowerManagementEax; + MSR_IA32_CLOCK_MODULATION_REGISTER ClockModulation; +} CLOCK_MODULATION_CONFIG_DATA; + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +ClockModulationGetConfigData ( + IN UINTN NumberOfProcessors + ) +{ + UINT32 *ConfigData; + + ConfigData = AllocateZeroPool (sizeof (CLOCK_MODULATION_CONFIG_DATA) * NumberOfProcessors); + ASSERT (ConfigData != NULL); + return ConfigData; +} + +/** + Detects if Clock Modulation feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Clock Modulation feature is supported. + @retval FALSE Clock Modulation feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +ClockModulationSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + CLOCK_MODULATION_CONFIG_DATA *CmConfigData; + + if (CpuInfo->CpuIdVersionInfoEdx.Bits.ACPI == 1) { + CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *) ConfigData; + ASSERT (CmConfigData != NULL); + AsmCpuid ( + CPUID_THERMAL_POWER_MANAGEMENT, + &CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Uint32, + NULL, + NULL, + NULL + ); + CmConfigData[ProcessorNumber].ClockModulation.Uint64 = AsmReadMsr64 (MSR_IA32_CLOCK_MODULATION); + return TRUE; + } + return FALSE; +} + +/** + Initializes Clock Modulation feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Clock Modulation feature must be enabled. + If FALSE, then the Clock Modulation feature must be disabled. + + @retval RETURN_SUCCESS Clock Modulation feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +ClockModulationInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + CLOCK_MODULATION_CONFIG_DATA *CmConfigData; + MSR_IA32_CLOCK_MODULATION_REGISTER *ClockModulation; + + CmConfigData = (CLOCK_MODULATION_CONFIG_DATA *) ConfigData; + ASSERT (CmConfigData != NULL); + ClockModulation = &CmConfigData[ProcessorNumber].ClockModulation; + + if (State) { + ClockModulation->Bits.OnDemandClockModulationEnable = 1; + ClockModulation->Bits.OnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) >> 1; + if (CmConfigData[ProcessorNumber].ThermalPowerManagementEax.Bits.ECMD == 1) { + ClockModulation->Bits.ExtendedOnDemandClockModulationDutyCycle = PcdGet8 (PcdCpuClockModulationDutyCycle) & BIT0; + } + } else { + ClockModulation->Bits.OnDemandClockModulationEnable = 0; + } + + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_CLOCK_MODULATION, + ClockModulation->Uint64 + ); + + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h new file mode 100644 index 000000000..b2390e6c3 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h @@ -0,0 +1,1039 @@ +/** @file + CPU Common features library header file. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_COMMON_FEATURES_H_ +#define _CPU_COMMON_FEATURES_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +AesniGetConfigData ( + IN UINTN NumberOfProcessors + ); + +/** + Detects if AESNI feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE AESNI feature is supported. + @retval FALSE AESNI feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +AesniSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes AESNI feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the AESNI feature must be enabled. + If FALSE, then the AESNI feature must be disabled. + + @retval RETURN_SUCCESS AESNI feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +AesniInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +ClockModulationGetConfigData ( + IN UINTN NumberOfProcessors + ); + +/** + Detects if Clock Modulation feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Clock Modulation feature is supported. + @retval FALSE Clock Modulation feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +ClockModulationSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Clock Modulation feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Clock Modulation feature must be enabled. + If FALSE, then the Clock Modulation feature must be disabled. + + @retval RETURN_SUCCESS Clock Modulation feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +ClockModulationInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Enhanced Intel SpeedStep feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Enhanced Intel SpeedStep feature is supported. + @retval FALSE Enhanced Intel SpeedStep feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +EistSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Enhanced Intel SpeedStep feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Enhanced Intel SpeedStep feature + must be enabled. + If FALSE, then the Enhanced Intel SpeedStep feature + must be disabled. + + @retval RETURN_SUCCESS Enhanced Intel SpeedStep feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +EistInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Execute Disable feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Execute Disable feature is supported. + @retval FALSE Execute Disable feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +ExecuteDisableSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Execute Disable feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Execute Disable feature must be enabled. + If FALSE, then the Execute Disable feature must be disabled. + + @retval RETURN_SUCCESS Execute Disable feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +ExecuteDisableInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Initializes Fast-Strings feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Fast-Strings feature must be enabled. + If FALSE, then the Fast-Strings feature must be disabled. + + @retval RETURN_SUCCESS Fast-Strings feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +FastStringsInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if MONITOR/MWAIT feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE MONITOR/MWAIT feature is supported. + @retval FALSE MONITOR/MWAIT feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +MonitorMwaitSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes MONITOR/MWAIT feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the MONITOR/MWAIT feature must be enabled. + If FALSE, then the MONITOR/MWAIT feature must be disabled. + + @retval RETURN_SUCCESS MONITOR/MWAIT feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +MonitorMwaitInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if VMX feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE VMX feature is supported. + @retval FALSE VMX feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +VmxSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes VMX feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the VMX feature must be enabled. + If FALSE, then the VMX feature must be disabled. + + @retval RETURN_SUCCESS VMX feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +VmxInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Lock Feature Control Register feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Lock Feature Control Register feature is supported. + @retval FALSE Lock Feature Control Register feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LockFeatureControlRegisterSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Lock Feature Control Register feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Lock Feature Control Register feature must be enabled. + If FALSE, then the Lock Feature Control Register feature must be disabled. + + @retval RETURN_SUCCESS Lock Feature Control Register feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +LockFeatureControlRegisterInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if SMX feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE SMX feature is supported. + @retval FALSE SMX feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +SmxSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes SMX feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then SMX feature must be enabled. + If FALSE, then SMX feature must be disabled. + + @retval RETURN_SUCCESS SMX feature is initialized. + @retval RETURN_UNSUPPORTED VMX not initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +SmxInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if LimitCpuidMaxval feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE LimitCpuidMaxval feature is supported. + @retval FALSE LimitCpuidMaxval feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LimitCpuidMaxvalSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes LimitCpuidMaxval feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the LimitCpuidMaxval feature must be enabled. + If FALSE, then the LimitCpuidMaxval feature must be disabled. + + @retval RETURN_SUCCESS LimitCpuidMaxval feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +LimitCpuidMaxvalInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Machine Check Exception feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Machine Check Exception feature is supported. + @retval FALSE Machine Check Exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +MceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Machine Check Exception feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Machine Check Exception feature must be enabled. + If FALSE, then the Machine Check Exception feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Exception feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +MceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Machine Check Architecture feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Machine Check Architecture feature is supported. + @retval FALSE Machine Check Architecture feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McaSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Machine Check Architecture feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Machine Check Architecture feature must be enabled. + If FALSE, then the Machine Check Architecture feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Architecture feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McaInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if IA32_MCG_CTL feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE IA32_MCG_CTL feature is supported. + @retval FALSE IA32_MCG_CTL feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McgCtlSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes IA32_MCG_CTL feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the IA32_MCG_CTL feature must be enabled. + If FALSE, then the IA32_MCG_CTL feature must be disabled. + + @retval RETURN_SUCCESS IA32_MCG_CTL feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McgCtlInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Pending Break feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Pending Break feature is supported. + @retval FALSE Pending Break feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +PendingBreakSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Pending Break feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Pending Break feature must be enabled. + If FALSE, then the Pending Break feature must be disabled. + + @retval RETURN_SUCCESS Pending Break feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +PendingBreakInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if C1E feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE C1E feature is supported. + @retval FALSE C1E feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +C1eSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes C1E feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the C1E feature must be enabled. + If FALSE, then the C1E feature must be disabled. + + @retval RETURN_SUCCESS C1E feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +C1eInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +X2ApicGetConfigData ( + IN UINTN NumberOfProcessors + ); + +/** + Detects if X2Apci feature supported on current processor. + + Detect if X2Apci has been already enabled. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE X2Apci feature is supported. + @retval FALSE X2Apci feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +X2ApicSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes X2Apci feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the X2Apci feature must be enabled. + If FALSE, then the X2Apci feature must be disabled. + + @retval RETURN_SUCCESS X2Apci feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +X2ApicInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +PpinGetConfigData ( + IN UINTN NumberOfProcessors + ); + +/** + Detects if Protected Processor Inventory Number feature supported on current + processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Protected Processor Inventory Number feature is supported. + @retval FALSE Protected Processor Inventory Number feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +PpinSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Protected Processor Inventory Number feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Protected Processor Inventory + Number feature must be enabled. + If FALSE, then the Protected Processor Inventory + Number feature must be disabled. + + @retval RETURN_SUCCESS Protected Processor Inventory Number feature is + initialized. + @retval RETURN_DEVICE_ERROR Device can't change state because it has been + locked. + +**/ +RETURN_STATUS +EFIAPI +PpinInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Detects if Local machine check exception feature supported on current + processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Local machine check exception feature is supported. + @retval FALSE Local machine check exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LmceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Local machine check exception feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Local machine check exception + feature must be enabled. + If FALSE, then the Local machine check exception + feature must be disabled. + + @retval RETURN_SUCCESS Local machine check exception feature is initialized. + +**/ +RETURN_STATUS +EFIAPI +LmceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +ProcTraceGetConfigData ( + IN UINTN NumberOfProcessors + ); + +/** + Detects if Intel Processor Trace feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Processor Trace feature is supported. + @retval FALSE Processor Trace feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +ProcTraceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes Intel Processor Trace feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Processor Trace feature must be + enabled. + If FALSE, then the Processor Trace feature must be + disabled. + + @retval RETURN_SUCCESS Intel Processor Trace feature is initialized. + +**/ +RETURN_STATUS +EFIAPI +ProcTraceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +#endif diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c new file mode 100644 index 000000000..725ef7bd4 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c @@ -0,0 +1,231 @@ +/** @file + This library registers CPU features defined in Intel(R) 64 and IA-32 + Architectures Software Developer's Manual. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Register CPU features. + + @retval RETURN_SUCCESS Register successfully +**/ +RETURN_STATUS +EFIAPI +CpuCommonFeaturesLibConstructor ( + VOID + ) +{ + RETURN_STATUS Status; + + if (IsCpuFeatureSupported (CPU_FEATURE_AESNI)) { + Status = RegisterCpuFeature ( + "AESNI", + AesniGetConfigData, + AesniSupport, + AesniInitialize, + CPU_FEATURE_AESNI, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_MWAIT)) { + Status = RegisterCpuFeature ( + "MWAIT", + NULL, + MonitorMwaitSupport, + MonitorMwaitInitialize, + CPU_FEATURE_MWAIT, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_ACPI)) { + Status = RegisterCpuFeature ( + "ACPI", + ClockModulationGetConfigData, + ClockModulationSupport, + ClockModulationInitialize, + CPU_FEATURE_ACPI, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_EIST)) { + Status = RegisterCpuFeature ( + "EIST", + NULL, + EistSupport, + EistInitialize, + CPU_FEATURE_EIST, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_FASTSTRINGS)) { + Status = RegisterCpuFeature ( + "FastStrings", + NULL, + NULL, + FastStringsInitialize, + CPU_FEATURE_FASTSTRINGS, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER)) { + Status = RegisterCpuFeature ( + "Lock Feature Control Register", + NULL, + LockFeatureControlRegisterSupport, + LockFeatureControlRegisterInitialize, + CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_SMX)) { + Status = RegisterCpuFeature ( + "SMX", + NULL, + SmxSupport, + SmxInitialize, + CPU_FEATURE_SMX, + CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER | CPU_FEATURE_THREAD_BEFORE, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_VMX)) { + Status = RegisterCpuFeature ( + "VMX", + NULL, + VmxSupport, + VmxInitialize, + CPU_FEATURE_VMX, + CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER | CPU_FEATURE_THREAD_BEFORE, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_LIMIT_CPUID_MAX_VAL)) { + Status = RegisterCpuFeature ( + "Limit CpuId Maximum Value", + NULL, + LimitCpuidMaxvalSupport, + LimitCpuidMaxvalInitialize, + CPU_FEATURE_LIMIT_CPUID_MAX_VAL, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_MCE)) { + Status = RegisterCpuFeature ( + "Machine Check Enable", + NULL, + MceSupport, + MceInitialize, + CPU_FEATURE_MCE, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_MCA)) { + Status = RegisterCpuFeature ( + "Machine Check Architect", + NULL, + McaSupport, + McaInitialize, + CPU_FEATURE_MCA, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_MCG_CTL)) { + Status = RegisterCpuFeature ( + "MCG_CTL", + NULL, + McgCtlSupport, + McgCtlInitialize, + CPU_FEATURE_MCG_CTL, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_PENDING_BREAK)) { + Status = RegisterCpuFeature ( + "Pending Break", + NULL, + PendingBreakSupport, + PendingBreakInitialize, + CPU_FEATURE_PENDING_BREAK, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_C1E)) { + Status = RegisterCpuFeature ( + "C1E", + NULL, + C1eSupport, + C1eInitialize, + CPU_FEATURE_C1E, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_X2APIC)) { + Status = RegisterCpuFeature ( + "X2Apic", + X2ApicGetConfigData, + X2ApicSupport, + X2ApicInitialize, + CPU_FEATURE_X2APIC, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_PPIN)) { + Status = RegisterCpuFeature ( + "PPIN", + PpinGetConfigData, + PpinSupport, + PpinInitialize, + CPU_FEATURE_PPIN, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_LMCE)) { + Status = RegisterCpuFeature ( + "LMCE", + NULL, + LmceSupport, + LmceInitialize, + CPU_FEATURE_LMCE, + CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER | CPU_FEATURE_THREAD_BEFORE, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + if (IsCpuFeatureSupported (CPU_FEATURE_PROC_TRACE)) { + Status = RegisterCpuFeature ( + "Proc Trace", + ProcTraceGetConfigData, + ProcTraceSupport, + ProcTraceInitialize, + CPU_FEATURE_PROC_TRACE, + CPU_FEATURE_END + ); + ASSERT_EFI_ERROR (Status); + } + + return RETURN_SUCCESS; +} + + + diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf new file mode 100644 index 000000000..7fbcd8da0 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf @@ -0,0 +1,64 @@ +## @file +# NULL instance to register CPU features. +# +# This library registers CPU features defined in Intel(R) 64 and IA-32 +# Architectures Software Developer's Manual. +# +# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuCommonFeaturesLib + MODULE_UNI_FILE = CpuCommonFeaturesLib.uni + FILE_GUID = 6D69F79F-9535-4893-9DD7-93929898252C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL + + CONSTRUCTOR = CpuCommonFeaturesLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CpuCommonFeaturesLib.c + CpuCommonFeatures.h + Aesni.c + C1e.c + ClockModulation.c + Eist.c + FastStrings.c + FeatureControl.c + LimitCpuIdMaxval.c + MachineCheck.c + MonitorMwait.c + PendingBreak.c + X2Apic.c + Ppin.c + ProcTrace.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + RegisterCpuFeaturesLib + BaseMemoryLib + MemoryAllocationLib + LocalApicLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuClockModulationDutyCycle ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.uni b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.uni new file mode 100644 index 000000000..7f799e895 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.uni @@ -0,0 +1,20 @@ +// /** @file +// Dxe Crc32 Guided Section Extract library. +// +// This library doesn't produce any library class. The constructor function uses +// ExtractGuidedSectionLib service to register CRC32 guided section handler +// that parses CRC32 encapsulation section and extracts raw data. +// +// It uses UEFI boot service CalculateCrc32 to authenticate 32 bit CRC value. +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Dxe Crc32 Guided Section Extract library." + +#string STR_MODULE_DESCRIPTION #language en-US "This library doesn't produce any library class. The constructor function uses ExtractGuidedSectionLib service to register CRC32 guided section handler that parses CRC32 encapsulation section and extracts raw data. It uses UEFI boot service CalculateCrc32 to authenticate 32 bit CRC value." + diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/Eist.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Eist.c new file mode 100644 index 000000000..e60220d3c --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Eist.c @@ -0,0 +1,87 @@ +/** @file + Enhanced Intel SpeedStep feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if Enhanced Intel SpeedStep feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Enhanced Intel SpeedStep feature is supported. + @retval FALSE Enhanced Intel SpeedStep feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +EistSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEcx.Bits.EIST == 1); +} + +/** + Initializes Enhanced Intel SpeedStep feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Enhanced Intel SpeedStep feature + must be enabled. + If FALSE, then the Enhanced Intel SpeedStep feature + must be disabled. + + @retval RETURN_SUCCESS Enhanced Intel SpeedStep feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +EistInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of the MSR_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE2_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_REGISTER, + Bits.EIST, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/FastStrings.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/FastStrings.c new file mode 100644 index 000000000..2b678f3bf --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/FastStrings.c @@ -0,0 +1,58 @@ +/** @file + Fast-Strings feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Initializes Fast-Strings feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Fast-Strings feature must be enabled. + If FALSE, then the Fast-Strings feature must be disabled. + + @retval RETURN_SUCCESS Fast-Strings feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +FastStringsInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of FastStrings bit in the MSR_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_REGISTER, + Bits.FastStrings, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c new file mode 100644 index 000000000..b4474d2fa --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c @@ -0,0 +1,280 @@ +/** @file + Features in MSR_IA32_FEATURE_CONTROL register. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if VMX feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE VMX feature is supported. + @retval FALSE VMX feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +VmxSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEcx.Bits.VMX == 1); +} + +/** + Initializes VMX feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the VMX feature must be enabled. + If FALSE, then the VMX feature must be disabled. + + @retval RETURN_SUCCESS VMX feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +VmxInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of EnableVmxOutsideSmx bit in the MSR_IA32_FEATURE_CONTROL is core for + // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each + // core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.EnableVmxOutsideSmx, + (State) ? 1 : 0 + ); + + return RETURN_SUCCESS; +} + +/** + Detects if Lock Feature Control Register feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Lock Feature Control Register feature is supported. + @retval FALSE Lock Feature Control Register feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LockFeatureControlRegisterSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return TRUE; +} + +/** + Initializes Lock Feature Control Register feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Lock Feature Control Register feature must be enabled. + If FALSE, then the Lock Feature Control Register feature must be disabled. + + @retval RETURN_SUCCESS Lock Feature Control Register feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +LockFeatureControlRegisterInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for + // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each + // core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.Lock, + 1 + ); + + return RETURN_SUCCESS; +} + +/** + Detects if SMX feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE SMX feature is supported. + @retval FALSE SMX feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +SmxSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEcx.Bits.SMX == 1); +} + +/** + Initializes SMX feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then SMX feature must be enabled. + If FALSE, then SMX feature must be disabled. + + @retval RETURN_SUCCESS SMX feature is initialized. + @retval RETURN_UNSUPPORTED VMX not initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +SmxInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + RETURN_STATUS Status; + + // + // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for + // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each + // core. + // + if (IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + Status = RETURN_SUCCESS; + + if (State && (!IsCpuFeatureInSetting (CPU_FEATURE_VMX))) { + DEBUG ((DEBUG_WARN, "Warning :: Can't enable SMX feature when VMX feature not enabled, disable it.\n")); + State = FALSE; + Status = RETURN_UNSUPPORTED; + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + ControlRegister, + 4, + IA32_CR4, + Bits.SMXE, + (State) ? 1 : 0 + ) + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.SenterLocalFunctionEnables, + (State) ? 0x7F : 0 + ); + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.SenterGlobalEnable, + (State) ? 1 : 0 + ); + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.EnableVmxInsideSmx, + (State) ? 1 : 0 + ); + + return Status; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/LimitCpuIdMaxval.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/LimitCpuIdMaxval.c new file mode 100644 index 000000000..906ed6540 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/LimitCpuIdMaxval.c @@ -0,0 +1,90 @@ +/** @file + LimitCpuidMaxval Feature. + + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if LimitCpuidMaxval feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE LimitCpuidMaxval feature is supported. + @retval FALSE LimitCpuidMaxval feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LimitCpuidMaxvalSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + UINT32 Eax; + + AsmCpuid (CPUID_SIGNATURE, &Eax, NULL, NULL, NULL); + return (Eax > 2); +} + +/** + Initializes LimitCpuidMaxval feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the LimitCpuidMaxval feature must be enabled. + If FALSE, then the LimitCpuidMaxval feature must be disabled. + + @retval RETURN_SUCCESS LimitCpuidMaxval feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +LimitCpuidMaxvalInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of LimitCpuidMaxval bit in the MSR_IA32_MISC_ENABLE is core for below + // processor type, only program MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE2_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_REGISTER, + Bits.LimitCpuidMaxval, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c new file mode 100644 index 000000000..844052b9a --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c @@ -0,0 +1,344 @@ +/** @file + Machine Check features. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if Machine Check Exception feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Machine Check Exception feature is supported. + @retval FALSE Machine Check Exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +MceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCE == 1); +} + +/** + Initializes Machine Check Exception feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Machine Check Exception feature must be enabled. + If FALSE, then the Machine Check Exception feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Exception feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +MceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // Set MCE bit in CR4 + // + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + ControlRegister, + 4, + IA32_CR4, + Bits.MCE, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} + +/** + Detects if Machine Check Architecture feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Machine Check Architecture feature is supported. + @retval FALSE Machine Check Architecture feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McaSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + if (!MceSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCA == 1); +} + +/** + Initializes Machine Check Architecture feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Machine Check Architecture feature must be enabled. + If FALSE, then the Machine Check Architecture feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Architecture feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McaInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + UINT32 BankIndex; + + // + // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is core for below processor type, only program + // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 in each core. + // + if (IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SANDY_BRIDGE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SKYLAKE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_XEON_PHI_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + // + // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is package for below processor type, only program + // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 core 0 in each package. + // + if (IS_NEHALEM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if ((CpuInfo->ProcessorInfo.Location.Thread != 0) || (CpuInfo->ProcessorInfo.Location.Core != 0)) { + return RETURN_SUCCESS; + } + } + + if (State) { + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + for (BankIndex = 0; BankIndex < (UINT32) McgCap.Bits.Count; BankIndex++) { + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MC0_CTL + BankIndex * 4, + MAX_UINT64 + ); + } + + if (PcdGetBool (PcdIsPowerOnReset)) { + for (BankIndex = 0; BankIndex < (UINTN) McgCap.Bits.Count; BankIndex++) { + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MC0_STATUS + BankIndex * 4, + 0 + ); + } + } + } + + return RETURN_SUCCESS; +} + +/** + Detects if IA32_MCG_CTL feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE IA32_MCG_CTL feature is supported. + @retval FALSE IA32_MCG_CTL feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McgCtlSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + + if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + return (McgCap.Bits.MCG_CTL_P == 1); +} + +/** + Initializes IA32_MCG_CTL feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the IA32_MCG_CTL feature must be enabled. + If FALSE, then the IA32_MCG_CTL feature must be disabled. + + @retval RETURN_SUCCESS IA32_MCG_CTL feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McgCtlInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MCG_CTL, + (State)? MAX_UINT64 : 0 + ); + return RETURN_SUCCESS; +} + +/** + Detects if Local machine check exception feature supported on current + processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Local machine check exception feature is supported. + @retval FALSE Local machine check exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LmceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + + if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + if (ProcessorNumber == 0) { + DEBUG ((EFI_D_INFO, "LMCE eanble = %x\n", (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0))); + } + return (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0); +} + +/** + Initializes Local machine check exception feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Local machine check exception + feature must be enabled. + If FALSE, then the Local machine check exception + feature must be disabled. + + @retval RETURN_SUCCESS Local machine check exception feature is initialized. + +**/ +RETURN_STATUS +EFIAPI +LmceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of LcmeOn bit in the MSR_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.LmceOn, + (State) ? 1 : 0 + ); + + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/MonitorMwait.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/MonitorMwait.c new file mode 100644 index 000000000..08dbb670a --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/MonitorMwait.c @@ -0,0 +1,88 @@ +/** @file + MonitorMwait feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if MONITOR/MWAIT feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE MONITOR/MWAIT feature is supported. + @retval FALSE MONITOR/MWAIT feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +MonitorMwaitSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEcx.Bits.MONITOR == 1); +} + +/** + Initializes MONITOR/MWAIT feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the MONITOR/MWAIT feature must be enabled. + If FALSE, then the MONITOR/MWAIT feature must be disabled. + + @retval RETURN_SUCCESS MONITOR/MWAIT feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +MonitorMwaitInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of the MSR_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_CORE2_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_REGISTER, + Bits.MONITOR, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/PendingBreak.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/PendingBreak.c new file mode 100644 index 000000000..9c20a60ef --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/PendingBreak.c @@ -0,0 +1,95 @@ +/** @file + Pending Break feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if Pending Break feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Pending Break feature is supported. + @retval FALSE Pending Break feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +PendingBreakSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + if (IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE2_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_M_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + return (CpuInfo->CpuIdVersionInfoEdx.Bits.PBE == 1); + } + return FALSE; +} + +/** + Initializes Pending Break feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Pending Break feature must be enabled. + If FALSE, then the Pending Break feature must be disabled. + + @retval RETURN_SUCCESS Pending Break feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +PendingBreakInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of the MSR_ATOM_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_ATOM_IA32_MISC_ENABLE for thread 0 in each core. + // + // Support function has check the processer type for this feature, no need to check again + // here. + // + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + + // + // ATOM, CORE2, CORE, PENTIUM_4 and IS_PENTIUM_M_PROCESSOR have the same MSR index, + // Simply use MSR_ATOM_IA32_MISC_ENABLE here + // + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_ATOM_IA32_MISC_ENABLE, + MSR_ATOM_IA32_MISC_ENABLE_REGISTER, + Bits.FERR, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/Ppin.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Ppin.c new file mode 100644 index 000000000..8450c7ea3 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/Ppin.c @@ -0,0 +1,164 @@ +/** @file + Protected Processor Inventory Number(PPIN) feature. + + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +PpinGetConfigData ( + IN UINTN NumberOfProcessors + ) +{ + VOID *ConfigData; + + ConfigData = AllocateZeroPool (sizeof (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER) * NumberOfProcessors); + ASSERT (ConfigData != NULL); + return ConfigData; +} + +/** + Detects if Protected Processor Inventory Number feature supported on current + processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Protected Processor Inventory Number feature is supported. + @retval FALSE Protected Processor Inventory Number feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +PpinSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER PlatformInfo; + MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *MsrPpinCtrl; + + if ((CpuInfo->DisplayFamily == 0x06) && + ((CpuInfo->DisplayModel == 0x3E) || // Xeon E5 V2 + (CpuInfo->DisplayModel == 0x56) || // Xeon Processor D Product + (CpuInfo->DisplayModel == 0x4F) || // Xeon E5 v4, E7 v4 + (CpuInfo->DisplayModel == 0x55) || // Xeon Processor Scalable + (CpuInfo->DisplayModel == 0x57) || // Xeon Phi processor 3200, 5200, 7200 series. + (CpuInfo->DisplayModel == 0x85) // Future Xeon phi processor + )) { + // + // Check whether platform support this feature. + // + PlatformInfo.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO_1); + if (PlatformInfo.Bits.PPIN_CAP != 0) { + MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *) ConfigData; + ASSERT (MsrPpinCtrl != NULL); + MsrPpinCtrl[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN_CTL); + return TRUE; + } + } + + return FALSE; +} + +/** + Initializes Protected Processor Inventory Number feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Protected Processor Inventory + Number feature must be enabled. + If FALSE, then the Protected Processor Inventory + Number feature must be disabled. + + @retval RETURN_SUCCESS Protected Processor Inventory Number feature is + initialized. + @retval RETURN_DEVICE_ERROR Device can't change state because it has been + locked. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +PpinInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *MsrPpinCtrl; + + MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *) ConfigData; + ASSERT (MsrPpinCtrl != NULL); + + // + // Check whether processor already lock this register. + // If already locked, just based on the request state and + // the current state to return the status. + // + if (MsrPpinCtrl[ProcessorNumber].Bits.LockOut != 0) { + return MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN == State ? RETURN_SUCCESS : RETURN_DEVICE_ERROR; + } + + // + // Support function already check the processor which support PPIN feature, so this function not need + // to check the processor again. + // + // The scope of the MSR_IVY_BRIDGE_PPIN_CTL is package level, only program MSR_IVY_BRIDGE_PPIN_CTL for + // thread 0 core 0 in each package. + // + if ((CpuInfo->ProcessorInfo.Location.Thread != 0) || (CpuInfo->ProcessorInfo.Location.Core != 0)) { + return RETURN_SUCCESS; + } + + if (State) { + // + // Enable and Unlock. + // According to SDM, once Enable_PPIN is set, attempt to write 1 to LockOut will cause #GP. + // + MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 1; + MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 0; + } else { + // + // Disable and Lock. + // According to SDM, writing 1 to LockOut is permitted only if Enable_PPIN is clear. + // + MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 0; + MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 1; + } + + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IVY_BRIDGE_PPIN_CTL, + MsrPpinCtrl[ProcessorNumber].Uint64 + ); + + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c new file mode 100644 index 000000000..611459105 --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c @@ -0,0 +1,473 @@ +/** @file + Intel Processor Trace feature. + + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/// +/// This macro define the max entries in the Topa table. +/// Each entry in the table contains some attribute bits, a pointer to an output region, and the size of the region. +/// The last entry in the table may hold a pointer to the next table. This pointer can either point to the top of the +/// current table (for circular array) or to the base of another table. +/// At least 2 entries are needed because the list of entries must +/// be terminated by an entry with the END bit set to 1, so 2 +/// entries are required to use a single valid entry. +/// +#define MAX_TOPA_ENTRY_COUNT 2 + + +/// +/// Processor trace output scheme selection. +/// +typedef enum { + RtitOutputSchemeSingleRange = 0, + RtitOutputSchemeToPA +} RTIT_OUTPUT_SCHEME; + +typedef struct { + BOOLEAN TopaSupported; + BOOLEAN SingleRangeSupported; + MSR_IA32_RTIT_CTL_REGISTER RtitCtrl; + MSR_IA32_RTIT_OUTPUT_BASE_REGISTER RtitOutputBase; + MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER RtitOutputMaskPtrs; +} PROC_TRACE_PROCESSOR_DATA; + +typedef struct { + UINT32 NumberOfProcessors; + + UINT8 ProcTraceOutputScheme; + UINT32 ProcTraceMemSize; + + UINTN *ThreadMemRegionTable; + UINTN AllocatedThreads; + + UINTN *TopaMemArray; + + PROC_TRACE_PROCESSOR_DATA *ProcessorData; +} PROC_TRACE_DATA; + +typedef struct { + RTIT_TOPA_TABLE_ENTRY TopaEntry[MAX_TOPA_ENTRY_COUNT]; +} PROC_TRACE_TOPA_TABLE; + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +ProcTraceGetConfigData ( + IN UINTN NumberOfProcessors + ) +{ + PROC_TRACE_DATA *ConfigData; + + ConfigData = AllocateZeroPool (sizeof (PROC_TRACE_DATA) + sizeof (PROC_TRACE_PROCESSOR_DATA) * NumberOfProcessors); + ASSERT (ConfigData != NULL); + ConfigData->ProcessorData = (PROC_TRACE_PROCESSOR_DATA *) ((UINT8*) ConfigData + sizeof (PROC_TRACE_DATA)); + + ConfigData->NumberOfProcessors = (UINT32) NumberOfProcessors; + ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize); + ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme); + + return ConfigData; +} + +/** + Detects if Intel Processor Trace feature supported on current + processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE Processor Trace feature is supported. + @retval FALSE Processor Trace feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +ProcTraceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + PROC_TRACE_DATA *ProcTraceData; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; + CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; + + // + // Check if ProcTraceMemorySize option is enabled (0xFF means disable by user) + // + ProcTraceData = (PROC_TRACE_DATA *) ConfigData; + ASSERT (ProcTraceData != NULL); + if ((ProcTraceData->ProcTraceMemSize > RtitTopaMemorySize128M) || + (ProcTraceData->ProcTraceOutputScheme > RtitOutputSchemeToPA)) { + return FALSE; + } + + // + // Check if Processor Trace is supported + // + AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, &Ebx.Uint32, NULL, NULL); + if (Ebx.Bits.IntelProcessorTrace == 0) { + return FALSE; + } + + AsmCpuidEx (CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, NULL, NULL, &Ecx.Uint32, NULL); + ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported = (BOOLEAN) (Ecx.Bits.RTIT == 1); + ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported = (BOOLEAN) (Ecx.Bits.SingleRangeOutput == 1); + if ((ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeToPA)) || + (ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeSingleRange))) { + ProcTraceData->ProcessorData[ProcessorNumber].RtitCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CTL); + ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_BASE); + ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_MASK_PTRS); + return TRUE; + } + + return FALSE; +} + +/** + Initializes Intel Processor Trace feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the Processor Trace feature must be + enabled. + If FALSE, then the Processor Trace feature must be + disabled. + + @retval RETURN_SUCCESS Intel Processor Trace feature is initialized. + +**/ +RETURN_STATUS +EFIAPI +ProcTraceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + UINT32 MemRegionSize; + UINTN Pages; + UINTN Alignment; + UINTN MemRegionBaseAddr; + UINTN *ThreadMemRegionTable; + UINTN Index; + UINTN TopaTableBaseAddr; + UINTN AlignedAddress; + UINTN *TopaMemArray; + PROC_TRACE_TOPA_TABLE *TopaTable; + PROC_TRACE_DATA *ProcTraceData; + BOOLEAN FirstIn; + MSR_IA32_RTIT_CTL_REGISTER CtrlReg; + MSR_IA32_RTIT_STATUS_REGISTER StatusReg; + MSR_IA32_RTIT_OUTPUT_BASE_REGISTER OutputBaseReg; + MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER OutputMaskPtrsReg; + RTIT_TOPA_TABLE_ENTRY *TopaEntryPtr; + + // + // The scope of the MSR_IA32_RTIT_* is core for below processor type, only program + // MSR_IA32_RTIT_* for thread 0 in each core. + // + if (IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + ProcTraceData = (PROC_TRACE_DATA *) ConfigData; + ASSERT (ProcTraceData != NULL); + + // + // Clear MSR_IA32_RTIT_CTL[0] and IA32_RTIT_STS only if MSR_IA32_RTIT_CTL[0]==1b + // + CtrlReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitCtrl.Uint64; + if (CtrlReg.Bits.TraceEn != 0) { + /// + /// Clear bit 0 in MSR IA32_RTIT_CTL (570) + /// + CtrlReg.Bits.TraceEn = 0; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_CTL, + CtrlReg.Uint64 + ); + + /// + /// Clear MSR IA32_RTIT_STS (571h) to all zeros + /// + StatusReg.Uint64 = 0x0; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_STATUS, + StatusReg.Uint64 + ); + } + + if (!State) { + return RETURN_SUCCESS; + } + + MemRegionBaseAddr = 0; + FirstIn = FALSE; + + if (ProcTraceData->ThreadMemRegionTable == NULL) { + FirstIn = TRUE; + DEBUG ((DEBUG_INFO, "Initialize Processor Trace\n")); + } + + /// + /// Refer to PROC_TRACE_MEM_SIZE Table for Size Encoding + /// + MemRegionSize = (UINT32) (1 << (ProcTraceData->ProcTraceMemSize + 12)); + if (FirstIn) { + DEBUG ((DEBUG_INFO, "ProcTrace: MemSize requested: 0x%X \n", MemRegionSize)); + } + + if (FirstIn) { + // + // Let BSP allocate and create the necessary memory region (Aligned to the size of + // the memory region from setup option(ProcTraceMemSize) which is an integral multiple of 4kB) + // for all the enabled threads to store Processor Trace debug data. Then Configure the trace + // address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be + // aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared. + // + ThreadMemRegionTable = (UINTN *) AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *)); + if (ThreadMemRegionTable == NULL) { + DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n")); + return RETURN_OUT_OF_RESOURCES; + } + ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable; + + for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) { + Pages = EFI_SIZE_TO_PAGES (MemRegionSize); + Alignment = MemRegionSize; + AlignedAddress = (UINTN) AllocateAlignedReservedPages (Pages, Alignment); + if (AlignedAddress == 0) { + DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads)); + if (Index == 0) { + // + // Could not allocate for BSP even + // + FreePool ((VOID *) ThreadMemRegionTable); + ThreadMemRegionTable = NULL; + return RETURN_OUT_OF_RESOURCES; + } + break; + } + + ThreadMemRegionTable[Index] = AlignedAddress; + DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64) ThreadMemRegionTable[Index])); + } + + DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads)); + } + + if (ProcessorNumber < ProcTraceData->AllocatedThreads) { + MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber]; + } else { + return RETURN_SUCCESS; + } + + /// + /// Check Processor Trace output scheme: Single Range output or ToPA table + /// + + // + // Single Range output scheme + // + if (ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported && + (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeSingleRange)) { + if (FirstIn) { + DEBUG ((DEBUG_INFO, "ProcTrace: Enabling Single Range Output scheme \n")); + } + + // + // Clear MSR IA32_RTIT_CTL (0x570) ToPA (Bit 8) + // + CtrlReg.Bits.ToPA = 0; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_CTL, + CtrlReg.Uint64 + ); + + // + // Program MSR IA32_RTIT_OUTPUT_BASE (0x560) bits[63:7] with the allocated Memory Region + // + OutputBaseReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64; + OutputBaseReg.Bits.Base = (MemRegionBaseAddr >> 7) & 0x01FFFFFF; + OutputBaseReg.Bits.BaseHi = RShiftU64 ((UINT64) MemRegionBaseAddr, 32) & 0xFFFFFFFF; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_OUTPUT_BASE, + OutputBaseReg.Uint64 + ); + + // + // Program the Mask bits for the Memory Region to MSR IA32_RTIT_OUTPUT_MASK_PTRS (561h) + // + OutputMaskPtrsReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64; + OutputMaskPtrsReg.Bits.MaskOrTableOffset = ((MemRegionSize - 1) >> 7) & 0x01FFFFFF; + OutputMaskPtrsReg.Bits.OutputOffset = RShiftU64 (MemRegionSize - 1, 32) & 0xFFFFFFFF; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_OUTPUT_MASK_PTRS, + OutputMaskPtrsReg.Uint64 + ); + } + + // + // ToPA(Table of physical address) scheme + // + if (ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported && + (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeToPA)) { + // + // Create ToPA structure aligned at 4KB for each logical thread + // with at least 2 entries by 8 bytes size each. The first entry + // should have the trace output base address in bits 47:12, 6:9 + // for Size, bits 4,2 and 0 must be cleared. The second entry + // should have the base address of the table location in bits + // 47:12, bits 4 and 2 must be cleared and bit 0 must be set. + // + if (FirstIn) { + DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n")); + // + // Let BSP allocate ToPA table mem for all threads + // + TopaMemArray = (UINTN *) AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *)); + if (TopaMemArray == NULL) { + DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n")); + return RETURN_OUT_OF_RESOURCES; + } + ProcTraceData->TopaMemArray = TopaMemArray; + + for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) { + Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE)); + Alignment = 0x1000; + AlignedAddress = (UINTN) AllocateAlignedReservedPages (Pages, Alignment); + if (AlignedAddress == 0) { + if (Index < ProcTraceData->AllocatedThreads) { + ProcTraceData->AllocatedThreads = Index; + } + DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads)); + if (Index == 0) { + // + // Could not allocate for BSP even + // + FreePool ((VOID *) TopaMemArray); + TopaMemArray = NULL; + return RETURN_OUT_OF_RESOURCES; + } + break; + } + + TopaMemArray[Index] = AlignedAddress; + DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64) TopaMemArray[Index])); + } + + DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads)); + } + + if (ProcessorNumber < ProcTraceData->AllocatedThreads) { + TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber]; + } else { + return RETURN_SUCCESS; + } + + TopaTable = (PROC_TRACE_TOPA_TABLE *) TopaTableBaseAddr; + TopaEntryPtr = &TopaTable->TopaEntry[0]; + TopaEntryPtr->Uint64 = 0; + TopaEntryPtr->Bits.Base = (MemRegionBaseAddr >> 12) & 0x000FFFFF; + TopaEntryPtr->Bits.BaseHi = RShiftU64 ((UINT64) MemRegionBaseAddr, 32) & 0xFFFFFFFF; + TopaEntryPtr->Bits.Size = ProcTraceData->ProcTraceMemSize; + TopaEntryPtr->Bits.END = 0; + + TopaEntryPtr = &TopaTable->TopaEntry[1]; + TopaEntryPtr->Uint64 = 0; + TopaEntryPtr->Bits.Base = (TopaTableBaseAddr >> 12) & 0x000FFFFF; + TopaEntryPtr->Bits.BaseHi = RShiftU64 ((UINT64) TopaTableBaseAddr, 32) & 0xFFFFFFFF; + TopaEntryPtr->Bits.END = 1; + + // + // Program the MSR IA32_RTIT_OUTPUT_BASE (0x560) bits[63:7] with ToPA base + // + OutputBaseReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64; + OutputBaseReg.Bits.Base = (TopaTableBaseAddr >> 7) & 0x01FFFFFF; + OutputBaseReg.Bits.BaseHi = RShiftU64 ((UINT64) TopaTableBaseAddr, 32) & 0xFFFFFFFF; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_OUTPUT_BASE, + OutputBaseReg.Uint64 + ); + + // + // Set the MSR IA32_RTIT_OUTPUT_MASK (0x561) bits[63:7] to 0 + // + OutputMaskPtrsReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64; + OutputMaskPtrsReg.Bits.MaskOrTableOffset = 0; + OutputMaskPtrsReg.Bits.OutputOffset = 0; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_OUTPUT_MASK_PTRS, + OutputMaskPtrsReg.Uint64 + ); + // + // Enable ToPA output scheme by enabling MSR IA32_RTIT_CTL (0x570) ToPA (Bit 8) + // + CtrlReg.Bits.ToPA = 1; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_CTL, + CtrlReg.Uint64 + ); + } + + /// + /// Enable the Processor Trace feature from MSR IA32_RTIT_CTL (570h) + /// + CtrlReg.Bits.OS = 1; + CtrlReg.Bits.User = 1; + CtrlReg.Bits.BranchEn = 1; + CtrlReg.Bits.TraceEn = 1; + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_RTIT_CTL, + CtrlReg.Uint64 + ); + + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c new file mode 100644 index 000000000..44b07749f --- /dev/null +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c @@ -0,0 +1,137 @@ +/** @file + X2Apic feature. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +VOID * +EFIAPI +X2ApicGetConfigData ( + IN UINTN NumberOfProcessors + ) +{ + BOOLEAN *ConfigData; + + ConfigData = AllocateZeroPool (sizeof (BOOLEAN) * NumberOfProcessors); + ASSERT (ConfigData != NULL); + return ConfigData; +} + +/** + Detects if X2Apci feature supported on current processor. + + Detect if X2Apci has been already enabled. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE X2Apci feature is supported. + @retval FALSE X2Apci feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +X2ApicSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + BOOLEAN *X2ApicEnabled; + + ASSERT (ConfigData != NULL); + X2ApicEnabled = (BOOLEAN *) ConfigData; + // + // *ConfigData indicates if X2APIC enabled on current processor + // + X2ApicEnabled[ProcessorNumber] = (GetApicMode () == LOCAL_APIC_MODE_X2APIC) ? TRUE : FALSE; + + return (CpuInfo->CpuIdVersionInfoEcx.Bits.x2APIC == 1); +} + +/** + Initializes X2Apci feature to specific state. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the X2Apci feature must be enabled. + If FALSE, then the X2Apci feature must be disabled. + + @retval RETURN_SUCCESS X2Apci feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +X2ApicInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + BOOLEAN *X2ApicEnabled; + + // + // The scope of the MSR_IA32_APIC_BASE is core for below processor type, only program + // MSR_IA32_APIC_BASE for thread 0 in each core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + ASSERT (ConfigData != NULL); + X2ApicEnabled = (BOOLEAN *) ConfigData; + if (X2ApicEnabled[ProcessorNumber]) { + PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_APIC_BASE, + MSR_IA32_APIC_BASE_REGISTER, + Bits.EXTD, + 1 + ); + } else { + // + // Enable X2APIC mode only if X2APIC is not enabled, + // Needn't to disabe X2APIC mode again if X2APIC is not enabled + // + if (State) { + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_APIC_BASE, + MSR_IA32_APIC_BASE_REGISTER, + Bits.EXTD, + 1 + ); + } + } + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c new file mode 100644 index 000000000..8adbd43fe --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -0,0 +1,175 @@ +/** @file + CPU Exception Handler Library common functions. + + Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuExceptionCommon.h" + +// +// Error code flag indicating whether or not an error code will be +// pushed on the stack if an exception occurs. +// +// 1 means an error code will be pushed, otherwise 0 +// +CONST UINT32 mErrorCodeFlag = 0x00227d00; + +// +// Define the maximum message length +// +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 + +CONST CHAR8 mExceptionReservedStr[] = "Reserved"; +CONST CHAR8 *mExceptionNameStr[] = { + "#DE - Divide Error", + "#DB - Debug", + "NMI Interrupt", + "#BP - Breakpoint", + "#OF - Overflow", + "#BR - BOUND Range Exceeded", + "#UD - Invalid Opcode", + "#NM - Device Not Available", + "#DF - Double Fault", + "Coprocessor Segment Overrun", + "#TS - Invalid TSS", + "#NP - Segment Not Present", + "#SS - Stack Fault Fault", + "#GP - General Protection", + "#PF - Page-Fault", + "Reserved", + "#MF - x87 FPU Floating-Point Error", + "#AC - Alignment Check", + "#MC - Machine-Check", + "#XM - SIMD floating-point", + "#VE - Virtualization", + "#CP - Control Protection" +}; + +#define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *)) + +/** + Get ASCII format string exception name by exception type. + + @param ExceptionType Exception type. + + @return ASCII format string exception name. +**/ +CONST CHAR8 * +GetExceptionNameStr ( + IN EFI_EXCEPTION_TYPE ExceptionType + ) +{ + if ((UINTN) ExceptionType < EXCEPTION_KNOWN_NAME_NUM) { + return mExceptionNameStr[ExceptionType]; + } else { + return mExceptionReservedStr; + } +} + +/** + Prints a message to the serial port. + + @param Format Format string for the message to print. + @param ... Variable argument list whose contents are accessed + based on the format string specified by Format. + +**/ +VOID +EFIAPI +InternalPrintMessage ( + IN CONST CHAR8 *Format, + ... + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + VA_LIST Marker; + + // + // Convert the message to an ASCII String + // + VA_START (Marker, Format); + AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); + VA_END (Marker); + + // + // Send the print string to a Serial Port + // + SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); +} + +/** + Find and display image base address and return image base and its entry point. + + @param CurrentEip Current instruction pointer. + +**/ +VOID +DumpModuleImageInfo ( + IN UINTN CurrentEip + ) +{ + EFI_STATUS Status; + UINTN Pe32Data; + VOID *PdbPointer; + VOID *EntryPoint; + + Pe32Data = PeCoffSearchImageBase (CurrentEip); + if (Pe32Data == 0) { + InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); + } else { + // + // Find Image Base entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, &EntryPoint); + if (EFI_ERROR (Status)) { + EntryPoint = NULL; + } + InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEip); + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data); + if (PdbPointer != NULL) { + InternalPrintMessage ("%a", PdbPointer); + } else { + InternalPrintMessage ("(No PDB) " ); + } + InternalPrintMessage ( + " (ImageBase=%016lp, EntryPoint=%016p) !!!!\n", + (VOID *) Pe32Data, + EntryPoint + ); + } +} + +/** + Read and save reserved vector information + + @param[in] VectorInfo Pointer to reserved vector list. + @param[out] ReservedVector Pointer to reserved vector data buffer. + @param[in] VectorCount Vector number to be updated. + + @return EFI_SUCCESS Read and save vector info successfully. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + +**/ +EFI_STATUS +ReadAndVerifyVectorInfo ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo, + OUT RESERVED_VECTORS_DATA *ReservedVector, + IN UINTN VectorCount + ) +{ + while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { + if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) { + // + // If vector attrubute is invalid + // + return EFI_INVALID_PARAMETER; + } + if (VectorInfo->VectorNumber < VectorCount) { + ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute; + } + VectorInfo ++; + } + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h new file mode 100644 index 000000000..805dd9cbb --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -0,0 +1,321 @@ +/** @file + Common header file for CPU Exception Handler Library. + + Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_EXCEPTION_COMMON_H_ +#define _CPU_EXCEPTION_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPU_EXCEPTION_NUM 32 +#define CPU_INTERRUPT_NUM 256 +#define HOOKAFTER_STUB_SIZE 16 + +// +// Exception Error Code of Page-Fault Exception +// +#define IA32_PF_EC_P BIT0 +#define IA32_PF_EC_WR BIT1 +#define IA32_PF_EC_US BIT2 +#define IA32_PF_EC_RSVD BIT3 +#define IA32_PF_EC_ID BIT4 +#define IA32_PF_EC_PK BIT5 +#define IA32_PF_EC_SS BIT6 +#define IA32_PF_EC_SGX BIT15 + +#include "ArchInterruptDefs.h" + +#define CPU_STACK_SWITCH_EXCEPTION_NUMBER \ + FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + +#define CPU_STACK_SWITCH_EXCEPTION_LIST \ + FixedPcdGetPtr (PcdCpuStackSwitchExceptionList) + +#define CPU_KNOWN_GOOD_STACK_SIZE \ + FixedPcdGet32 (PcdCpuKnownGoodStackSize) + +#define CPU_TSS_GDT_SIZE (SIZE_2KB + CPU_TSS_DESC_SIZE + CPU_TSS_SIZE) + +// +// Record exception handler information +// +typedef struct { + UINTN ExceptionStart; + UINTN ExceptionStubHeaderSize; + UINTN HookAfterStubHeaderStart; +} EXCEPTION_HANDLER_TEMPLATE_MAP; + +typedef struct { + UINTN IdtEntryCount; + SPIN_LOCK DisplayMessageSpinLock; + RESERVED_VECTORS_DATA *ReservedVectors; + EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler; +} EXCEPTION_HANDLER_DATA; + +extern CONST UINT32 mErrorCodeFlag; +extern CONST UINTN mDoFarReturnFlag; + +/** + Return address map of exception handler template so that C code can generate + exception tables. + + @param AddressMap Pointer to a buffer where the address map is returned. +**/ +VOID +EFIAPI +AsmGetTemplateAddressMap ( + OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap + ); + +/** + Return address map of exception handler template so that C code can generate + exception tables. + + @param IdtEntry Pointer to IDT entry to be updated. + @param InterruptHandler IDT handler value. + +**/ +VOID +ArchUpdateIdtEntry ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, + IN UINTN InterruptHandler + ); + +/** + Read IDT handler value from IDT entry. + + @param IdtEntry Pointer to IDT entry to be read. + +**/ +UINTN +ArchGetIdtHandler ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry + ); + +/** + Prints a message to the serial port. + + @param Format Format string for the message to print. + @param ... Variable argument list whose contents are accessed + based on the format string specified by Format. + +**/ +VOID +EFIAPI +InternalPrintMessage ( + IN CONST CHAR8 *Format, + ... + ); + +/** + Find and display image base address and return image base and its entry point. + + @param CurrentEip Current instruction pointer. + +**/ +VOID +DumpModuleImageInfo ( + IN UINTN CurrentEip + ); + +/** + Display CPU information. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +DumpImageAndCpuContent ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ); + +/** + Internal worker function to initialize exception handler. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in, out] ExceptionHandlerData Pointer to exception handler data. + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + with default exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +InitializeCpuExceptionHandlersWorker ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN OUT EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Registers a function to be called from the processor interrupt handler. + + @param[in] InterruptType Defines which interrupt or exception to hook. + @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the handler + will be uninstalled + @param[in] ExceptionHandlerData Pointer to exception handler data. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, + or this function is not supported. +**/ +EFI_STATUS +RegisterCpuInterruptHandlerWorker ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Internal worker function to update IDT entries accordling to vector attributes. + + @param[in] IdtTable Pointer to IDT table. + @param[in] TemplateMap Pointer to a buffer where the address map is + returned. + @param[in] ExceptionHandlerData Pointer to exception handler data. + +**/ +VOID +UpdateIdtTable ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, + IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchSaveExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchRestoreExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Fix up the vector number and function address in the vector code. + + @param[in] NewVectorAddr New vector handler address. + @param[in] VectorNum Index of vector. + @param[in] OldVectorAddr Old vector handler address. + +**/ +VOID +EFIAPI +AsmVectorNumFixup ( + IN VOID *NewVectorAddr, + IN UINT8 VectorNum, + IN VOID *OldVectorAddr + ); + +/** + Read and save reserved vector information + + @param[in] VectorInfo Pointer to reserved vector list. + @param[out] ReservedVector Pointer to reserved vector data buffer. + @param[in] VectorCount Vector number to be updated. + + @return EFI_SUCCESS Read and save vector info successfully. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + +**/ +EFI_STATUS +ReadAndVerifyVectorInfo ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo, + OUT RESERVED_VECTORS_DATA *ReservedVector, + IN UINTN VectorCount + ); + +/** + Get ASCII format string exception name by exception type. + + @param ExceptionType Exception type. + + @return ASCII format string exception name. +**/ +CONST CHAR8 * +GetExceptionNameStr ( + IN EFI_EXCEPTION_TYPE ExceptionType + ); + +/** + Internal worker function for common exception handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +CommonExceptionHandlerWorker ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ); + +/** + Setup separate stack for specific exceptions. + + @param[in] StackSwitchData Pointer to data required for setuping up + stack switch. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized with new stack. + @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. +**/ +EFI_STATUS +ArchSetupExceptionStack ( + IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + ); + +/** + Return address map of exception handler template so that C code can generate + exception tables. The template is only for exceptions using task gate instead + of interrupt gate. + + @param AddressMap Pointer to a buffer where the address map is returned. +**/ +VOID +EFIAPI +AsmGetTssTemplateMap ( + OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap + ); + +#endif + diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf similarity index 54% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index 5873bf021..61e2ec30b 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -1,15 +1,9 @@ ## @file # CPU Exception Handler library instance for DXE modules. # -# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# +# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# ## [Defines] @@ -18,7 +12,7 @@ MODULE_UNI_FILE = DxeCpuExceptionHandlerLib.uni FILE_GUID = B6E9835A-EDCF-4748-98A8-27D3C722E02D MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 + VERSION_STRING = 1.1 LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER UEFI_APPLICATION # @@ -28,27 +22,31 @@ # [Sources.Ia32] - Ia32/ExceptionHandlerAsm.asm - Ia32/ExceptionHandlerAsm.S |GCC + Ia32/ExceptionHandlerAsm.nasm + Ia32/ExceptionTssEntryAsm.nasm Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] - X64/ExceptionHandlerAsm.asm - X64/ExceptionHandlerAsm.S |GCC + X64/Xcode5ExceptionHandlerAsm.nasm X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h [Sources.common] CpuExceptionCommon.h CpuExceptionCommon.c - DxeSmmCpuException.c + PeiDxeSmmCpuException.c DxeException.c +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] BaseLib @@ -56,9 +54,6 @@ PrintLib SynchronizationLib LocalApicLib - PeCoffGetEntryPointLib + PeCoffGetEntryPointLib MemoryAllocationLib DebugLib - -[Ppis] - gEfiVectorHandoffInfoPpiGuid diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni new file mode 100644 index 000000000..e1850eee2 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Exception Handler library instance for DXE modules. +// +// CPU Exception Handler library instance for DXE modules. +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Handler library instance for DXE modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Handler library instance for DXE modules." + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c new file mode 100644 index 000000000..fd59f09ec --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -0,0 +1,287 @@ +/** @file + CPU exception handler library implemenation for DXE modules. + + Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "CpuExceptionCommon.h" +#include +#include +#include + +CONST UINTN mDoFarReturnFlag = 0; + +RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM]; +EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM]; +UINTN mEnabledInterruptNum = 0; + +EXCEPTION_HANDLER_DATA mExceptionHandlerData; + +UINT8 mNewStack[CPU_STACK_SWITCH_EXCEPTION_NUMBER * + CPU_KNOWN_GOOD_STACK_SIZE]; +UINT8 mNewGdt[CPU_TSS_GDT_SIZE]; + +/** + Common exception handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +EFIAPI +CommonExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + CommonExceptionHandlerWorker (ExceptionType, SystemContext, &mExceptionHandlerData); +} + +/** + Initializes all CPU exceptions entries and provides the default exception handlers. + + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to + persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. + + @param[in] VectorInfo Pointer to reserved vector list. + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + with default exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlers ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL + ) +{ + mExceptionHandlerData.ReservedVectors = mReservedVectorsData; + mExceptionHandlerData.ExternalInterruptHandler = mExternalInterruptHandlerTable; + InitializeSpinLock (&mExceptionHandlerData.DisplayMessageSpinLock); + return InitializeCpuExceptionHandlersWorker (VectorInfo, &mExceptionHandlerData); +} + +/** + Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers. + + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to + persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. + + @param[in] VectorInfo Pointer to reserved vector list. + + @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized + with default interrupt/exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuInterruptHandlers ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL + ) +{ + EFI_STATUS Status; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + IA32_DESCRIPTOR IdtDescriptor; + UINTN IdtEntryCount; + EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; + UINTN Index; + UINTN InterruptEntry; + UINT8 *InterruptEntryCode; + RESERVED_VECTORS_DATA *ReservedVectors; + EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler; + + Status = gBS->AllocatePool ( + EfiBootServicesCode, + sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, + (VOID **)&ReservedVectors + ); + ASSERT (!EFI_ERROR (Status) && ReservedVectors != NULL); + SetMem ((VOID *) ReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff); + if (VectorInfo != NULL) { + Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectors, CPU_INTERRUPT_NUM); + if (EFI_ERROR (Status)) { + FreePool (ReservedVectors); + return EFI_INVALID_PARAMETER; + } + } + + ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM); + ASSERT (ExternalInterruptHandler != NULL); + + // + // Read IDT descriptor and calculate IDT size + // + AsmReadIdtr (&IdtDescriptor); + IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); + if (IdtEntryCount > CPU_INTERRUPT_NUM) { + IdtEntryCount = CPU_INTERRUPT_NUM; + } + // + // Create Interrupt Descriptor Table and Copy the old IDT table in + // + IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM); + ASSERT (IdtTable != NULL); + CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount); + + AsmGetTemplateAddressMap (&TemplateMap); + ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); + + Status = gBS->AllocatePool ( + EfiBootServicesCode, + TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM, + (VOID **)&InterruptEntryCode + ); + ASSERT (!EFI_ERROR (Status) && InterruptEntryCode != NULL); + + InterruptEntry = (UINTN) InterruptEntryCode; + for (Index = 0; Index < CPU_INTERRUPT_NUM; Index ++) { + CopyMem ( + (VOID *) InterruptEntry, + (VOID *) TemplateMap.ExceptionStart, + TemplateMap.ExceptionStubHeaderSize + ); + AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index, (VOID *) TemplateMap.ExceptionStart); + InterruptEntry += TemplateMap.ExceptionStubHeaderSize; + } + + TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode; + mExceptionHandlerData.IdtEntryCount = CPU_INTERRUPT_NUM; + mExceptionHandlerData.ReservedVectors = ReservedVectors; + mExceptionHandlerData.ExternalInterruptHandler = ExternalInterruptHandler; + InitializeSpinLock (&mExceptionHandlerData.DisplayMessageSpinLock); + + UpdateIdtTable (IdtTable, &TemplateMap, &mExceptionHandlerData); + + // + // Load Interrupt Descriptor Table + // + IdtDescriptor.Base = (UINTN) IdtTable; + IdtDescriptor.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1); + AsmWriteIdtr ((IA32_DESCRIPTOR *) &IdtDescriptor); + + return EFI_SUCCESS; +} + +/** + Registers a function to be called from the processor interrupt handler. + + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the + handler for the processor interrupt or exception type specified by InterruptType is uninstalled. + The installed handler is called once for each processor interrupt or exception. + NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or + InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned. + + @param[in] InterruptType Defines which interrupt or exception to hook. + @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, + or this function is not supported. +**/ +EFI_STATUS +EFIAPI +RegisterCpuInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler, &mExceptionHandlerData); +} + +/** + Initializes CPU exceptions entries and setup stack switch for given exceptions. + + This method will call InitializeCpuExceptionHandlers() to setup default + exception handlers unless indicated not to do it explicitly. + + If InitData is passed with NULL, this method will use the resource reserved + by global variables to initialize it; Otherwise it will use data in InitData + to setup stack switch. This is for the different use cases in DxeCore and + Cpu MP exception initialization. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in] InitData Pointer to data required to setup stack switch for + given exceptions. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized. + @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid + content. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlersEx ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL + ) +{ + EFI_STATUS Status; + CPU_EXCEPTION_INIT_DATA EssData; + IA32_DESCRIPTOR Idtr; + IA32_DESCRIPTOR Gdtr; + + // + // To avoid repeat initialization of default handlers, the caller should pass + // an extended init data with InitDefaultHandlers set to FALSE. There's no + // need to call this method to just initialize default handlers. Call non-ex + // version instead; or this method must be implemented as a simple wrapper of + // non-ex version of it, if this version has to be called. + // + if (InitData == NULL || InitData->X64.InitDefaultHandlers) { + Status = InitializeCpuExceptionHandlers (VectorInfo); + } else { + Status = EFI_SUCCESS; + } + + if (!EFI_ERROR (Status)) { + // + // Initializing stack switch is only necessary for Stack Guard functionality. + // + if (PcdGetBool (PcdCpuStackGuard)) { + if (InitData == NULL) { + SetMem (mNewGdt, sizeof (mNewGdt), 0); + + AsmReadIdtr (&Idtr); + AsmReadGdtr (&Gdtr); + + EssData.X64.Revision = CPU_EXCEPTION_INIT_DATA_REV; + EssData.X64.KnownGoodStackTop = (UINTN)mNewStack + sizeof (mNewStack); + EssData.X64.KnownGoodStackSize = CPU_KNOWN_GOOD_STACK_SIZE; + EssData.X64.StackSwitchExceptions = CPU_STACK_SWITCH_EXCEPTION_LIST; + EssData.X64.StackSwitchExceptionNumber = CPU_STACK_SWITCH_EXCEPTION_NUMBER; + EssData.X64.IdtTable = (VOID *)Idtr.Base; + EssData.X64.IdtTableSize = Idtr.Limit + 1; + EssData.X64.GdtTable = mNewGdt; + EssData.X64.GdtTableSize = sizeof (mNewGdt); + EssData.X64.ExceptionTssDesc = mNewGdt + Gdtr.Limit + 1; + EssData.X64.ExceptionTssDescSize = CPU_TSS_DESC_SIZE; + EssData.X64.ExceptionTss = mNewGdt + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE; + EssData.X64.ExceptionTssSize = CPU_TSS_SIZE; + + InitData = &EssData; + } + Status = ArchSetupExceptionStack (InitData); + } + } + + return Status; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c new file mode 100644 index 000000000..1aafb7dac --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -0,0 +1,427 @@ +/** @file + IA32 CPU Exception Handler functons. + + Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuExceptionCommon.h" + +/** + Return address map of exception handler template so that C code can generate + exception tables. + + @param IdtEntry Pointer to IDT entry to be updated. + @param InterruptHandler IDT handler value. + +**/ +VOID +ArchUpdateIdtEntry ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, + IN UINTN InterruptHandler + ) +{ + IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Read IDT handler value from IDT entry. + + @param IdtEntry Pointer to IDT entry to be read. + +**/ +UINTN +ArchGetIdtHandler ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry + ) +{ + return (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16); +} + +/** + Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchSaveExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + IA32_EFLAGS32 Eflags; + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + // + // Save Exception context in global variable in first entry of the exception handler. + // So when original exception handler returns to the new exception handler (second entry), + // the Eflags/Cs/Eip/ExceptionData can be used. + // + ReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextIa32->Eflags; + ReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextIa32->Cs; + ReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextIa32->Eip; + ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData; + // + // Clear IF flag to avoid old IDT handler enable interrupt by IRET + // + Eflags.UintN = SystemContext.SystemContextIa32->Eflags; + Eflags.Bits.IF = 0; + SystemContext.SystemContextIa32->Eflags = Eflags.UintN; + // + // Modify the EIP in stack, then old IDT handler will return to HookAfterStubBegin. + // + SystemContext.SystemContextIa32->Eip = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode; +} + +/** + Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchRestoreExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + SystemContext.SystemContextIa32->Eflags = ReservedVectors[ExceptionType].OldFlags; + SystemContext.SystemContextIa32->Cs = ReservedVectors[ExceptionType].OldCs; + SystemContext.SystemContextIa32->Eip = ReservedVectors[ExceptionType].OldIp; + SystemContext.SystemContextIa32->ExceptionData = ReservedVectors[ExceptionType].ExceptionData; +} + +/** + Setup separate stack for given exceptions. + + @param[in] StackSwitchData Pointer to data required for setuping up + stack switch. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized with new stack. + @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. + +**/ +EFI_STATUS +ArchSetupExceptionStack ( + IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + ) +{ + IA32_DESCRIPTOR Gdtr; + IA32_DESCRIPTOR Idtr; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + IA32_TSS_DESCRIPTOR *TssDesc; + IA32_TASK_STATE_SEGMENT *Tss; + UINTN StackTop; + UINTN Index; + UINTN Vector; + UINTN TssBase; + UINTN GdtSize; + EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; + + if (StackSwitchData == NULL || + StackSwitchData->Ia32.Revision != CPU_EXCEPTION_INIT_DATA_REV || + StackSwitchData->Ia32.KnownGoodStackTop == 0 || + StackSwitchData->Ia32.KnownGoodStackSize == 0 || + StackSwitchData->Ia32.StackSwitchExceptions == NULL || + StackSwitchData->Ia32.StackSwitchExceptionNumber == 0 || + StackSwitchData->Ia32.StackSwitchExceptionNumber > CPU_EXCEPTION_NUM || + StackSwitchData->Ia32.GdtTable == NULL || + StackSwitchData->Ia32.IdtTable == NULL || + StackSwitchData->Ia32.ExceptionTssDesc == NULL || + StackSwitchData->Ia32.ExceptionTss == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // The caller is responsible for that the GDT table, no matter the existing + // one or newly allocated, has enough space to hold descriptors for exception + // task-state segments. + // + if (((UINTN)StackSwitchData->Ia32.GdtTable & (IA32_GDT_ALIGNMENT - 1)) != 0) { + return EFI_INVALID_PARAMETER; + } + + if ((UINTN)StackSwitchData->Ia32.ExceptionTssDesc < (UINTN)(StackSwitchData->Ia32.GdtTable)) { + return EFI_INVALID_PARAMETER; + } + + if ((UINTN)StackSwitchData->Ia32.ExceptionTssDesc + StackSwitchData->Ia32.ExceptionTssDescSize > + ((UINTN)(StackSwitchData->Ia32.GdtTable) + StackSwitchData->Ia32.GdtTableSize)) { + return EFI_INVALID_PARAMETER; + } + + // + // We need one descriptor and one TSS for current task and every exception + // specified. + // + if (StackSwitchData->Ia32.ExceptionTssDescSize < + sizeof (IA32_TSS_DESCRIPTOR) * (StackSwitchData->Ia32.StackSwitchExceptionNumber + 1)) { + return EFI_INVALID_PARAMETER; + } + if (StackSwitchData->Ia32.ExceptionTssSize < + sizeof (IA32_TASK_STATE_SEGMENT) * (StackSwitchData->Ia32.StackSwitchExceptionNumber + 1)) { + return EFI_INVALID_PARAMETER; + } + + TssDesc = StackSwitchData->Ia32.ExceptionTssDesc; + Tss = StackSwitchData->Ia32.ExceptionTss; + + // + // Initialize new GDT table and/or IDT table, if any + // + AsmReadIdtr (&Idtr); + AsmReadGdtr (&Gdtr); + + GdtSize = (UINTN)TssDesc + + sizeof (IA32_TSS_DESCRIPTOR) * + (StackSwitchData->Ia32.StackSwitchExceptionNumber + 1) - + (UINTN)(StackSwitchData->Ia32.GdtTable); + if ((UINTN)StackSwitchData->Ia32.GdtTable != Gdtr.Base) { + CopyMem (StackSwitchData->Ia32.GdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); + Gdtr.Base = (UINTN)StackSwitchData->Ia32.GdtTable; + Gdtr.Limit = (UINT16)GdtSize - 1; + } + + if ((UINTN)StackSwitchData->Ia32.IdtTable != Idtr.Base) { + Idtr.Base = (UINTN)StackSwitchData->Ia32.IdtTable; + } + if (StackSwitchData->Ia32.IdtTableSize > 0) { + Idtr.Limit = (UINT16)(StackSwitchData->Ia32.IdtTableSize - 1); + } + + // + // Fixup current task descriptor. Task-state segment for current task will + // be filled by processor during task switching. + // + TssBase = (UINTN)Tss; + + TssDesc->Uint64 = 0; + TssDesc->Bits.LimitLow = sizeof(IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.BaseLow = (UINT16)TssBase; + TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); + TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.P = 1; + TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); + + // + // Fixup exception task descriptor and task-state segment + // + AsmGetTssTemplateMap (&TemplateMap); + StackTop = StackSwitchData->Ia32.KnownGoodStackTop - CPU_STACK_ALIGNMENT; + StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + IdtTable = StackSwitchData->Ia32.IdtTable; + for (Index = 0; Index < StackSwitchData->Ia32.StackSwitchExceptionNumber; ++Index) { + TssDesc += 1; + Tss += 1; + + // + // Fixup TSS descriptor + // + TssBase = (UINTN)Tss; + + TssDesc->Uint64 = 0; + TssDesc->Bits.LimitLow = sizeof(IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.BaseLow = (UINT16)TssBase; + TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); + TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.P = 1; + TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); + + // + // Fixup TSS + // + Vector = StackSwitchData->Ia32.StackSwitchExceptions[Index]; + if (Vector >= CPU_EXCEPTION_NUM || + Vector >= (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)) { + continue; + } + + ZeroMem (Tss, sizeof (*Tss)); + Tss->EIP = (UINT32)(TemplateMap.ExceptionStart + + Vector * TemplateMap.ExceptionStubHeaderSize); + Tss->EFLAGS = 0x2; + Tss->ESP = StackTop; + Tss->CR3 = AsmReadCr3 (); + Tss->ES = AsmReadEs (); + Tss->CS = AsmReadCs (); + Tss->SS = AsmReadSs (); + Tss->DS = AsmReadDs (); + Tss->FS = AsmReadFs (); + Tss->GS = AsmReadGs (); + + StackTop -= StackSwitchData->Ia32.KnownGoodStackSize; + + // + // Update IDT to use Task Gate for given exception + // + IdtTable[Vector].Bits.OffsetLow = 0; + IdtTable[Vector].Bits.Selector = (UINT16)((UINTN)TssDesc - Gdtr.Base); + IdtTable[Vector].Bits.Reserved_0 = 0; + IdtTable[Vector].Bits.GateType = IA32_IDT_GATE_TYPE_TASK; + IdtTable[Vector].Bits.OffsetHigh = 0; + } + + // + // Publish GDT + // + AsmWriteGdtr (&Gdtr); + + // + // Load current task + // + AsmWriteTr ((UINT16)((UINTN)StackSwitchData->Ia32.ExceptionTssDesc - Gdtr.Base)); + + // + // Publish IDT + // + AsmWriteIdtr (&Idtr); + + return EFI_SUCCESS; +} + +/** + Display processor context. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Processor context to be display. +**/ +VOID +EFIAPI +DumpCpuContext ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + InternalPrintMessage ( + "!!!! IA32 Exception Type - %02x(%a) CPU Apic ID - %08x !!!!\n", + ExceptionType, + GetExceptionNameStr (ExceptionType), + GetApicId () + ); + if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) { + InternalPrintMessage ( + "ExceptionData - %08x", + SystemContext.SystemContextIa32->ExceptionData + ); + if (ExceptionType == EXCEPT_IA32_PAGE_FAULT) { + InternalPrintMessage ( + " I:%x R:%x U:%x W:%x P:%x PK:%x SS:%x SGX:%x", + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_RSVD) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_US) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_WR) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_P) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_PK) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_SS) != 0, + (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_SGX) != 0 + ); + } + InternalPrintMessage ("\n"); + } + InternalPrintMessage ( + "EIP - %08x, CS - %08x, EFLAGS - %08x\n", + SystemContext.SystemContextIa32->Eip, + SystemContext.SystemContextIa32->Cs, + SystemContext.SystemContextIa32->Eflags + ); + InternalPrintMessage ( + "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n", + SystemContext.SystemContextIa32->Eax, + SystemContext.SystemContextIa32->Ecx, + SystemContext.SystemContextIa32->Edx, + SystemContext.SystemContextIa32->Ebx + ); + InternalPrintMessage ( + "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n", + SystemContext.SystemContextIa32->Esp, + SystemContext.SystemContextIa32->Ebp, + SystemContext.SystemContextIa32->Esi, + SystemContext.SystemContextIa32->Edi + ); + InternalPrintMessage ( + "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n", + SystemContext.SystemContextIa32->Ds, + SystemContext.SystemContextIa32->Es, + SystemContext.SystemContextIa32->Fs, + SystemContext.SystemContextIa32->Gs, + SystemContext.SystemContextIa32->Ss + ); + InternalPrintMessage ( + "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n", + SystemContext.SystemContextIa32->Cr0, + SystemContext.SystemContextIa32->Cr2, + SystemContext.SystemContextIa32->Cr3, + SystemContext.SystemContextIa32->Cr4 + ); + InternalPrintMessage ( + "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n", + SystemContext.SystemContextIa32->Dr0, + SystemContext.SystemContextIa32->Dr1, + SystemContext.SystemContextIa32->Dr2, + SystemContext.SystemContextIa32->Dr3 + ); + InternalPrintMessage ( + "DR6 - %08x, DR7 - %08x\n", + SystemContext.SystemContextIa32->Dr6, + SystemContext.SystemContextIa32->Dr7 + ); + InternalPrintMessage ( + "GDTR - %08x %08x, IDTR - %08x %08x\n", + SystemContext.SystemContextIa32->Gdtr[0], + SystemContext.SystemContextIa32->Gdtr[1], + SystemContext.SystemContextIa32->Idtr[0], + SystemContext.SystemContextIa32->Idtr[1] + ); + InternalPrintMessage ( + "LDTR - %08x, TR - %08x\n", + SystemContext.SystemContextIa32->Ldtr, + SystemContext.SystemContextIa32->Tr + ); + InternalPrintMessage ( + "FXSAVE_STATE - %08x\n", + &SystemContext.SystemContextIa32->FxSaveState + ); +} + +/** + Display CPU information. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +DumpImageAndCpuContent ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + DumpCpuContext (ExceptionType, SystemContext); + // + // Dump module image base and module entry point by EIP + // + if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) && + ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0)) { + // + // The EIP in SystemContext could not be used + // if it is page fault with I/D set. + // + DumpModuleImageInfo ((*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp)); + } else { + DumpModuleImageInfo (SystemContext.SystemContextIa32->Eip); + } +} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h similarity index 60% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h index a8d3556a8..fc37fbe58 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h @@ -1,14 +1,8 @@ /** @file Ia32 arch definition for CPU Exception Handler Library. - Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -41,4 +35,12 @@ typedef struct { UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE]; } RESERVED_VECTORS_DATA; +#define CPU_TSS_DESC_SIZE \ + (sizeof (IA32_TSS_DESCRIPTOR) * \ + (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) + +#define CPU_TSS_SIZE \ + (sizeof (IA32_TASK_STATE_SEGMENT) * \ + (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) + #endif diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm similarity index 68% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 90da51bd6..58d531289 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -1,12 +1,6 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php. -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: ; @@ -20,20 +14,17 @@ ; ;------------------------------------------------------------------------------ - .686 - .model flat,C - ; ; CommonExceptionHandler() ; -CommonExceptionHandler PROTO C +extern ASM_PFX(CommonExceptionHandler) -.data +SECTION .data -EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions -EXTRN mDoFarReturnFlag:DWORD ; Do far return flag +extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions +extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag -.code +SECTION .text ALIGN 8 @@ -41,31 +32,31 @@ ALIGN 8 ; exception handler stub table ; AsmIdtVectorBegin: -REPEAT 32 - db 6ah ; push #VectorNum +%rep 32 + db 0x6a ; push #VectorNum db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum push eax - mov eax, CommonInterruptEntry + mov eax, ASM_PFX(CommonInterruptEntry) jmp eax -ENDM +%endrep AsmIdtVectorEnd: HookAfterStubBegin: - db 6ah ; push + db 0x6a ; push VectorNum: - db 0 ; 0 will be fixed + db 0 ; 0 will be fixed push eax mov eax, HookAfterStubHeaderEnd jmp eax HookAfterStubHeaderEnd: pop eax sub esp, 8 ; reserve room for filling exception data later - push [esp + 8] + push dword [esp + 8] xchg ecx, [esp] ; get vector number - bt mErrorCodeFlag, ecx - jnc @F - push [esp] ; addition push if exception data needed -@@: + bt [ASM_PFX(mErrorCodeFlag)], ecx + jnc .0 + push dword [esp] ; addition push if exception data needed +.0: xchg ecx, [esp] ; restore ecx push eax @@ -88,7 +79,8 @@ HookAfterStubHeaderEnd: ; +---------------------+ ; + EBP + ; +---------------------+ <-- EBP -CommonInterruptEntry PROC PUBLIC +global ASM_PFX(CommonInterruptEntry) +ASM_PFX(CommonInterruptEntry): cli pop eax ; @@ -100,10 +92,10 @@ CommonInterruptEntry PROC PUBLIC ; Get vector number from top of stack ; xchg ecx, [esp] - and ecx, 0FFh ; Vector number should be less than 256 + and ecx, 0xFF ; Vector number should be less than 256 cmp ecx, 32 ; Intel reserved vector for exceptions? jae NoErrorCode - bt mErrorCodeFlag, ecx + bt [ASM_PFX(mErrorCodeFlag)], ecx jc HasErrorCode NoErrorCode: @@ -187,13 +179,13 @@ ErrorCodeAndVectorOnStack: ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 ; is 16-byte aligned ; - and esp, 0fffffff0h + and esp, 0xfffffff0 sub esp, 12 sub esp, 8 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - + ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; push eax push ecx @@ -201,14 +193,14 @@ ErrorCodeAndVectorOnStack: push ebx lea ecx, [ebp + 6 * 4] push ecx ; ESP - push dword ptr [ebp] ; EBP + push dword [ebp] ; EBP push esi push edi ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; mov eax, ss push eax - movzx eax, word ptr [ebp + 4 * 4] + movzx eax, word [ebp + 4 * 4] push eax mov eax, ds push eax @@ -228,14 +220,14 @@ ErrorCodeAndVectorOnStack: sidt [esp] mov eax, [esp + 2] xchg eax, [esp] - and eax, 0FFFFh + and eax, 0xFFFF mov [esp+4], eax sub esp, 8 sgdt [esp] mov eax, [esp + 2] xchg eax, [esp] - and eax, 0FFFFh + and eax, 0xFFFF mov [esp+4], eax ;; UINT32 Ldtr, Tr; @@ -250,10 +242,22 @@ ErrorCodeAndVectorOnStack: push eax ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + mov eax, 1 + push ebx ; temporarily save value of ebx on stack + cpuid ; use CPUID to determine if FXSAVE/FXRESTOR and DE + ; are supported + pop ebx ; retore value of ebx that was overwritten by CPUID mov eax, cr4 - or eax, 208h + push eax ; push cr4 firstly + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz .1 + or eax, BIT9 ; Set CR4.OSFXSR +.1: + test edx, BIT2 ; Test for Debugging Extensions support + jz .2 + or eax, BIT3 ; Set CR4.DE +.2: mov cr4, eax - push eax mov eax, cr3 push eax mov eax, cr2 @@ -280,24 +284,28 @@ ErrorCodeAndVectorOnStack: ;; FX_SAVE_STATE_IA32 FxSaveState; sub esp, 512 mov edi, esp - db 0fh, 0aeh, 07h ;fxsave [edi] + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support. + ; edx still contains result from CPUID above + jz .3 + db 0xf, 0xae, 0x7 ;fxsave [edi] +.3: ;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear cld ;; UINT32 ExceptionData; - push dword ptr [ebp + 2 * 4] + push dword [ebp + 2 * 4] ;; Prepare parameter and call mov edx, esp push edx - mov edx, dword ptr [ebp + 1 * 4] + mov edx, dword [ebp + 1 * 4] push edx ; ; Call External Exception Handler ; - mov eax, CommonExceptionHandler + mov eax, ASM_PFX(CommonExceptionHandler) call eax add esp, 8 @@ -307,7 +315,13 @@ ErrorCodeAndVectorOnStack: ;; FX_SAVE_STATE_IA32 FxSaveState; mov esi, esp - db 0fh, 0aeh, 0eh ; fxrstor [esi] + mov eax, 1 + cpuid ; use CPUID to determine if FXSAVE/FXRESTOR + ; are supported + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz .4 + db 0xf, 0xae, 0xe ; fxrstor [esi] +.4: add esp, 512 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; @@ -327,7 +341,7 @@ ErrorCodeAndVectorOnStack: mov cr4, eax ;; UINT32 EFlags; - pop dword ptr [ebp + 5 * 4] + pop dword [ebp + 5 * 4] ;; UINT32 Ldtr, Tr; ;; UINT32 Gdtr[2], Idtr[2]; @@ -335,7 +349,7 @@ ErrorCodeAndVectorOnStack: add esp, 24 ;; UINT32 Eip; - pop dword ptr [ebp + 3 * 4] + pop dword [ebp + 3 * 4] ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; ;; NOTE - modified segment registers could hang the debugger... We @@ -346,7 +360,7 @@ ErrorCodeAndVectorOnStack: pop fs pop es pop ds - pop dword ptr [ebp + 4 * 4] + pop dword [ebp + 4 * 4] pop ss ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; @@ -359,87 +373,84 @@ ErrorCodeAndVectorOnStack: pop ecx pop eax - pop dword ptr [ebp - 8] - pop dword ptr [ebp - 4] + pop dword [ebp - 8] + pop dword [ebp - 4] mov esp, ebp pop ebp add esp, 8 - cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler + cmp dword [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler jz DoReturn - cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + cmp dword [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag jz ErrorCode - jmp dword ptr [esp - 16] + jmp dword [esp - 16] ErrorCode: sub esp, 4 - jmp dword ptr [esp - 12] + jmp dword [esp - 12] -DoReturn: - cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET +DoReturn: + cmp dword [ASM_PFX(mDoFarReturnFlag)], 0 ; Check if need to do far return instead of IRET jz DoIret - push [esp + 8] ; save EFLAGS + push dword [esp + 8] ; save EFLAGS add esp, 16 - push [esp - 8] ; save CS in new location - push [esp - 8] ; save EIP in new location - push [esp - 8] ; save EFLAGS in new location + push dword [esp - 8] ; save CS in new location + push dword [esp - 8] ; save EIP in new location + push dword [esp - 8] ; save EFLAGS in new location popfd ; restore EFLAGS retf ; far return DoIret: iretd -CommonInterruptEntry ENDP - ;---------------------------------------; ; _AsmGetTemplateAddressMap ; ;----------------------------------------------------------------------------; -; +; ; Protocol prototype ; AsmGetTemplateAddressMap ( ; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap ; ); -; +; ; Routine Description: -; +; ; Return address map of interrupt handler template so that C code can generate ; interrupt table. -; +; ; Arguments: -; -; -; Returns: -; +; +; +; Returns: +; ; Nothing ; -; +; ; Input: [ebp][0] = Original ebp ; [ebp][4] = Return address -; +; ; Output: Nothing -; +; ; Destroys: Nothing ;-----------------------------------------------------------------------------; -AsmGetTemplateAddressMap proc near public +global ASM_PFX(AsmGetTemplateAddressMap) +ASM_PFX(AsmGetTemplateAddressMap): push ebp ; C prolog mov ebp, esp pushad - mov ebx, dword ptr [ebp + 08h] - mov dword ptr [ebx], AsmIdtVectorBegin - mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 - mov dword ptr [ebx + 8h], HookAfterStubBegin - + mov ebx, dword [ebp + 0x8] + mov dword [ebx], AsmIdtVectorBegin + mov dword [ebx + 0x4], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 + mov dword [ebx + 0x8], HookAfterStubBegin + popad pop ebp ret -AsmGetTemplateAddressMap ENDP ;------------------------------------------------------------------------------------- -; AsmVectorNumFixup (*VectorBase, VectorNum, HookStub); +; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr); ;------------------------------------------------------------------------------------- -AsmVectorNumFixup proc near public - mov eax, dword ptr [esp + 8] +global ASM_PFX(AsmVectorNumFixup) +ASM_PFX(AsmVectorNumFixup): + mov eax, dword [esp + 8] mov ecx, [esp + 4] mov [ecx + (VectorNum - HookAfterStubBegin)], al ret -AsmVectorNumFixup ENDP -END diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm new file mode 100644 index 000000000..dd3f74d2a --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm @@ -0,0 +1,390 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2017, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; ExceptionTssEntryAsm.Asm +; +; Abstract: +; +; IA32 CPU Exception Handler with Separate Stack +; +; Notes: +; +;------------------------------------------------------------------------------ + +; +; IA32 TSS Memory Layout Description +; +struc IA32_TSS + resw 1 + resw 1 + .ESP0: resd 1 + .SS0: resw 1 + resw 1 + .ESP1: resd 1 + .SS1: resw 1 + resw 1 + .ESP2: resd 1 + .SS2: resw 1 + resw 1 + ._CR3: resd 1 + .EIP: resd 1 + .EFLAGS: resd 1 + ._EAX: resd 1 + ._ECX: resd 1 + ._EDX: resd 1 + ._EBX: resd 1 + ._ESP: resd 1 + ._EBP: resd 1 + ._ESI: resd 1 + ._EDI: resd 1 + ._ES: resw 1 + resw 1 + ._CS: resw 1 + resw 1 + ._SS: resw 1 + resw 1 + ._DS: resw 1 + resw 1 + ._FS: resw 1 + resw 1 + ._GS: resw 1 + resw 1 + .LDT: resw 1 + resw 1 + resw 1 + resw 1 +endstruc + +; +; CommonExceptionHandler() +; +extern ASM_PFX(CommonExceptionHandler) + +SECTION .data + +SECTION .text + +ALIGN 8 + +; +; Exception handler stub table +; +AsmExceptionEntryBegin: +%assign Vector 0 +%rep 32 + +DoIret%[Vector]: + iretd +ASM_PFX(ExceptionTaskSwtichEntry%[Vector]): + db 0x6a ; push #VectorNum + db %[Vector] + mov eax, ASM_PFX(CommonTaskSwtichEntryPoint) + call eax + mov esp, eax ; Restore stack top + jmp DoIret%[Vector] + +%assign Vector Vector+1 +%endrep +AsmExceptionEntryEnd: + +; +; Common part of exception handler +; +global ASM_PFX(CommonTaskSwtichEntryPoint) +ASM_PFX(CommonTaskSwtichEntryPoint): + ; + ; Stack: + ; +---------------------+ <-- EBP - 8 + ; + TSS Base + + ; +---------------------+ <-- EBP - 4 + ; + CPUID.EDX + + ; +---------------------+ <-- EBP + ; + EIP + + ; +---------------------+ <-- EBP + 4 + ; + Vector Number + + ; +---------------------+ <-- EBP + 8 + ; + Error Code + + ; +---------------------+ + ; + + mov ebp, esp ; Stack frame + +; Use CPUID to determine if FXSAVE/FXRESTOR and DE are supported + mov eax, 1 + cpuid + push edx + +; Get TSS base of interrupted task through PreviousTaskLink field in +; current TSS base + sub esp, 8 + sgdt [esp + 2] + mov eax, [esp + 4] ; GDT base + add esp, 8 + + xor ebx, ebx + str bx ; Current TR + + mov ecx, [eax + ebx + 2] + shl ecx, 8 + mov cl, [eax + ebx + 7] + ror ecx, 8 ; ecx = Current TSS base + push ecx ; keep it in stack for later use + + movzx ebx, word [ecx] ; Previous Task Link + mov ecx, [eax + ebx + 2] + shl ecx, 8 + mov cl, [eax + ebx + 7] + ror ecx, 8 ; ecx = Previous TSS base + +; +; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 +; is 16-byte aligned +; + and esp, 0xfffffff0 + sub esp, 12 + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + push dword [ecx + IA32_TSS._EAX] + push dword [ecx + IA32_TSS._ECX] + push dword [ecx + IA32_TSS._EDX] + push dword [ecx + IA32_TSS._EBX] + push dword [ecx + IA32_TSS._ESP] + push dword [ecx + IA32_TSS._EBP] + push dword [ecx + IA32_TSS._ESI] + push dword [ecx + IA32_TSS._EDI] + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; + movzx eax, word [ecx + IA32_TSS._SS] + push eax + movzx eax, word [ecx + IA32_TSS._CS] + push eax + movzx eax, word [ecx + IA32_TSS._DS] + push eax + movzx eax, word [ecx + IA32_TSS._ES] + push eax + movzx eax, word [ecx + IA32_TSS._FS] + push eax + movzx eax, word [ecx + IA32_TSS._GS] + push eax + +;; UINT32 Eip; + push dword [ecx + IA32_TSS.EIP] + +;; UINT32 Gdtr[2], Idtr[2]; + sub esp, 8 + sidt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + + sub esp, 8 + sgdt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + +;; UINT32 Ldtr, Tr; + mov eax, ebx ; ebx still keeps selector of interrupted task + push eax + movzx eax, word [ecx + IA32_TSS.LDT] + push eax + +;; UINT32 EFlags; + push dword [ecx + IA32_TSS.EFLAGS] + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + mov eax, cr4 + push eax ; push cr4 firstly + + mov edx, [ebp - 4] ; cpuid.edx + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz .1 + or eax, BIT9 ; Set CR4.OSFXSR +.1: + test edx, BIT2 ; Test for Debugging Extensions support + jz .2 + or eax, BIT3 ; Set CR4.DE +.2: + mov cr4, eax + + mov eax, cr3 + push eax + mov eax, cr2 + push eax + xor eax, eax + push eax + mov eax, cr0 + push eax + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov eax, dr7 + push eax + mov eax, dr6 + push eax + mov eax, dr3 + push eax + mov eax, dr2 + push eax + mov eax, dr1 + push eax + mov eax, dr0 + push eax + +;; FX_SAVE_STATE_IA32 FxSaveState; +;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM) +;; when executing fxsave/fxrstor instruction + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support. + ; edx still contains result from CPUID above + jz .3 + clts + sub esp, 512 + mov edi, esp + db 0xf, 0xae, 0x7 ;fxsave [edi] +.3: + +;; UINT32 ExceptionData; + push dword [ebp + 8] + +;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear + cld + +;; call into exception handler + mov esi, ecx ; Keep TSS base to avoid overwrite + mov eax, ASM_PFX(CommonExceptionHandler) + +;; Prepare parameter and call + mov edx, esp + push edx ; EFI_SYSTEM_CONTEXT + push dword [ebp + 4] ; EFI_EXCEPTION_TYPE (vector number) + + ; + ; Call External Exception Handler + ; + call eax + add esp, 8 ; Restore stack before calling + mov ecx, esi ; Restore TSS base + +;; UINT32 ExceptionData; + add esp, 4 + +;; FX_SAVE_STATE_IA32 FxSaveState; + mov edx, [ebp - 4] ; cpuid.edx + test edx, BIT24 ; Test for FXSAVE/FXRESTOR support + jz .4 + mov esi, esp + db 0xf, 0xae, 0xe ; fxrstor [esi] +.4: + add esp, 512 + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; Skip restoration of DRx registers to support debuggers +;; that set breakpoints in interrupt/exception context + add esp, 4 * 6 + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + pop eax + mov cr0, eax + add esp, 4 ; not for Cr1 + pop eax + mov cr2, eax + pop eax + mov dword [ecx + IA32_TSS._CR3], eax + pop eax + mov cr4, eax + +;; UINT32 EFlags; + pop dword [ecx + IA32_TSS.EFLAGS] + mov ebx, dword [ecx + IA32_TSS.EFLAGS] + btr ebx, 9 ; Do 'cli' + mov dword [ecx + IA32_TSS.EFLAGS], ebx + +;; UINT32 Ldtr, Tr; +;; UINT32 Gdtr[2], Idtr[2]; +;; Best not let anyone mess with these particular registers... + add esp, 24 + +;; UINT32 Eip; + pop dword [ecx + IA32_TSS.EIP] + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; +;; NOTE - modified segment registers could hang the debugger... We +;; could attempt to insulate ourselves against this possibility, +;; but that poses risks as well. +;; + pop eax +o16 mov [ecx + IA32_TSS._GS], ax + pop eax +o16 mov [ecx + IA32_TSS._FS], ax + pop eax +o16 mov [ecx + IA32_TSS._ES], ax + pop eax +o16 mov [ecx + IA32_TSS._DS], ax + pop eax +o16 mov [ecx + IA32_TSS._CS], ax + pop eax +o16 mov [ecx + IA32_TSS._SS], ax + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + pop dword [ecx + IA32_TSS._EDI] + pop dword [ecx + IA32_TSS._ESI] + add esp, 4 ; not for ebp + add esp, 4 ; not for esp + pop dword [ecx + IA32_TSS._EBX] + pop dword [ecx + IA32_TSS._EDX] + pop dword [ecx + IA32_TSS._ECX] + pop dword [ecx + IA32_TSS._EAX] + +; Set single step DB# to allow debugger to able to go back to the EIP +; where the exception is triggered. + +;; Create return context for iretd in stub function + mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack pointer + mov ebx, dword [ecx + IA32_TSS.EIP] + mov [eax - 0xc], ebx ; create EIP in old stack + movzx ebx, word [ecx + IA32_TSS._CS] + mov [eax - 0x8], ebx ; create CS in old stack + mov ebx, dword [ecx + IA32_TSS.EFLAGS] + bts ebx, 8 ; Set TF + mov [eax - 0x4], ebx ; create eflags in old stack + sub eax, 0xc ; minus 12 byte + mov dword [ecx + IA32_TSS._ESP], eax ; Set new stack pointer + +;; Replace the EIP of interrupted task with stub function + mov eax, ASM_PFX(SingleStepStubFunction) + mov dword [ecx + IA32_TSS.EIP], eax + + mov ecx, [ebp - 8] ; Get current TSS base + mov eax, dword [ecx + IA32_TSS._ESP] ; Return current stack top + mov esp, ebp + + ret + +global ASM_PFX(SingleStepStubFunction) +ASM_PFX(SingleStepStubFunction): +; +; we need clean TS bit in CR0 to execute +; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions. +; + clts + iretd + +global ASM_PFX(AsmGetTssTemplateMap) +ASM_PFX(AsmGetTssTemplateMap): + push ebp ; C prolog + mov ebp, esp + pushad + + mov ebx, dword [ebp + 0x8] + mov dword [ebx], ASM_PFX(ExceptionTaskSwtichEntry0) + mov dword [ebx + 0x4], (AsmExceptionEntryEnd - AsmExceptionEntryBegin) / 32 + mov dword [ebx + 0x8], 0 + + popad + pop ebp + ret + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c new file mode 100644 index 000000000..d25664343 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -0,0 +1,262 @@ +/** @file + CPU exception handler library implementation for PEIM module. + +Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "CpuExceptionCommon.h" +#include +#include +#include +#include + +CONST UINTN mDoFarReturnFlag = 0; + +typedef struct { + UINT8 ExceptionStubHeader[HOOKAFTER_STUB_SIZE]; + EXCEPTION_HANDLER_DATA *ExceptionHandlerData; +} EXCEPTION0_STUB_HEADER; + +/** + Get exception handler data pointer from IDT[0]. + + The exception #0 stub header is duplicated in an allocated pool with extra 4-byte/8-byte to store the + exception handler data. The new allocated memory layout follows structure EXCEPTION0_STUB_HEADER. + The code assumes that all processors uses the same exception handler for #0 exception. + + @return pointer to exception handler data. +**/ +EXCEPTION_HANDLER_DATA * +GetExceptionHandlerData ( + VOID + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + EXCEPTION0_STUB_HEADER *Exception0StubHeader; + + AsmReadIdtr (&IdtDescriptor); + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base; + + Exception0StubHeader = (EXCEPTION0_STUB_HEADER *)ArchGetIdtHandler (&IdtTable[0]); + return Exception0StubHeader->ExceptionHandlerData; +} + +/** + Set exception handler data pointer to IDT[0]. + + The exception #0 stub header is duplicated in an allocated pool with extra 4-byte/8-byte to store the + exception handler data. The new allocated memory layout follows structure EXCEPTION0_STUB_HEADER. + The code assumes that all processors uses the same exception handler for #0 exception. + + @param ExceptionHandlerData pointer to exception handler data. +**/ +VOID +SetExceptionHandlerData ( + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + EXCEPTION0_STUB_HEADER *Exception0StubHeader; + IA32_DESCRIPTOR IdtDescriptor; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + // + // Duplicate the exception #0 stub header in pool and cache the ExceptionHandlerData just after the stub header. + // So AP can get the ExceptionHandlerData by reading the IDT[0]. + // + AsmReadIdtr (&IdtDescriptor); + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base; + + Exception0StubHeader = AllocatePool (sizeof (*Exception0StubHeader)); + ASSERT (Exception0StubHeader != NULL); + CopyMem ( + Exception0StubHeader->ExceptionStubHeader, + (VOID *)ArchGetIdtHandler (&IdtTable[0]), + sizeof (Exception0StubHeader->ExceptionStubHeader) + ); + Exception0StubHeader->ExceptionHandlerData = ExceptionHandlerData; + ArchUpdateIdtEntry (&IdtTable[0], (UINTN)Exception0StubHeader->ExceptionStubHeader); +} + +/** + Common exception handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +EFIAPI +CommonExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EXCEPTION_HANDLER_DATA *ExceptionHandlerData; + + ExceptionHandlerData = GetExceptionHandlerData (); + CommonExceptionHandlerWorker (ExceptionType, SystemContext, ExceptionHandlerData); +} + +/** + Initializes all CPU exceptions entries and provides the default exception handlers. + + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to + persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. + Note: Before invoking this API, caller must allocate memory for IDT table and load + IDTR by AsmWriteIdtr(). + + @param[in] VectorInfo Pointer to reserved vector list. + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + with default exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlers ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL + ) +{ + EFI_STATUS Status; + EXCEPTION_HANDLER_DATA *ExceptionHandlerData; + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM); + ASSERT (ReservedVectors != NULL); + + ExceptionHandlerData = AllocatePool (sizeof (EXCEPTION_HANDLER_DATA)); + ASSERT (ExceptionHandlerData != NULL); + ExceptionHandlerData->ReservedVectors = ReservedVectors; + ExceptionHandlerData->ExternalInterruptHandler = NULL; + InitializeSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock); + + Status = InitializeCpuExceptionHandlersWorker (VectorInfo, ExceptionHandlerData); + if (EFI_ERROR (Status)) { + FreePool (ReservedVectors); + FreePool (ExceptionHandlerData); + return Status; + } + + SetExceptionHandlerData (ExceptionHandlerData); + return EFI_SUCCESS; +} + +/** + Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers. + + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to + persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. + + @param[in] VectorInfo Pointer to reserved vector list. + + @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized + with default interrupt/exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuInterruptHandlers ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Registers a function to be called from the processor interrupt handler. + + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the + handler for the processor interrupt or exception type specified by InterruptType is uninstalled. + The installed handler is called once for each processor interrupt or exception. + NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or + InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned. + + @param[in] InterruptType Defines which interrupt or exception to hook. + @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, + or this function is not supported. +**/ +EFI_STATUS +EFIAPI +RegisterCpuInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Initializes all CPU exceptions entries with optional extra initializations. + + By default, this method should include all functionalities implemented by + InitializeCpuExceptionHandlers(), plus extra initialization works, if any. + This could be done by calling InitializeCpuExceptionHandlers() directly + in this method besides the extra works. + + InitData is optional and its use and content are processor arch dependent. + The typical usage of it is to convey resources which have to be reserved + elsewhere and are necessary for the extra initializations of exception. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in] InitData Pointer to data optional for extra initializations + of exception. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized. + @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid + content. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlersEx ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL + ) +{ + EFI_STATUS Status; + + // + // To avoid repeat initialization of default handlers, the caller should pass + // an extended init data with InitDefaultHandlers set to FALSE. There's no + // need to call this method to just initialize default handlers. Call non-ex + // version instead; or this method must be implemented as a simple wrapper of + // non-ex version of it, if this version has to be called. + // + if (InitData == NULL || InitData->Ia32.InitDefaultHandlers) { + Status = InitializeCpuExceptionHandlers (VectorInfo); + } else { + Status = EFI_SUCCESS; + } + + if (!EFI_ERROR (Status)) { + // + // Initializing stack switch is only necessary for Stack Guard functionality. + // + if (PcdGetBool (PcdCpuStackGuard) && InitData != NULL) { + Status = ArchSetupExceptionStack (InitData); + } + } + + return Status; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf new file mode 100644 index 000000000..093374944 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -0,0 +1,58 @@ +## @file +# CPU Exception Handler library instance for PEI module. +# +# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiCpuExceptionHandlerLib + MODULE_UNI_FILE = PeiCpuExceptionHandlerLib.uni + FILE_GUID = 980DDA67-44A6-4897-99E6-275290B71F9E + MODULE_TYPE = PEIM + VERSION_STRING = 1.1 + LIBRARY_CLASS = CpuExceptionHandlerLib|PEI_CORE PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.Ia32] + Ia32/ExceptionHandlerAsm.nasm + Ia32/ExceptionTssEntryAsm.nasm + Ia32/ArchExceptionHandler.c + Ia32/ArchInterruptDefs.h + +[Sources.X64] + X64/Xcode5ExceptionHandlerAsm.nasm + X64/ArchExceptionHandler.c + X64/ArchInterruptDefs.h + +[Sources.common] + CpuExceptionCommon.h + CpuExceptionCommon.c + PeiCpuException.c + PeiDxeSmmCpuException.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + SerialPortLib + PrintLib + LocalApicLib + PeCoffGetEntryPointLib + HobLib + MemoryAllocationLib + SynchronizationLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard # CONSUMES + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni new file mode 100644 index 000000000..300356c8d --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Exception Handler library instance for PEI module. +// +// CPU Exception Handler library instance for PEI module. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Handler library instance for PEI module." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Handler library instance for PEI module." + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c new file mode 100644 index 000000000..6a2670d55 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c @@ -0,0 +1,296 @@ +/** @file + CPU Exception Library provides PEI/DXE/SMM CPU common exception handler. + +Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuExceptionCommon.h" +#include + +/** + Internal worker function for common exception handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +CommonExceptionHandlerWorker ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + EXCEPTION_HANDLER_CONTEXT *ExceptionHandlerContext; + RESERVED_VECTORS_DATA *ReservedVectors; + EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler; + + ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32); + ReservedVectors = ExceptionHandlerData->ReservedVectors; + ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler; + + switch (ReservedVectors[ExceptionType].Attribute) { + case EFI_VECTOR_HANDOFF_HOOK_BEFORE: + // + // The new exception handler registered by RegisterCpuInterruptHandler() is executed BEFORE original handler. + // Save the original handler to stack so the assembly code can jump to it instead of returning from handler. + // + ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; + ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler; + break; + case EFI_VECTOR_HANDOFF_HOOK_AFTER: + while (TRUE) { + // + // If spin-lock can be acquired, it's the first time entering here. + // + if (AcquireSpinLockOrFail (&ReservedVectors[ExceptionType].SpinLock)) { + // + // The new exception handler registered by RegisterCpuInterruptHandler() is executed AFTER original handler. + // Save the original handler to stack but skip running the new handler so the original handler is executed + // firstly. + // + ReservedVectors[ExceptionType].ApicId = GetApicId (); + ArchSaveExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData); + ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; + ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler; + return; + } + // + // If spin-lock cannot be acquired, it's the second time entering here. + // 'break' instead of 'return' is used so the new exception handler can be executed. + // + if (ReservedVectors[ExceptionType].ApicId == GetApicId ()) { + // + // Old IDT handler has been executed, then restore CPU exception content to + // run new exception handler. + // + ArchRestoreExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData); + // + // Release spin lock for ApicId + // + ReleaseSpinLock (&ReservedVectors[ExceptionType].SpinLock); + break; + } + CpuPause (); + } + break; + case 0xffffffff: + break; + default: + // + // It should never reach here + // + CpuDeadLoop (); + break; + } + + if (ExternalInterruptHandler != NULL && + ExternalInterruptHandler[ExceptionType] != NULL) { + (ExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext); + } else if (ExceptionType < CPU_EXCEPTION_NUM) { + // + // Get Spinlock to display CPU information + // + while (!AcquireSpinLockOrFail (&ExceptionHandlerData->DisplayMessageSpinLock)) { + CpuPause (); + } + // + // Initialize the serial port before dumping. + // + SerialPortInitialize (); + // + // Display ExceptionType, CPU information and Image information + // + DumpImageAndCpuContent (ExceptionType, SystemContext); + // + // Release Spinlock of output message + // + ReleaseSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock); + // + // Enter a dead loop if needn't to execute old IDT handler further + // + if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) { + CpuDeadLoop (); + } + } +} + +/** + Internal worker function to update IDT entries accordling to vector attributes. + + @param[in] IdtTable Pointer to IDT table. + @param[in] TemplateMap Pointer to a buffer where the address map is + returned. + @param[in] ExceptionHandlerData Pointer to exception handler data. + +**/ +VOID +UpdateIdtTable ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, + IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + UINT16 CodeSegment; + UINTN Index; + UINTN InterruptHandler; + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + for (Index = 0; Index < ExceptionHandlerData->IdtEntryCount; Index ++) { + IdtTable[Index].Bits.Selector = CodeSegment; + // + // Check reserved vectors attributes + // + switch (ReservedVectors[Index].Attribute) { + case EFI_VECTOR_HANDOFF_DO_NOT_HOOK: + // + // Keep original IDT entry + // + continue; + case EFI_VECTOR_HANDOFF_HOOK_AFTER: + InitializeSpinLock (&ReservedVectors[Index].SpinLock); + CopyMem ( + (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode, + (VOID *) TemplateMap->HookAfterStubHeaderStart, + TemplateMap->ExceptionStubHeaderSize + ); + AsmVectorNumFixup ( + (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode, + (UINT8) Index, + (VOID *) TemplateMap->HookAfterStubHeaderStart + ); + // + // Go on the following code + // + case EFI_VECTOR_HANDOFF_HOOK_BEFORE: + // + // Save original IDT handler address + // + ReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]); + // + // Go on the following code + // + default: + // + // Update new IDT entry + // + InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize; + ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler); + break; + } + } +} + +/** + Internal worker function to initialize exception handler. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in, out] ExceptionHandlerData Pointer to exception handler data. + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + with default exception handlers. + @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. + @retval EFI_UNSUPPORTED This function is not supported. + +**/ +EFI_STATUS +InitializeCpuExceptionHandlersWorker ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN OUT EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + EFI_STATUS Status; + IA32_DESCRIPTOR IdtDescriptor; + UINTN IdtEntryCount; + EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + SetMem ((VOID *) ReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff); + if (VectorInfo != NULL) { + Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectors, CPU_EXCEPTION_NUM); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Read IDT descriptor and calculate IDT size + // + AsmReadIdtr (&IdtDescriptor); + IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); + if (IdtEntryCount > CPU_EXCEPTION_NUM) { + // + // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most + // + IdtEntryCount = CPU_EXCEPTION_NUM; + } + + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; + AsmGetTemplateAddressMap (&TemplateMap); + ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); + + ExceptionHandlerData->IdtEntryCount = IdtEntryCount; + UpdateIdtTable (IdtTable, &TemplateMap, ExceptionHandlerData); + + return EFI_SUCCESS; +} + +/** + Registers a function to be called from the processor interrupt handler. + + @param[in] InterruptType Defines which interrupt or exception to hook. + @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the handler + will be uninstalled + @param[in] ExceptionHandlerData Pointer to exception handler data. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, + or this function is not supported. +**/ +EFI_STATUS +RegisterCpuInterruptHandlerWorker ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + UINTN EnabledInterruptNum; + RESERVED_VECTORS_DATA *ReservedVectors; + EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler; + + EnabledInterruptNum = ExceptionHandlerData->IdtEntryCount; + ReservedVectors = ExceptionHandlerData->ReservedVectors; + ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler; + + if (InterruptType < 0 || InterruptType >= (EFI_EXCEPTION_TYPE)EnabledInterruptNum || + ReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) { + return EFI_UNSUPPORTED; + } + + if (InterruptHandler == NULL && ExternalInterruptHandler[InterruptType] == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (InterruptHandler != NULL && ExternalInterruptHandler[InterruptType] != NULL) { + return EFI_ALREADY_STARTED; + } + + ExternalInterruptHandler[InterruptType] = InterruptHandler; + return EFI_SUCCESS; +} + diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c similarity index 73% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c index 1660a3388..20148db74 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c @@ -1,24 +1,14 @@ /** @file CPU exception handler library implemenation for SEC/PEIM modules. -Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that accompanies this distribution. -The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include "CpuExceptionCommon.h" -// -// Image Aglinment size for SEC/PEI phase -// -CONST UINTN mImageAlignSize = 4; CONST UINTN mDoFarReturnFlag = 0; /** @@ -30,15 +20,19 @@ CONST UINTN mDoFarReturnFlag = 0; VOID EFIAPI CommonExceptionHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext ) { + // + // Initialize the serial port before dumping. + // + SerialPortInitialize (); // // Display ExceptionType, CPU information and Image information - // - DumpCpuContent (ExceptionType, SystemContext); - + // + DumpImageAndCpuContent (ExceptionType, SystemContext); + // // Enter a dead loop. // @@ -47,17 +41,17 @@ CommonExceptionHandler ( /** Initializes all CPU exceptions entries and provides the default exception handlers. - + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. - Note: Before invoking this API, caller must allocate memory for IDT table and load + Note: Before invoking this API, caller must allocate memory for IDT table and load IDTR by AsmWriteIdtr(). @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized with default exception handlers. @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. @retval EFI_UNSUPPORTED This function is not supported. @@ -69,7 +63,7 @@ InitializeCpuExceptionHandlers ( IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; RESERVED_VECTORS_DATA ReservedVectorData[CPU_EXCEPTION_NUM]; IA32_DESCRIPTOR IdtDescriptor; UINTN IdtEntryCount; @@ -80,9 +74,9 @@ InitializeCpuExceptionHandlers ( UINTN InterruptHandler; if (VectorInfo != NULL) { - SetMem((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff); + SetMem ((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff); Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, CPU_EXCEPTION_NUM); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } } @@ -126,15 +120,15 @@ InitializeCpuExceptionHandlers ( /** Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers. - + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized + + @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized with default interrupt/exception handlers. @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. @retval EFI_UNSUPPORTED This function is not supported. @@ -152,9 +146,9 @@ InitializeCpuInterruptHandlers ( /** Registers a function to be called from the processor interrupt handler. - This function registers and enables the handler specified by InterruptHandler for a processor - interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the - handler for the processor interrupt or exception type specified by InterruptType is uninstalled. + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the + handler for the processor interrupt or exception type specified by InterruptType is uninstalled. The installed handler is called once for each processor interrupt or exception. NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned. @@ -181,3 +175,35 @@ RegisterCpuInterruptHandler ( { return EFI_UNSUPPORTED; } + +/** + Initializes all CPU exceptions entries with optional extra initializations. + + By default, this method should include all functionalities implemented by + InitializeCpuExceptionHandlers(), plus extra initialization works, if any. + This could be done by calling InitializeCpuExceptionHandlers() directly + in this method besides the extra works. + + InitData is optional and its use and content are processor arch dependent. + The typical usage of it is to convey resources which have to be reserved + elsewhere and are necessary for the extra initializations of exception. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in] InitData Pointer to data optional for extra initializations + of exception. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized. + @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid + content. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlersEx ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL + ) +{ + return InitializeCpuExceptionHandlers (VectorInfo); +} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf similarity index 56% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index dfd756289..6d25cafe2 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -1,15 +1,9 @@ ## @file # CPU Exception Handler library instance for SEC/PEI modules. # -# Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# +# Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# ## [Defines] @@ -18,7 +12,7 @@ MODULE_UNI_FILE = SecPeiCpuExceptionHandlerLib.uni FILE_GUID = CA4BBC99-DFC6-4234-B553-8B6586B7B113 MODULE_TYPE = PEIM - VERSION_STRING = 1.0 + VERSION_STRING = 1.1 LIBRARY_CLASS = CpuExceptionHandlerLib|SEC PEI_CORE PEIM # @@ -28,14 +22,13 @@ # [Sources.Ia32] - Ia32/ExceptionHandlerAsm.asm - Ia32/ExceptionHandlerAsm.S |GCC + Ia32/ExceptionHandlerAsm.nasm + Ia32/ExceptionTssEntryAsm.nasm Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] - X64/ExceptionHandlerAsm.asm - X64/ExceptionHandlerAsm.S |GCC + X64/ExceptionHandlerAsm.nasm X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h @@ -47,7 +40,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] BaseLib diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni new file mode 100644 index 000000000..72300e519 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Exception Handler library instance for SEC/PEI modules. +// +// CPU Exception Handler library instance for SEC/PEI modules. +// +// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Handler library instance for SEC/PEI modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Handler library instance for SEC/PEI modules." + diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf similarity index 56% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index 37031204c..2ffbbccc3 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -1,15 +1,9 @@ ## @file # CPU Exception Handler library instance for SMM modules. # -# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# +# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# ## [Defines] @@ -18,7 +12,7 @@ MODULE_UNI_FILE = SmmCpuExceptionHandlerLib.uni FILE_GUID = 8D2C439B-3981-42ff-9CE5-1B50ECA502D6 MODULE_TYPE = DXE_SMM_DRIVER - VERSION_STRING = 1.0 + VERSION_STRING = 1.1 LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_SMM_DRIVER # @@ -28,27 +22,26 @@ # [Sources.Ia32] - Ia32/ExceptionHandlerAsm.asm - Ia32/ExceptionHandlerAsm.S |GCC + Ia32/ExceptionHandlerAsm.nasm + Ia32/ExceptionTssEntryAsm.nasm Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] - X64/ExceptionHandlerAsm.asm - X64/ExceptionHandlerAsm.S |GCC + X64/Xcode5ExceptionHandlerAsm.nasm X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h [Sources.common] CpuExceptionCommon.h CpuExceptionCommon.c - DxeSmmCpuException.c + PeiDxeSmmCpuException.c SmmException.c [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - CloverEFI/UefiCpuPkg/UefiCpuPkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] BaseLib diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni new file mode 100644 index 000000000..2ec2f7933 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni @@ -0,0 +1,16 @@ +// /** @file +// CPU Exception Handler library instance for SMM modules. +// +// CPU Exception Handler library instance for SMM modules. +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Handler library instance for SMM modules." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Handler library instance for SMM modules." + diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c similarity index 55% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c index 40f125026..e7977d49b 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c @@ -1,33 +1,51 @@ /** @file - CPU exception handler library implemenation for SMM modules. + CPU exception handler library implementation for SMM modules. - Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include "CpuExceptionCommon.h" -CONST UINTN mDoFarReturnFlag = 1; +CONST UINTN mDoFarReturnFlag = 1; + +// +// Spin lock for CPU information display +// +SPIN_LOCK mDisplayMessageSpinLock; + +RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM]; +EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM]; +EXCEPTION_HANDLER_DATA mExceptionHandlerData; +/** + Common exception handler. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +EFIAPI +CommonExceptionHandler ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + CommonExceptionHandlerWorker (ExceptionType, SystemContext, &mExceptionHandlerData); +} /** Initializes all CPU exceptions entries and provides the default exception handlers. - + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized + + @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized with default exception handlers. @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. @retval EFI_UNSUPPORTED This function is not supported. @@ -39,20 +57,23 @@ InitializeCpuExceptionHandlers ( IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL ) { - return InitializeCpuExceptionHandlersWorker (VectorInfo); + mExceptionHandlerData.ReservedVectors = mReservedVectorsData; + mExceptionHandlerData.ExternalInterruptHandler = mExternalInterruptHandlerTable; + InitializeSpinLock (&mExceptionHandlerData.DisplayMessageSpinLock); + return InitializeCpuExceptionHandlersWorker (VectorInfo, &mExceptionHandlerData); } /** Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers. - + Caller should try to get an array of interrupt and/or exception vectors that are in use and need to persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification. - If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. + If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly. @param[in] VectorInfo Pointer to reserved vector list. - - @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized + + @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized with default interrupt/exception handlers. @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. @retval EFI_UNSUPPORTED This function is not supported. @@ -70,9 +91,9 @@ InitializeCpuInterruptHandlers ( /** Registers a function to be called from the processor interrupt handler. - This function registers and enables the handler specified by InterruptHandler for a processor - interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the - handler for the processor interrupt or exception type specified by InterruptType is uninstalled. + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the + handler for the processor interrupt or exception type specified by InterruptType is uninstalled. The installed handler is called once for each processor interrupt or exception. NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned. @@ -97,5 +118,37 @@ RegisterCpuInterruptHandler ( IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler ) { - return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler); -} \ No newline at end of file + return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler, &mExceptionHandlerData); +} + +/** + Initializes all CPU exceptions entries with optional extra initializations. + + By default, this method should include all functionalities implemented by + InitializeCpuExceptionHandlers(), plus extra initialization works, if any. + This could be done by calling InitializeCpuExceptionHandlers() directly + in this method besides the extra works. + + InitData is optional and its use and content are processor arch dependent. + The typical usage of it is to convey resources which have to be reserved + elsewhere and are necessary for the extra initializations of exception. + + @param[in] VectorInfo Pointer to reserved vector list. + @param[in] InitData Pointer to data optional for extra initializations + of exception. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized. + @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid + content. + +**/ +EFI_STATUS +EFIAPI +InitializeCpuExceptionHandlersEx ( + IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, + IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL + ) +{ + return InitializeCpuExceptionHandlers (VectorInfo); +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c new file mode 100644 index 000000000..894c1cfb7 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -0,0 +1,427 @@ +/** @file + x64 CPU Exception Handler. + + Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuExceptionCommon.h" + +/** + Return address map of exception handler template so that C code can generate + exception tables. + + @param IdtEntry Pointer to IDT entry to be updated. + @param InterruptHandler IDT handler value. +**/ +VOID +ArchUpdateIdtEntry ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry, + IN UINTN InterruptHandler + ) +{ + IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); + IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Read IDT handler value from IDT entry. + + @param IdtEntry Pointer to IDT entry to be read. + +**/ +UINTN +ArchGetIdtHandler ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry + ) +{ + return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh) << 16) + + (((UINTN) IdtEntry->Bits.OffsetUpper) << 32); +} + +/** + Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchSaveExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + IA32_EFLAGS32 Eflags; + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + // + // Save Exception context in global variable in first entry of the exception handler. + // So when original exception handler returns to the new exception handler (second entry), + // the Eflags/Cs/Eip/ExceptionData can be used. + // + ReservedVectors[ExceptionType].OldSs = SystemContext.SystemContextX64->Ss; + ReservedVectors[ExceptionType].OldSp = SystemContext.SystemContextX64->Rsp; + ReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextX64->Rflags; + ReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextX64->Cs; + ReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextX64->Rip; + ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData; + // + // Clear IF flag to avoid old IDT handler enable interrupt by IRET + // + Eflags.UintN = SystemContext.SystemContextX64->Rflags; + Eflags.Bits.IF = 0; + SystemContext.SystemContextX64->Rflags = Eflags.UintN; + // + // Modify the EIP in stack, then old IDT handler will return to HookAfterStubBegin. + // + SystemContext.SystemContextX64->Rip = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode; +} + +/** + Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. + + @param[in] ExceptionType Exception type. + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. + @param[in] ExceptionHandlerData Pointer to exception handler data. +**/ +VOID +ArchRestoreExceptionContext ( + IN UINTN ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext, + IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData + ) +{ + RESERVED_VECTORS_DATA *ReservedVectors; + + ReservedVectors = ExceptionHandlerData->ReservedVectors; + SystemContext.SystemContextX64->Ss = ReservedVectors[ExceptionType].OldSs; + SystemContext.SystemContextX64->Rsp = ReservedVectors[ExceptionType].OldSp; + SystemContext.SystemContextX64->Rflags = ReservedVectors[ExceptionType].OldFlags; + SystemContext.SystemContextX64->Cs = ReservedVectors[ExceptionType].OldCs; + SystemContext.SystemContextX64->Rip = ReservedVectors[ExceptionType].OldIp; + SystemContext.SystemContextX64->ExceptionData = ReservedVectors[ExceptionType].ExceptionData; +} + +/** + Setup separate stack for given exceptions. + + @param[in] StackSwitchData Pointer to data required for setuping up + stack switch. + + @retval EFI_SUCCESS The exceptions have been successfully + initialized with new stack. + @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content. + +**/ +EFI_STATUS +ArchSetupExceptionStack ( + IN CPU_EXCEPTION_INIT_DATA *StackSwitchData + ) +{ + IA32_DESCRIPTOR Gdtr; + IA32_DESCRIPTOR Idtr; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; + IA32_TSS_DESCRIPTOR *TssDesc; + IA32_TASK_STATE_SEGMENT *Tss; + UINTN StackTop; + UINTN Index; + UINTN Vector; + UINTN TssBase; + UINTN GdtSize; + + if (StackSwitchData == NULL || + StackSwitchData->Ia32.Revision != CPU_EXCEPTION_INIT_DATA_REV || + StackSwitchData->X64.KnownGoodStackTop == 0 || + StackSwitchData->X64.KnownGoodStackSize == 0 || + StackSwitchData->X64.StackSwitchExceptions == NULL || + StackSwitchData->X64.StackSwitchExceptionNumber == 0 || + StackSwitchData->X64.StackSwitchExceptionNumber > CPU_EXCEPTION_NUM || + StackSwitchData->X64.GdtTable == NULL || + StackSwitchData->X64.IdtTable == NULL || + StackSwitchData->X64.ExceptionTssDesc == NULL || + StackSwitchData->X64.ExceptionTss == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // The caller is responsible for that the GDT table, no matter the existing + // one or newly allocated, has enough space to hold descriptors for exception + // task-state segments. + // + if (((UINTN)StackSwitchData->X64.GdtTable & (IA32_GDT_ALIGNMENT - 1)) != 0) { + return EFI_INVALID_PARAMETER; + } + + if ((UINTN)StackSwitchData->X64.ExceptionTssDesc < (UINTN)(StackSwitchData->X64.GdtTable)) { + return EFI_INVALID_PARAMETER; + } + + if (((UINTN)StackSwitchData->X64.ExceptionTssDesc + StackSwitchData->X64.ExceptionTssDescSize) > + ((UINTN)(StackSwitchData->X64.GdtTable) + StackSwitchData->X64.GdtTableSize)) { + return EFI_INVALID_PARAMETER; + } + + // + // One task gate descriptor and one task-state segment are needed. + // + if (StackSwitchData->X64.ExceptionTssDescSize < sizeof (IA32_TSS_DESCRIPTOR)) { + return EFI_INVALID_PARAMETER; + } + if (StackSwitchData->X64.ExceptionTssSize < sizeof (IA32_TASK_STATE_SEGMENT)) { + return EFI_INVALID_PARAMETER; + } + + // + // Interrupt stack table supports only 7 vectors. + // + TssDesc = StackSwitchData->X64.ExceptionTssDesc; + Tss = StackSwitchData->X64.ExceptionTss; + if (StackSwitchData->X64.StackSwitchExceptionNumber > ARRAY_SIZE (Tss->IST)) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize new GDT table and/or IDT table, if any + // + AsmReadIdtr (&Idtr); + AsmReadGdtr (&Gdtr); + + GdtSize = (UINTN)TssDesc + sizeof (IA32_TSS_DESCRIPTOR) - + (UINTN)(StackSwitchData->X64.GdtTable); + if ((UINTN)StackSwitchData->X64.GdtTable != Gdtr.Base) { + CopyMem (StackSwitchData->X64.GdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1); + Gdtr.Base = (UINTN)StackSwitchData->X64.GdtTable; + Gdtr.Limit = (UINT16)GdtSize - 1; + } + + if ((UINTN)StackSwitchData->X64.IdtTable != Idtr.Base) { + Idtr.Base = (UINTN)StackSwitchData->X64.IdtTable; + } + if (StackSwitchData->X64.IdtTableSize > 0) { + Idtr.Limit = (UINT16)(StackSwitchData->X64.IdtTableSize - 1); + } + + // + // Fixup current task descriptor. Task-state segment for current task will + // be filled by processor during task switching. + // + TssBase = (UINTN)Tss; + + TssDesc->Uint128.Uint64 = 0; + TssDesc->Uint128.Uint64_1= 0; + TssDesc->Bits.LimitLow = sizeof(IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.BaseLow = (UINT16)TssBase; + TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); + TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.P = 1; + TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); + TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32); + + // + // Fixup exception task descriptor and task-state segment + // + ZeroMem (Tss, sizeof (*Tss)); + StackTop = StackSwitchData->X64.KnownGoodStackTop - CPU_STACK_ALIGNMENT; + StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + IdtTable = StackSwitchData->X64.IdtTable; + for (Index = 0; Index < StackSwitchData->X64.StackSwitchExceptionNumber; ++Index) { + // + // Fixup IST + // + Tss->IST[Index] = StackTop; + StackTop -= StackSwitchData->X64.KnownGoodStackSize; + + // + // Set the IST field to enable corresponding IST + // + Vector = StackSwitchData->X64.StackSwitchExceptions[Index]; + if (Vector >= CPU_EXCEPTION_NUM || + Vector >= (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)) { + continue; + } + IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1); + } + + // + // Publish GDT + // + AsmWriteGdtr (&Gdtr); + + // + // Load current task + // + AsmWriteTr ((UINT16)((UINTN)StackSwitchData->X64.ExceptionTssDesc - Gdtr.Base)); + + // + // Publish IDT + // + AsmWriteIdtr (&Idtr); + + return EFI_SUCCESS; +} + +/** + Display CPU information. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +EFIAPI +DumpCpuContext ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + InternalPrintMessage ( + "!!!! X64 Exception Type - %02x(%a) CPU Apic ID - %08x !!!!\n", + ExceptionType, + GetExceptionNameStr (ExceptionType), + GetApicId () + ); + if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) { + InternalPrintMessage ( + "ExceptionData - %016lx", + SystemContext.SystemContextX64->ExceptionData + ); + if (ExceptionType == EXCEPT_IA32_PAGE_FAULT) { + InternalPrintMessage ( + " I:%x R:%x U:%x W:%x P:%x PK:%x SS:%x SGX:%x", + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_RSVD) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_US) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_WR) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_P) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_PK) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_SS) != 0, + (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_SGX) != 0 + ); + } + InternalPrintMessage ("\n"); + } + InternalPrintMessage ( + "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n", + SystemContext.SystemContextX64->Rip, + SystemContext.SystemContextX64->Cs, + SystemContext.SystemContextX64->Rflags + ); + InternalPrintMessage ( + "RAX - %016lx, RCX - %016lx, RDX - %016lx\n", + SystemContext.SystemContextX64->Rax, + SystemContext.SystemContextX64->Rcx, + SystemContext.SystemContextX64->Rdx + ); + InternalPrintMessage ( + "RBX - %016lx, RSP - %016lx, RBP - %016lx\n", + SystemContext.SystemContextX64->Rbx, + SystemContext.SystemContextX64->Rsp, + SystemContext.SystemContextX64->Rbp + ); + InternalPrintMessage ( + "RSI - %016lx, RDI - %016lx\n", + SystemContext.SystemContextX64->Rsi, + SystemContext.SystemContextX64->Rdi + ); + InternalPrintMessage ( + "R8 - %016lx, R9 - %016lx, R10 - %016lx\n", + SystemContext.SystemContextX64->R8, + SystemContext.SystemContextX64->R9, + SystemContext.SystemContextX64->R10 + ); + InternalPrintMessage ( + "R11 - %016lx, R12 - %016lx, R13 - %016lx\n", + SystemContext.SystemContextX64->R11, + SystemContext.SystemContextX64->R12, + SystemContext.SystemContextX64->R13 + ); + InternalPrintMessage ( + "R14 - %016lx, R15 - %016lx\n", + SystemContext.SystemContextX64->R14, + SystemContext.SystemContextX64->R15 + ); + InternalPrintMessage ( + "DS - %016lx, ES - %016lx, FS - %016lx\n", + SystemContext.SystemContextX64->Ds, + SystemContext.SystemContextX64->Es, + SystemContext.SystemContextX64->Fs + ); + InternalPrintMessage ( + "GS - %016lx, SS - %016lx\n", + SystemContext.SystemContextX64->Gs, + SystemContext.SystemContextX64->Ss + ); + InternalPrintMessage ( + "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n", + SystemContext.SystemContextX64->Cr0, + SystemContext.SystemContextX64->Cr2, + SystemContext.SystemContextX64->Cr3 + ); + InternalPrintMessage ( + "CR4 - %016lx, CR8 - %016lx\n", + SystemContext.SystemContextX64->Cr4, + SystemContext.SystemContextX64->Cr8 + ); + InternalPrintMessage ( + "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n", + SystemContext.SystemContextX64->Dr0, + SystemContext.SystemContextX64->Dr1, + SystemContext.SystemContextX64->Dr2 + ); + InternalPrintMessage ( + "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n", + SystemContext.SystemContextX64->Dr3, + SystemContext.SystemContextX64->Dr6, + SystemContext.SystemContextX64->Dr7 + ); + InternalPrintMessage ( + "GDTR - %016lx %016lx, LDTR - %016lx\n", + SystemContext.SystemContextX64->Gdtr[0], + SystemContext.SystemContextX64->Gdtr[1], + SystemContext.SystemContextX64->Ldtr + ); + InternalPrintMessage ( + "IDTR - %016lx %016lx, TR - %016lx\n", + SystemContext.SystemContextX64->Idtr[0], + SystemContext.SystemContextX64->Idtr[1], + SystemContext.SystemContextX64->Tr + ); + InternalPrintMessage ( + "FXSAVE_STATE - %016lx\n", + &SystemContext.SystemContextX64->FxSaveState + ); +} + +/** + Display CPU information. + + @param ExceptionType Exception type. + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +VOID +DumpImageAndCpuContent ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + DumpCpuContext (ExceptionType, SystemContext); + // + // Dump module image base and module entry point by RIP + // + if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) && + ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0)) { + // + // The RIP in SystemContext could not be used + // if it is page fault with I/D set. + // + DumpModuleImageInfo ((*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp)); + } else { + DumpModuleImageInfo (SystemContext.SystemContextX64->Rip); + } +} diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h similarity index 66% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 906480134..c3a07862e 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -2,13 +2,7 @@ X64 arch definition for CPU Exception Handler Library. Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -43,4 +37,7 @@ typedef struct { UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE]; } RESERVED_VECTORS_DATA; +#define CPU_TSS_DESC_SIZE sizeof (IA32_TSS_DESCRIPTOR) +#define CPU_TSS_SIZE sizeof (IA32_TASK_STATE_SEGMENT) + #endif diff --git a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm similarity index 67% rename from CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm rename to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index dfb66e2bc..3814f9de3 100644 --- a/CloverEFI/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -1,12 +1,6 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php. -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: ; @@ -23,46 +17,47 @@ ; ; CommonExceptionHandler() ; -externdef CommonExceptionHandler:near -EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions -EXTRN mDoFarReturnFlag:QWORD ; Do far return flag +extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions +extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag +extern ASM_PFX(CommonExceptionHandler) -data SEGMENT +SECTION .data -.code +DEFAULT REL +SECTION .text ALIGN 8 AsmIdtVectorBegin: -REPEAT 32 - db 6ah ; push #VectorNum +%rep 32 + db 0x6a ; push #VectorNum db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum push rax - mov rax, CommonInterruptEntry + mov rax, ASM_PFX(CommonInterruptEntry) jmp rax -ENDM +%endrep AsmIdtVectorEnd: HookAfterStubHeaderBegin: - db 6ah ; push + db 0x6a ; push @VectorNum: - db 0 ; 0 will be fixed + db 0 ; 0 will be fixed push rax mov rax, HookAfterStubHeaderEnd jmp rax HookAfterStubHeaderEnd: mov rax, rsp - and sp, 0fff0h ; make sure 16-byte aligned for exception context - sub rsp, 18h ; reserve room for filling exception data later + and sp, 0xfff0 ; make sure 16-byte aligned for exception context + sub rsp, 0x18 ; reserve room for filling exception data later push rcx mov rcx, [rax + 8] - bt mErrorCodeFlag, ecx - jnc @F - push [rsp] ; push additional rcx to make stack alignment -@@: + bt [ASM_PFX(mErrorCodeFlag)], ecx + jnc .0 + push qword [rsp] ; push additional rcx to make stack alignment +.0: xchg rcx, [rsp] ; restore rcx, save Exception Number in stack - push [rax] ; push rax into stack to keep code consistence + push qword [rax] ; push rax into stack to keep code consistence ;---------------------------------------; ; CommonInterruptEntry ; @@ -89,7 +84,8 @@ HookAfterStubHeaderEnd: ; + RBP + ; +---------------------+ <-- RBP, 16-byte aligned ; The follow algorithm is used for the common interrupt routine. -CommonInterruptEntry PROC PUBLIC +global ASM_PFX(CommonInterruptEntry) +ASM_PFX(CommonInterruptEntry): cli pop rax ; @@ -97,11 +93,11 @@ CommonInterruptEntry PROC PUBLIC ; IF flag automatically cleared at the entry point ; xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx - and rcx, 0FFh + and rcx, 0xFF cmp ecx, 32 ; Intel reserved vector for exceptions? jae NoErrorCode - bt mErrorCodeFlag, ecx - jc @F + bt [ASM_PFX(mErrorCodeFlag)], ecx + jc HasErrorCode NoErrorCode: @@ -109,9 +105,9 @@ NoErrorCode: ; Push a dummy error code on the stack ; to maintain coherent stack map ; - push [rsp] - mov qword ptr [rsp + 8], 0 -@@: + push qword [rsp] + mov qword [rsp + 8], 0 +HasErrorCode: push rbp mov rbp, rsp push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler @@ -138,7 +134,6 @@ NoErrorCode: ; +---------------------+ <-- RBP, 16-byte aligned ; - ; ; Since here the stack pointer is 16-byte aligned, so ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 @@ -156,18 +151,18 @@ NoErrorCode: push r9 push r8 push rax - push qword ptr [rbp + 8] ; RCX + push qword [rbp + 8] ; RCX push rdx push rbx - push qword ptr [rbp + 48] ; RSP - push qword ptr [rbp] ; RBP + push qword [rbp + 48] ; RSP + push qword [rbp] ; RBP push rsi push rdi ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzx rax, word ptr [rbp + 56] + movzx rax, word [rbp + 56] push rax ; for ss - movzx rax, word ptr [rbp + 32] + movzx rax, word [rbp + 32] push rax ; for cs mov rax, ds push rax @@ -181,24 +176,26 @@ NoErrorCode: mov [rbp + 8], rcx ; save vector number ;; UINT64 Rip; - push qword ptr [rbp + 24] + push qword [rbp + 24] ;; UINT64 Gdtr[2], Idtr[2]; xor rax, rax push rax push rax sidt [rsp] - xchg rax, [rsp + 2] - xchg rax, [rsp] - xchg rax, [rsp + 8] + mov bx, word [rsp] + mov rax, qword [rsp + 2] + mov qword [rsp], rax + mov word [rsp + 8], bx xor rax, rax push rax push rax sgdt [rsp] - xchg rax, [rsp + 2] - xchg rax, [rsp] - xchg rax, [rsp + 8] + mov bx, word [rsp] + mov rax, qword [rsp + 2] + mov qword [rsp], rax + mov word [rsp + 8], bx ;; UINT64 Ldtr, Tr; xor rax, rax @@ -208,13 +205,13 @@ NoErrorCode: push rax ;; UINT64 RFlags; - push qword ptr [rbp + 40] + push qword [rbp + 40] ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; mov rax, cr8 push rax mov rax, cr4 - or rax, 208h + or rax, 0x208 mov cr4, rax push rax mov rax, cr3 @@ -243,13 +240,13 @@ NoErrorCode: ;; FX_SAVE_STATE_X64 FxSaveState; sub rsp, 512 mov rdi, rsp - db 0fh, 0aeh, 07h ;fxsave [rdi] + db 0xf, 0xae, 0x7 ;fxsave [rdi] ;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear cld ;; UINT32 ExceptionData; - push qword ptr [rbp + 16] + push qword [rbp + 16] ;; Prepare parameter and call mov rcx, [rbp + 8] @@ -259,7 +256,7 @@ NoErrorCode: ; and make sure RSP is 16-byte aligned ; sub rsp, 4 * 8 + 8 - mov rax, CommonExceptionHandler + mov rax, ASM_PFX(CommonExceptionHandler) call rax add rsp, 4 * 8 + 8 @@ -270,7 +267,7 @@ NoErrorCode: ;; FX_SAVE_STATE_X64 FxSaveState; mov rsi, rsp - db 0fh, 0aeh, 0Eh ; fxrstor [rsi] + db 0xf, 0xae, 0xE ; fxrstor [rsi] add rsp, 512 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; @@ -292,7 +289,7 @@ NoErrorCode: mov cr8, rax ;; UINT64 RFlags; - pop qword ptr [rbp + 40] + pop qword [rbp + 40] ;; UINT64 Ldtr, Tr; ;; UINT64 Gdtr[2], Idtr[2]; @@ -300,7 +297,7 @@ NoErrorCode: add rsp, 48 ;; UINT64 Rip; - pop qword ptr [rbp + 24] + pop qword [rbp + 24] ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; pop rax @@ -312,15 +309,15 @@ NoErrorCode: mov es, rax pop rax mov ds, rax - pop qword ptr [rbp + 32] ; for cs - pop qword ptr [rbp + 56] ; for ss + pop qword [rbp + 32] ; for cs + pop qword [rbp + 56] ; for ss ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; pop rdi pop rsi add rsp, 8 ; not for rbp - pop qword ptr [rbp + 48] ; for rsp + pop qword [rbp + 48] ; for rsp pop rbx pop rdx pop rcx @@ -337,53 +334,50 @@ NoErrorCode: mov rsp, rbp pop rbp add rsp, 16 - cmp qword ptr [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler + cmp qword [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler jz DoReturn - cmp qword ptr [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + cmp qword [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag jz ErrorCode - jmp qword ptr [rsp - 32] + jmp qword [rsp - 32] ErrorCode: sub rsp, 8 - jmp qword ptr [rsp - 24] + jmp qword [rsp - 24] DoReturn: - cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET + cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 ; Check if need to do far return instead of IRET jz DoIret push rax mov rax, rsp ; save old RSP to rax - mov rsp, [rsp + 20h] - push [rax + 10h] ; save CS in new location - push [rax + 8h] ; save EIP in new location - push [rax + 18h] ; save EFLAGS in new location + mov rsp, [rsp + 0x20] + push qword [rax + 0x10] ; save CS in new location + push qword [rax + 0x8] ; save EIP in new location + push qword [rax + 0x18] ; save EFLAGS in new location mov rax, [rax] ; restore rax popfq ; restore EFLAGS - DB 48h ; prefix to composite "retq" with next "retf" + DB 0x48 ; prefix to composite "retq" with next "retf" retf ; far return DoIret: iretq -CommonInterruptEntry ENDP - ;------------------------------------------------------------------------------------- ; GetTemplateAddressMap (&AddressMap); ;------------------------------------------------------------------------------------- ; comments here for definition of address map -AsmGetTemplateAddressMap PROC - mov rax, offset AsmIdtVectorBegin - mov qword ptr [rcx], rax - mov qword ptr [rcx + 8h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 - mov rax, offset HookAfterStubHeaderBegin - mov qword ptr [rcx + 10h], rax +global ASM_PFX(AsmGetTemplateAddressMap) +ASM_PFX(AsmGetTemplateAddressMap): + mov rax, AsmIdtVectorBegin + mov qword [rcx], rax + mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 + mov rax, HookAfterStubHeaderBegin + mov qword [rcx + 0x10], rax ret -AsmGetTemplateAddressMap ENDP ;------------------------------------------------------------------------------------- -; AsmVectorNumFixup (*VectorBase, VectorNum, HookStub); +; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr); ;------------------------------------------------------------------------------------- -AsmVectorNumFixup PROC +global ASM_PFX(AsmVectorNumFixup) +ASM_PFX(AsmVectorNumFixup): mov rax, rdx mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al ret -AsmVectorNumFixup ENDP -END diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm new file mode 100644 index 000000000..19198f273 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm @@ -0,0 +1,396 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; ExceptionHandlerAsm.Asm +; +; Abstract: +; +; x64 CPU Exception Handler +; +; Notes: +; +;------------------------------------------------------------------------------ + +; +; CommonExceptionHandler() +; + +extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions +extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag +extern ASM_PFX(CommonExceptionHandler) + +SECTION .data + +DEFAULT REL +SECTION .text + +ALIGN 8 + +AsmIdtVectorBegin: +%rep 32 + db 0x6a ; push #VectorNum + db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum + push rax + mov rax, strict qword 0 ; mov rax, ASM_PFX(CommonInterruptEntry) + jmp rax +%endrep +AsmIdtVectorEnd: + +HookAfterStubHeaderBegin: + db 0x6a ; push +@VectorNum: + db 0 ; 0 will be fixed + push rax + mov rax, strict qword 0 ; mov rax, HookAfterStubHeaderEnd +JmpAbsoluteAddress: + jmp rax +HookAfterStubHeaderEnd: + mov rax, rsp + and sp, 0xfff0 ; make sure 16-byte aligned for exception context + sub rsp, 0x18 ; reserve room for filling exception data later + push rcx + mov rcx, [rax + 8] + bt [ASM_PFX(mErrorCodeFlag)], ecx + jnc .0 + push qword [rsp] ; push additional rcx to make stack alignment +.0: + xchg rcx, [rsp] ; restore rcx, save Exception Number in stack + push qword [rax] ; push rax into stack to keep code consistence + +;---------------------------------------; +; CommonInterruptEntry ; +;---------------------------------------; +; The follow algorithm is used for the common interrupt routine. +; Entry from each interrupt with a push eax and eax=interrupt number +; Stack frame would be as follows as specified in IA32 manuals: +; +; +---------------------+ <-- 16-byte aligned ensured by processor +; + Old SS + +; +---------------------+ +; + Old RSP + +; +---------------------+ +; + RFlags + +; +---------------------+ +; + CS + +; +---------------------+ +; + RIP + +; +---------------------+ +; + Error Code + +; +---------------------+ +; + Vector Number + +; +---------------------+ +; + RBP + +; +---------------------+ <-- RBP, 16-byte aligned +; The follow algorithm is used for the common interrupt routine. +global ASM_PFX(CommonInterruptEntry) +ASM_PFX(CommonInterruptEntry): + cli + pop rax + ; + ; All interrupt handlers are invoked through interrupt gates, so + ; IF flag automatically cleared at the entry point + ; + xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx + and rcx, 0xFF + cmp ecx, 32 ; Intel reserved vector for exceptions? + jae NoErrorCode + bt [ASM_PFX(mErrorCodeFlag)], ecx + jc HasErrorCode + +NoErrorCode: + + ; + ; Push a dummy error code on the stack + ; to maintain coherent stack map + ; + push qword [rsp] + mov qword [rsp + 8], 0 +HasErrorCode: + push rbp + mov rbp, rsp + push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler + push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + + ; + ; Stack: + ; +---------------------+ <-- 16-byte aligned ensured by processor + ; + Old SS + + ; +---------------------+ + ; + Old RSP + + ; +---------------------+ + ; + RFlags + + ; +---------------------+ + ; + CS + + ; +---------------------+ + ; + RIP + + ; +---------------------+ + ; + Error Code + + ; +---------------------+ + ; + RCX / Vector Number + + ; +---------------------+ + ; + RBP + + ; +---------------------+ <-- RBP, 16-byte aligned + ; + + ; + ; Since here the stack pointer is 16-byte aligned, so + ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 + ; is 16-byte aligned + ; + +;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; +;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rax + push qword [rbp + 8] ; RCX + push rdx + push rbx + push qword [rbp + 48] ; RSP + push qword [rbp] ; RBP + push rsi + push rdi + +;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero + movzx rax, word [rbp + 56] + push rax ; for ss + movzx rax, word [rbp + 32] + push rax ; for cs + mov rax, ds + push rax + mov rax, es + push rax + mov rax, fs + push rax + mov rax, gs + push rax + + mov [rbp + 8], rcx ; save vector number + +;; UINT64 Rip; + push qword [rbp + 24] + +;; UINT64 Gdtr[2], Idtr[2]; + xor rax, rax + push rax + push rax + sidt [rsp] + mov bx, word [rsp] + mov rax, qword [rsp + 2] + mov qword [rsp], rax + mov word [rsp + 8], bx + + xor rax, rax + push rax + push rax + sgdt [rsp] + mov bx, word [rsp] + mov rax, qword [rsp + 2] + mov qword [rsp], rax + mov word [rsp + 8], bx + +;; UINT64 Ldtr, Tr; + xor rax, rax + str ax + push rax + sldt ax + push rax + +;; UINT64 RFlags; + push qword [rbp + 40] + +;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; + mov rax, cr8 + push rax + mov rax, cr4 + or rax, 0x208 + mov cr4, rax + push rax + mov rax, cr3 + push rax + mov rax, cr2 + push rax + xor rax, rax + push rax + mov rax, cr0 + push rax + +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov rax, dr7 + push rax + mov rax, dr6 + push rax + mov rax, dr3 + push rax + mov rax, dr2 + push rax + mov rax, dr1 + push rax + mov rax, dr0 + push rax + +;; FX_SAVE_STATE_X64 FxSaveState; + sub rsp, 512 + mov rdi, rsp + db 0xf, 0xae, 0x7 ;fxsave [rdi] + +;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear + cld + +;; UINT32 ExceptionData; + push qword [rbp + 16] + +;; Prepare parameter and call + mov rcx, [rbp + 8] + mov rdx, rsp + ; + ; Per X64 calling convention, allocate maximum parameter stack space + ; and make sure RSP is 16-byte aligned + ; + sub rsp, 4 * 8 + 8 + call ASM_PFX(CommonExceptionHandler) + add rsp, 4 * 8 + 8 + + cli +;; UINT64 ExceptionData; + add rsp, 8 + +;; FX_SAVE_STATE_X64 FxSaveState; + + mov rsi, rsp + db 0xf, 0xae, 0xE ; fxrstor [rsi] + add rsp, 512 + +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; Skip restoration of DRx registers to support in-circuit emualators +;; or debuggers set breakpoint in interrupt/exception context + add rsp, 8 * 6 + +;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; + pop rax + mov cr0, rax + add rsp, 8 ; not for Cr1 + pop rax + mov cr2, rax + pop rax + mov cr3, rax + pop rax + mov cr4, rax + pop rax + mov cr8, rax + +;; UINT64 RFlags; + pop qword [rbp + 40] + +;; UINT64 Ldtr, Tr; +;; UINT64 Gdtr[2], Idtr[2]; +;; Best not let anyone mess with these particular registers... + add rsp, 48 + +;; UINT64 Rip; + pop qword [rbp + 24] + +;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; + pop rax + ; mov gs, rax ; not for gs + pop rax + ; mov fs, rax ; not for fs + ; (X64 will not use fs and gs, so we do not restore it) + pop rax + mov es, rax + pop rax + mov ds, rax + pop qword [rbp + 32] ; for cs + pop qword [rbp + 56] ; for ss + +;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; +;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; + pop rdi + pop rsi + add rsp, 8 ; not for rbp + pop qword [rbp + 48] ; for rsp + pop rbx + pop rdx + pop rcx + pop rax + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + + mov rsp, rbp + pop rbp + add rsp, 16 + cmp qword [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler + jz DoReturn + cmp qword [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + jz ErrorCode + jmp qword [rsp - 32] +ErrorCode: + sub rsp, 8 + jmp qword [rsp - 24] + +DoReturn: + cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 ; Check if need to do far return instead of IRET + jz DoIret + push rax + mov rax, rsp ; save old RSP to rax + mov rsp, [rsp + 0x20] + push qword [rax + 0x10] ; save CS in new location + push qword [rax + 0x8] ; save EIP in new location + push qword [rax + 0x18] ; save EFLAGS in new location + mov rax, [rax] ; restore rax + popfq ; restore EFLAGS + DB 0x48 ; prefix to composite "retq" with next "retf" + retf ; far return +DoIret: + iretq + +;------------------------------------------------------------------------------------- +; GetTemplateAddressMap (&AddressMap); +;------------------------------------------------------------------------------------- +; comments here for definition of address map +global ASM_PFX(AsmGetTemplateAddressMap) +ASM_PFX(AsmGetTemplateAddressMap): + lea rax, [AsmIdtVectorBegin] + mov qword [rcx], rax + mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 + lea rax, [HookAfterStubHeaderBegin] + mov qword [rcx + 0x10], rax + +; Fix up CommonInterruptEntry address + lea rax, [ASM_PFX(CommonInterruptEntry)] + lea rcx, [AsmIdtVectorBegin] +%rep 32 + mov qword [rcx + (JmpAbsoluteAddress - 8 - HookAfterStubHeaderBegin)], rax + add rcx, (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 +%endrep +; Fix up HookAfterStubHeaderEnd + lea rax, [HookAfterStubHeaderEnd] + lea rcx, [JmpAbsoluteAddress] + mov qword [rcx - 8], rax + + ret + +;------------------------------------------------------------------------------------- +; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmVectorNumFixup) +ASM_PFX(AsmVectorNumFixup): + mov rax, rdx + mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al + ret + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf new file mode 100644 index 000000000..7e21beaab --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf @@ -0,0 +1,55 @@ +## @file +# CPU Exception Handler library instance for SEC/PEI modules. +# +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# This is the XCODE5 variant of the SEC/PEI CpuExceptionHandlerLib. This +# variant performs binary patching to fix up addresses that allow the +# XCODE5 toolchain to be used. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Xcode5SecPeiCpuExceptionHandlerLib + MODULE_UNI_FILE = Xcode5SecPeiCpuExceptionHandlerLib.uni + FILE_GUID = 49C481AF-1621-42F3-8FA1-27C64143E304 + MODULE_TYPE = PEIM + VERSION_STRING = 1.1 + LIBRARY_CLASS = CpuExceptionHandlerLib|SEC PEI_CORE PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.Ia32] + Ia32/ExceptionHandlerAsm.nasm + Ia32/ExceptionTssEntryAsm.nasm + Ia32/ArchExceptionHandler.c + Ia32/ArchInterruptDefs.h + +[Sources.X64] + X64/Xcode5ExceptionHandlerAsm.nasm + X64/ArchExceptionHandler.c + X64/ArchInterruptDefs.h + +[Sources.common] + CpuExceptionCommon.h + CpuExceptionCommon.c + SecPeiCpuException.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + SerialPortLib + PrintLib + LocalApicLib + PeCoffGetEntryPointLib diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.uni new file mode 100644 index 000000000..a63b25f39 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.uni @@ -0,0 +1,18 @@ +// /** @file +// XCODE5 CPU Exception Handler library instance for SEC/PEI modules. +// +// CPU Exception Handler library instance for SEC/PEI modules when built +// using the XCODE5 toolchain. +// +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Exception Handler library instance for SEC/PEI modules with the XCODE5 toolchain." + +#string STR_MODULE_DESCRIPTION #language en-US "CPU Exception Handler library instance for SEC/PEI modules with the XCODE5 toolchain." + diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c new file mode 100644 index 000000000..6ddf917ba --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c @@ -0,0 +1,41 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance as Base Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0 if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ); + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ) +{ + return CpuidCoreClockCalculateTscFrequency (); +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf new file mode 100644 index 000000000..fd93adc5f --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf @@ -0,0 +1,35 @@ +## @file +# Base CPU Timer Library +# +# Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +# counter features are provided by the processors time stamp counter. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseCpuTimerLib + FILE_GUID = F10B5B91-D15A-496C-B044-B5235721AA08 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|SEC PEI_CORE PEIM + MODULE_UNI_FILE = BaseCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + BaseCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni new file mode 100644 index 000000000..fcf2b0fbc --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// Base CPU Timer Library +// +// Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +// counter features are provided by the processors time stamp counter. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c new file mode 100644 index 000000000..192a401fe --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c @@ -0,0 +1,279 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +GUID mCpuCrystalFrequencyHobGuid = { 0xe1ec5ad0, 0x8569, 0x46bd, { 0x8d, 0xcd, 0x3b, 0x9f, 0x6f, 0x45, 0x82, 0x7a } }; + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ); + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0 if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ) +{ + UINT64 TscFrequency; + UINT64 CoreXtalFrequency; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + + // + // Use CPUID leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Information + // EBX returns 0 if not supported. ECX, if non zero, provides Core Xtal Frequency in hertz. + // TSC frequency = (ECX, Core Xtal Frequency) * EBX/EAX. + // + AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL); + + // + // If EAX or EBX returns 0, the XTAL ratio is not enumerated. + // + if (RegEax == 0 || RegEbx ==0 ) { + ASSERT (RegEax != 0); + ASSERT (RegEbx != 0); + return 0; + } + // + // If ECX returns 0, the XTAL frequency is not enumerated. + // And PcdCpuCoreCrystalClockFrequency defined should base on processor series. + // + if (RegEcx == 0) { + CoreXtalFrequency = PcdGet64 (PcdCpuCoreCrystalClockFrequency); + } else { + CoreXtalFrequency = (UINT64) RegEcx; + } + + // + // Calculate TSC frequency = (ECX, Core Xtal Frequency) * EBX/EAX + // + TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UINT64)(RegEax >> 1), RegEax); + + return TscFrequency; +} + +/** + Stalls the CPU for at least the given number of ticks. + + Stalls the CPU for at least the given number of ticks. It's invoked by + MicroSecondDelay() and NanoSecondDelay(). + + @param Delay A period of time to delay in ticks. + +**/ +VOID +InternalCpuDelay ( + IN UINT64 Delay + ) +{ + UINT64 Ticks; + + // + // The target timer count is calculated here + // + Ticks = AsmReadTsc() + Delay; + + // + // Wait until time out + // Timer wrap-arounds are NOT handled correctly by this function. + // Thus, this function must be called within 10 years of reset since + // Intel guarantees a minimum of 10 years before the TSC wraps. + // + while (AsmReadTsc() <= Ticks) { + CpuPause(); + } +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param[in] MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + MicroSeconds, + InternalGetPerformanceCounterFrequency () + ), + 1000000u + ) + ); + + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + NanoSeconds, + InternalGetPerformanceCounterFrequency () + ), + 1000000000u + ) + ); + + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + Retrieves the current value of a 64-bit free running performance counter. The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return AsmReadTsc (); +} + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter starts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end with + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartValue + is less than EndValue, then the performance counter counts up. If StartValue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a StartValue + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with before + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue != NULL) { + *StartValue = 0; + } + + if (EndValue != NULL) { + *EndValue = 0xffffffffffffffffULL; + } + return InternalGetPerformanceCounterFrequency (); +} + +/** + Converts elapsed ticks of performance counter to time in nanoseconds. + + This function converts the elapsed ticks of running performance counter to + time value in unit of nanoseconds. + + @param Ticks The number of elapsed ticks of running performance counter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency = GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time = --------- x 1,000,000,000 + // Frequency + // + NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, + // i.e. highest bit set in Remainder should <= 33. + // + Shift = MAX (0, HighBitSet64 (Remainder) - 33); + Remainder = RShiftU64 (Remainder, (UINTN) Shift); + Frequency = RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); + + return NanoSeconds; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c new file mode 100644 index 000000000..269e5a3e8 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c @@ -0,0 +1,85 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +extern GUID mCpuCrystalFrequencyHobGuid; + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0 if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ); + +// +// Cached CPU Crystal counter frequency +// +UINT64 mCpuCrystalCounterFrequency = 0; + + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ) +{ + return mCpuCrystalCounterFrequency; +} + +/** + The constructor function is to initialize CpuCrystalCounterFrequency. + + @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 RETURN_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeCpuTimerLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Initialize CpuCrystalCounterFrequency + // + GuidHob = GetFirstGuidHob (&mCpuCrystalFrequencyHobGuid); + if (GuidHob != NULL) { + mCpuCrystalCounterFrequency = *(UINT64*)GET_GUID_HOB_DATA (GuidHob); + } else { + mCpuCrystalCounterFrequency = CpuidCoreClockCalculateTscFrequency (); + } + + if (mCpuCrystalCounterFrequency == 0) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf new file mode 100644 index 000000000..6c83549c8 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf @@ -0,0 +1,37 @@ +## @file +# DXE CPU Timer Library +# +# Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +# counter features are provided by the processors time stamp counter. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCpuTimerLib + FILE_GUID = F22CC0DA-E7DB-4E4D-ABE2-A608188233A2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE + CONSTRUCTOR = DxeCpuTimerLibConstructor + MODULE_UNI_FILE = DxeCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + DxeCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + HobLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni new file mode 100644 index 000000000..f55b92aba --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// DXE CPU Timer Library +// +// Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +// counter features are provided by the processors time stamp counter. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c new file mode 100644 index 000000000..91a721205 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c @@ -0,0 +1,58 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance as PEI Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +extern GUID mCpuCrystalFrequencyHobGuid; + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0 if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ); + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ) +{ + UINT64 *CpuCrystalCounterFrequency; + EFI_HOB_GUID_TYPE *GuidHob; + + CpuCrystalCounterFrequency = NULL; + GuidHob = GetFirstGuidHob (&mCpuCrystalFrequencyHobGuid); + if (GuidHob == NULL) { + CpuCrystalCounterFrequency = (UINT64*)BuildGuidHob(&mCpuCrystalFrequencyHobGuid, sizeof (*CpuCrystalCounterFrequency)); + ASSERT (CpuCrystalCounterFrequency != NULL); + *CpuCrystalCounterFrequency = CpuidCoreClockCalculateTscFrequency (); + } else { + CpuCrystalCounterFrequency = (UINT64*)GET_GUID_HOB_DATA (GuidHob); + } + + return *CpuCrystalCounterFrequency; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf new file mode 100644 index 000000000..7af0fc44a --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf @@ -0,0 +1,36 @@ +## @file +# PEI CPU Timer Library +# +# Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +# counter features are provided by the processors time stamp counter. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiCpuTimerLib + FILE_GUID = 2B13DE00-1A5F-4DD7-A298-01B08AF1015A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|PEI_CORE PEIM + MODULE_UNI_FILE = PeiCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + PeiCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + HobLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni new file mode 100644 index 000000000..49beb4490 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// PEI CPU Timer Library +// +// Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The performance +// counter features are provided by the processors time stamp counter. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf new file mode 100644 index 000000000..9907f4157 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -0,0 +1,74 @@ +## @file +# MP Initialize Library instance for DXE driver. +# +# Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeMpInitLib + MODULE_UNI_FILE = DxeMpInitLib.uni + FILE_GUID = B88F7146-9834-4c55-BFAC-481CC0C33736 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.1 + LIBRARY_CLASS = MpInitLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32] + Ia32/MpEqu.inc + Ia32/MpFuncs.nasm + +[Sources.X64] + X64/MpEqu.inc + X64/MpFuncs.nasm + +[Sources.common] + DxeMpLib.c + MpLib.c + MpLib.h + Microcode.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + LocalApicLib + MemoryAllocationLib + HobLib + MtrrLib + CpuLib + UefiCpuLib + UefiBootServicesTableLib + DebugAgentLib + SynchronizationLib + PcdLib + +[Protocols] + gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event + gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni new file mode 100644 index 000000000..27cfdd37a --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni @@ -0,0 +1,16 @@ +// /** @file +// MP Initialize Library instance for DXE driver. +// +// MP Initialize Library instance for DXE driver. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "MP Initialize Library instance for DXE driver." + +#string STR_MODULE_DESCRIPTION #language en-US "MP Initialize Library instance for DXE driver." + diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c new file mode 100644 index 000000000..8ccddf8e9 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -0,0 +1,843 @@ +/** @file + MP initialize support functions for DXE phase. + + Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" + +#include +#include +#include +#include + +#include + +#define AP_SAFE_STACK_SIZE 128 + +CPU_MP_DATA *mCpuMpData = NULL; +EFI_EVENT mCheckAllApsEvent = NULL; +EFI_EVENT mMpInitExitBootServicesEvent = NULL; +EFI_EVENT mLegacyBootEvent = NULL; +volatile BOOLEAN mStopCheckAllApsStatus = TRUE; +VOID *mReservedApLoopFunc = NULL; +UINTN mReservedTopOfApStack; +volatile UINT32 mNumberToFinish = 0; + +/** + Enable Debug Agent to support source debugging on AP function. + +**/ +VOID +EnableDebugAgent ( + VOID + ) +{ + // + // Initialize Debug Agent to support source level debug in DXE phase + // + InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_AP, NULL, NULL); +} + +/** + Get the pointer to CPU MP Data structure. + + @return The pointer to CPU MP Data structure. +**/ +CPU_MP_DATA * +GetCpuMpData ( + VOID + ) +{ + ASSERT (mCpuMpData != NULL); + return mCpuMpData; +} + +/** + Save the pointer to CPU MP Data structure. + + @param[in] CpuMpData The pointer to CPU MP Data structure will be saved. +**/ +VOID +SaveCpuMpData ( + IN CPU_MP_DATA *CpuMpData + ) +{ + mCpuMpData = CpuMpData; +} + +/** + Get available system memory below 0x88000 by specified size. + + @param[in] WakeupBufferSize Wakeup buffer size required + + @retval other Return wakeup buffer address below 1MB. + @retval -1 Cannot find free memory below 1MB. +**/ +UINTN +GetWakeupBuffer ( + IN UINTN WakeupBufferSize + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS StartAddress; + + // + // Try to allocate buffer below 1M for waking vector. + // LegacyBios driver only reports warning when page allocation in range + // [0x60000, 0x88000) fails. + // This library is consumed by CpuDxe driver to produce CPU Arch protocol. + // LagacyBios driver depends on CPU Arch protocol which guarantees below + // allocation runs earlier than LegacyBios driver. + // + StartAddress = 0x88000; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, + EFI_SIZE_TO_PAGES (WakeupBufferSize), + &StartAddress + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + StartAddress = (EFI_PHYSICAL_ADDRESS) -1; + } + + DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n", + (UINTN) StartAddress, WakeupBufferSize)); + + return (UINTN) StartAddress; +} + +/** + Get available EfiBootServicesCode memory below 4GB by specified size. + + This buffer is required to safely transfer AP from real address mode to + protected mode or long mode, due to the fact that the buffer returned by + GetWakeupBuffer() may be marked as non-executable. + + @param[in] BufferSize Wakeup transition buffer size. + + @retval other Return wakeup transition buffer address below 4GB. + @retval 0 Cannot find free memory below 4GB. +**/ +UINTN +GetModeTransitionBuffer ( + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS StartAddress; + + StartAddress = BASE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesCode, + EFI_SIZE_TO_PAGES (BufferSize), + &StartAddress + ); + if (EFI_ERROR (Status)) { + StartAddress = 0; + } + + return (UINTN)StartAddress; +} + +/** + Checks APs status and updates APs status if needed. + +**/ +VOID +CheckAndUpdateApsStatus ( + VOID + ) +{ + UINTN ProcessorNumber; + EFI_STATUS Status; + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + + // + // First, check whether pending StartupAllAPs() exists. + // + if (CpuMpData->WaitEvent != NULL) { + + Status = CheckAllAPs (); + // + // If all APs finish for StartupAllAPs(), signal the WaitEvent for it. + // + if (Status != EFI_NOT_READY) { + Status = gBS->SignalEvent (CpuMpData->WaitEvent); + CpuMpData->WaitEvent = NULL; + } + } + + // + // Second, check whether pending StartupThisAPs() callings exist. + // + for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) { + + if (CpuMpData->CpuData[ProcessorNumber].WaitEvent == NULL) { + continue; + } + + Status = CheckThisAP (ProcessorNumber); + + if (Status != EFI_NOT_READY) { + gBS->SignalEvent (CpuMpData->CpuData[ProcessorNumber].WaitEvent); + CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL; + } + } +} + +/** + Checks APs' status periodically. + + This function is triggered by timer periodically to check the + state of APs for StartupAllAPs() and StartupThisAP() executed + in non-blocking mode. + + @param[in] Event Event triggered. + @param[in] Context Parameter passed with the event. + +**/ +VOID +EFIAPI +CheckApsStatus ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // If CheckApsStatus() is not stopped, otherwise return immediately. + // + if (!mStopCheckAllApsStatus) { + CheckAndUpdateApsStatus (); + } +} + +/** + Get Protected mode code segment from current GDT table. + + @return Protected mode code segment value. +**/ +UINT16 +GetProtectedModeCS ( + VOID + ) +{ + IA32_DESCRIPTOR GdtrDesc; + IA32_SEGMENT_DESCRIPTOR *GdtEntry; + UINTN GdtEntryCount; + UINT16 Index; + + AsmReadGdtr (&GdtrDesc); + GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR); + GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base; + for (Index = 0; Index < GdtEntryCount; Index++) { + if (GdtEntry->Bits.L == 0) { + if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) { + break; + } + } + GdtEntry++; + } + ASSERT (Index != GdtEntryCount); + return Index * 8; +} + +/** + Do sync on APs. + + @param[in, out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +RelocateApLoop ( + IN OUT VOID *Buffer + ) +{ + CPU_MP_DATA *CpuMpData; + BOOLEAN MwaitSupport; + ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; + UINTN ProcessorNumber; + + MpInitLibWhoAmI (&ProcessorNumber); + CpuMpData = GetCpuMpData (); + MwaitSupport = IsMwaitSupport (); + AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc; + AsmRelocateApLoopFunc ( + MwaitSupport, + CpuMpData->ApTargetCState, + CpuMpData->PmCodeSegment, + mReservedTopOfApStack - ProcessorNumber * AP_SAFE_STACK_SIZE, + (UINTN) &mNumberToFinish + ); + // + // It should never reach here + // + ASSERT (FALSE); +} + +/** + Callback function for ExitBootServices. + + @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 +MpInitChangeApLoopCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + CpuMpData->PmCodeSegment = GetProtectedModeCS (); + CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); + mNumberToFinish = CpuMpData->CpuCount - 1; + WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + while (mNumberToFinish > 0) { + CpuPause (); + } + DEBUG ((DEBUG_INFO, "%a() done!\n", __FUNCTION__)); +} + +/** + Initialize global data for MP support. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +InitMpGlobalData ( + IN CPU_MP_DATA *CpuMpData + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + UINTN ApSafeBufferSize; + UINTN Index; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; + UINTN StackBase; + CPU_INFO_IN_HOB *CpuInfoInHob; + + SaveCpuMpData (CpuMpData); + + if (CpuMpData->CpuCount == 1) { + // + // If only BSP exists, return + // + return; + } + + if (PcdGetBool (PcdCpuStackGuard)) { + // + // One extra page at the bottom of the stack is needed for Guard page. + // + if (CpuMpData->CpuApStackSize <= EFI_PAGE_SIZE) { + DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n")); + ASSERT (FALSE); + } + + // + // DXE will reuse stack allocated for APs at PEI phase if it's available. + // Let's check it here. + // + // Note: BSP's stack guard is set at DxeIpl phase. But for the sake of + // BSP/AP exchange, stack guard for ApTopOfStack of cpu 0 will still be + // set here. + // + CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; + for (Index = 0; Index < CpuMpData->CpuCount; ++Index) { + if (CpuInfoInHob != NULL && CpuInfoInHob[Index].ApTopOfStack != 0) { + StackBase = (UINTN)CpuInfoInHob[Index].ApTopOfStack - CpuMpData->CpuApStackSize; + } else { + StackBase = CpuMpData->Buffer + Index * CpuMpData->CpuApStackSize; + } + + Status = gDS->GetMemorySpaceDescriptor (StackBase, &MemDesc); + ASSERT_EFI_ERROR (Status); + + Status = gDS->SetMemorySpaceAttributes ( + StackBase, + EFI_PAGES_TO_SIZE (1), + MemDesc.Attributes | EFI_MEMORY_RP + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n", + (UINT64)StackBase, (UINT64)Index)); + } + } + + // + // Avoid APs access invalid buffer data which allocated by BootServices, + // so we will allocate reserved data for AP loop code. We also need to + // allocate this buffer below 4GB due to APs may be transferred to 32bit + // protected mode on long mode DXE. + // Allocating it in advance since memory services are not available in + // Exit Boot Services callback function. + // + ApSafeBufferSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ( + CpuMpData->AddressMap.RelocateApLoopFuncSize + )); + Address = BASE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (ApSafeBufferSize), + &Address + ); + ASSERT_EFI_ERROR (Status); + + mReservedApLoopFunc = (VOID *) (UINTN) Address; + ASSERT (mReservedApLoopFunc != NULL); + + // + // Make sure that the buffer memory is executable if NX protection is enabled + // for EfiReservedMemoryType. + // + // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD + // service. + // + Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc); + if (!EFI_ERROR (Status)) { + gDS->SetMemorySpaceAttributes ( + Address, + ApSafeBufferSize, + MemDesc.Attributes & (~EFI_MEMORY_XP) + ); + } + + ApSafeBufferSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ( + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + )); + Address = BASE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (ApSafeBufferSize), + &Address + ); + ASSERT_EFI_ERROR (Status); + + mReservedTopOfApStack = (UINTN) Address + ApSafeBufferSize; + ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); + CopyMem ( + mReservedApLoopFunc, + CpuMpData->AddressMap.RelocateApLoopFuncAddress, + CpuMpData->AddressMap.RelocateApLoopFuncSize + ); + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + CheckApsStatus, + NULL, + &mCheckAllApsEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Set timer to check all APs status. + // + Status = gBS->SetTimer ( + mCheckAllApsEvent, + TimerPeriodic, + EFI_TIMER_PERIOD_MICROSECONDS ( + PcdGet32 (PcdCpuApStatusCheckIntervalInMicroSeconds) + ) + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + MpInitChangeApLoopCallback, + NULL, + &mMpInitExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + MpInitChangeApLoopCallback, + NULL, + &gEfiEventLegacyBootGuid, + &mLegacyBootEvent + ); + ASSERT_EFI_ERROR (Status); +} + +/** + This service executes a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by MpInitLibStartupAllAPs() or + MPInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Initialization + library, and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllAPs ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ) +{ + EFI_STATUS Status; + + // + // Temporarily stop checkAllApsStatus for avoid resource dead-lock. + // + mStopCheckAllApsStatus = TRUE; + + Status = StartupAllCPUsWorker ( + Procedure, + SingleThread, + TRUE, + WaitEvent, + TimeoutInMicroseconds, + ProcedureArgument, + FailedCpuList + ); + + // + // Start checkAllApsStatus + // + mStopCheckAllApsStatus = FALSE; + + return Status; +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by MpInitLibStartupAllAPs() or + MpInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupThisAP ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ) +{ + EFI_STATUS Status; + + // + // temporarily stop checkAllApsStatus for avoid resource dead-lock. + // + mStopCheckAllApsStatus = TRUE; + + Status = StartupThisAPWorker ( + Procedure, + ProcessorNumber, + WaitEvent, + TimeoutInMicroseconds, + ProcedureArgument, + Finished + ); + + mStopCheckAllApsStatus = FALSE; + + return Status; +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibSwitchBSP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + EFI_STATUS Status; + EFI_TIMER_ARCH_PROTOCOL *Timer; + UINT64 TimerPeriod; + + TimerPeriod = 0; + // + // Locate Timer Arch Protocol + // + Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **) &Timer); + if (EFI_ERROR (Status)) { + Timer = NULL; + } + + if (Timer != NULL) { + // + // Save current rate of DXE Timer + // + Timer->GetTimerPeriod (Timer, &TimerPeriod); + // + // Disable DXE Timer and drain pending interrupts + // + Timer->SetTimerPeriod (Timer, 0); + } + + Status = SwitchBSPWorker (ProcessorNumber, EnableOldBSP); + + if (Timer != NULL) { + // + // Enable and restore rate of DXE Timer + // + Timer->SetTimerPeriod (Timer, TimerPeriod); + } + + return Status; +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibEnableDisableAP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + EFI_STATUS Status; + BOOLEAN TempStopCheckState; + + TempStopCheckState = FALSE; + // + // temporarily stop checkAllAPsStatus for initialize parameters. + // + if (!mStopCheckAllApsStatus) { + mStopCheckAllApsStatus = TRUE; + TempStopCheckState = TRUE; + } + + Status = EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag); + + if (TempStopCheckState) { + mStopCheckAllApsStatus = FALSE; + } + + return Status; +} + +/** + This funtion will try to invoke platform specific microcode shadow logic to + relocate microcode update patches into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + + @retval EFI_SUCCESS Shadow microcode success. + @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation. + @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow + PPI/Protocol. +**/ +EFI_STATUS +PlatformShadowMicrocode ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + // + // There is no DXE version of platform shadow microcode protocol so far. + // A platform which only uses DxeMpInitLib instance could only supports + // the PCD based microcode shadowing. + // + return EFI_UNSUPPORTED; +} diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc new file mode 100644 index 000000000..efb1bc2bf --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpEqu.inc +; +; Abstract: +; +; This is the equates file for Multiple Processor support +; +;------------------------------------------------------------------------------- + +VacantFlag equ 00h +NotVacantFlag equ 0ffh + +CPU_SWITCH_STATE_IDLE equ 0 +CPU_SWITCH_STATE_STORED equ 1 +CPU_SWITCH_STATE_LOADED equ 2 + +LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart) +StackStartAddressLocation equ LockLocation + 04h +StackSizeLocation equ LockLocation + 08h +ApProcedureLocation equ LockLocation + 0Ch +GdtrLocation equ LockLocation + 10h +IdtrLocation equ LockLocation + 16h +BufferStartLocation equ LockLocation + 1Ch +ModeOffsetLocation equ LockLocation + 20h +ApIndexLocation equ LockLocation + 24h +CodeSegmentLocation equ LockLocation + 28h +DataSegmentLocation equ LockLocation + 2Ch +EnableExecuteDisableLocation equ LockLocation + 30h +Cr3Location equ LockLocation + 34h +InitFlagLocation equ LockLocation + 38h +CpuInfoLocation equ LockLocation + 3Ch +NumApsExecutingLocation equ LockLocation + 40h +InitializeFloatingPointUnitsAddress equ LockLocation + 48h +ModeTransitionMemoryLocation equ LockLocation + 4Ch +ModeTransitionSegmentLocation equ LockLocation + 50h +ModeHighMemoryLocation equ LockLocation + 52h +ModeHighSegmentLocation equ LockLocation + 56h + diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm new file mode 100644 index 000000000..b74046b76 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm @@ -0,0 +1,342 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpFuncs.nasm +; +; Abstract: +; +; This is the assembly code for MP support +; +;------------------------------------------------------------------------------- + +%include "MpEqu.inc" +extern ASM_PFX(InitializeFloatingPointUnits) + +SECTION .text + +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc procedure follows. All APs execute their procedure. This +;procedure serializes all the AP processors through an Init sequence. It must be +;noted that APs arrive here very raw...ie: real mode, no stack. +;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC +;IS IN MACHINE CODE. +;------------------------------------------------------------------------------------- +global ASM_PFX(RendezvousFunnelProc) +ASM_PFX(RendezvousFunnelProc): +RendezvousFunnelProcStart: +; At this point CS = 0x(vv00) and ip= 0x0. +BITS 16 + mov ebp, eax ; save BIST information + + mov ax, cs + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + + mov si, BufferStartLocation + mov ebx, [si] + + mov si, DataSegmentLocation + mov edx, [si] + + ; + ; Get start address of 32-bit code in low memory (<1MB) + ; + mov edi, ModeTransitionMemoryLocation + + mov si, GdtrLocation +o32 lgdt [cs:si] + + mov si, IdtrLocation +o32 lidt [cs:si] + + ; + ; Switch to protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 000000003h ; Set PE bit (bit #0) & MP + mov cr0, eax + + ; Switch to 32-bit code in executable memory (>1MB) +o32 jmp far [cs:di] + +; +; Following code may be copied to memory with type of EfiBootServicesCode. +; This is required at DXE phase if NX is enabled for EfiBootServicesCode of +; memory. +; +BITS 32 +Flat32Start: ; protected mode entry point + mov ds, dx + mov es, dx + mov fs, dx + mov gs, dx + mov ss, dx + + mov esi, ebx + + mov edi, esi + add edi, EnableExecuteDisableLocation + cmp byte [edi], 0 + jz SkipEnableExecuteDisable + + ; + ; Enable IA32 PAE execute disable + ; + + mov ecx, 0xc0000080 + rdmsr + bts eax, 11 + wrmsr + + mov edi, esi + add edi, Cr3Location + mov eax, dword [edi] + mov cr3, eax + + mov eax, cr4 + bts eax, 5 + mov cr4, eax + + mov eax, cr0 + bts eax, 31 + mov cr0, eax + +SkipEnableExecuteDisable: + mov edi, esi + add edi, InitFlagLocation + cmp dword [edi], 1 ; 1 == ApInitConfig + jnz GetApicId + + ; Increment the number of APs executing here as early as possible + ; This is decremented in C code when AP is finished executing + mov edi, esi + add edi, NumApsExecutingLocation + lock inc dword [edi] + + ; AP init + mov edi, esi + add edi, LockLocation + mov eax, NotVacantFlag + +TestLock: + xchg [edi], eax + cmp eax, NotVacantFlag + jz TestLock + + mov ecx, esi + add ecx, ApIndexLocation + inc dword [ecx] + mov ebx, [ecx] + +Releaselock: + mov eax, VacantFlag + xchg [edi], eax + + mov edi, esi + add edi, StackSizeLocation + mov eax, [edi] + mov ecx, ebx + inc ecx + mul ecx ; EAX = StackSize * (CpuNumber + 1) + mov edi, esi + add edi, StackStartAddressLocation + add eax, [edi] + mov esp, eax + jmp CProcedureInvoke + +GetApicId: + mov eax, 0 + cpuid + cmp eax, 0bh + jb NoX2Apic ; CPUID level below CPUID_EXTENDED_TOPOLOGY + + mov eax, 0bh + xor ecx, ecx + cpuid + test ebx, 0ffffh + jz NoX2Apic ; CPUID.0BH:EBX[15:0] is zero + + ; Processor is x2APIC capable; 32-bit x2APIC ID is already in EDX + jmp GetProcessorNumber + +NoX2Apic: + ; Processor is not x2APIC capable, so get 8-bit APIC ID + mov eax, 1 + cpuid + shr ebx, 24 + mov edx, ebx + +GetProcessorNumber: + ; + ; Get processor number for this AP + ; Note that BSP may become an AP due to SwitchBsp() + ; + xor ebx, ebx + lea eax, [esi + CpuInfoLocation] + mov edi, [eax] + +GetNextProcNumber: + cmp [edi], edx ; APIC ID match? + jz ProgramStack + add edi, 20 + inc ebx + jmp GetNextProcNumber + +ProgramStack: + mov esp, [edi + 12] + +CProcedureInvoke: + push ebp ; push BIST data at top of AP stack + xor ebp, ebp ; clear ebp for call stack trace + push ebp + mov ebp, esp + + mov eax, ASM_PFX(InitializeFloatingPointUnits) + call eax ; Call assembly function to initialize FPU per UEFI spec + + push ebx ; Push ApIndex + mov eax, esi + add eax, LockLocation + push eax ; push address of exchange info data buffer + + mov edi, esi + add edi, ApProcedureLocation + mov eax, [edi] + + call eax ; Invoke C function + + jmp $ ; Never reach here +RendezvousFunnelProcEnd: + +;------------------------------------------------------------------------------------- +; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmRelocateApLoop) +ASM_PFX(AsmRelocateApLoop): +AsmRelocateApLoopStart: + mov eax, esp + mov esp, [eax + 16] ; TopOfApStack + push dword [eax] ; push return address for stack trace + push ebp + mov ebp, esp + mov ebx, [eax + 8] ; ApTargetCState + mov ecx, [eax + 4] ; MwaitSupport + mov eax, [eax + 20] ; CountTofinish + lock dec dword [eax] ; (*CountTofinish)-- + cmp cl, 1 ; Check mwait-monitor support + jnz HltLoop +MwaitLoop: + cli + mov eax, esp + xor ecx, ecx + xor edx, edx + monitor + mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4] + shl eax, 4 + mwait + jmp MwaitLoop +HltLoop: + cli + hlt + jmp HltLoop +AsmRelocateApLoopEnd: + +;------------------------------------------------------------------------------------- +; AsmGetAddressMap (&AddressMap); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmGetAddressMap) +ASM_PFX(AsmGetAddressMap): + pushad + mov ebp,esp + + mov ebx, [ebp + 24h] + mov dword [ebx], RendezvousFunnelProcStart + mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart + mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart + mov dword [ebx + 0Ch], AsmRelocateApLoopStart + mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart + mov dword [ebx + 14h], Flat32Start - RendezvousFunnelProcStart + + popad + ret + +;------------------------------------------------------------------------------------- +;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is +;about to become an AP. It switches it'stack with the current AP. +;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmExchangeRole) +ASM_PFX(AsmExchangeRole): + ; DO NOT call other functions in this function, since 2 CPU may use 1 stack + ; at the same time. If 1 CPU try to call a function, stack will be corrupted. + pushad + mov ebp,esp + + ; esi contains MyInfo pointer + mov esi, [ebp + 24h] + + ; edi contains OthersInfo pointer + mov edi, [ebp + 28h] + + ;Store EFLAGS, GDTR and IDTR register to stack + pushfd + mov eax, cr4 + push eax ; push cr4 firstly + mov eax, cr0 + push eax + + sgdt [esi + 8] + sidt [esi + 14] + + ; Store the its StackPointer + mov [esi + 4],esp + + ; update its switch state to STORED + mov byte [esi], CPU_SWITCH_STATE_STORED + +WaitForOtherStored: + ; wait until the other CPU finish storing its state + cmp byte [edi], CPU_SWITCH_STATE_STORED + jz OtherStored + pause + jmp WaitForOtherStored + +OtherStored: + ; Since another CPU already stored its state, load them + ; load GDTR value + lgdt [edi + 8] + + ; load IDTR value + lidt [edi + 14] + + ; load its future StackPointer + mov esp, [edi + 4] + + ; update the other CPU's switch state to LOADED + mov byte [edi], CPU_SWITCH_STATE_LOADED + +WaitForOtherLoaded: + ; wait until the other CPU finish loading new state, + ; otherwise the data in stack may corrupt + cmp byte [esi], CPU_SWITCH_STATE_LOADED + jz OtherLoaded + pause + jmp WaitForOtherLoaded + +OtherLoaded: + ; since the other CPU already get the data it want, leave this procedure + pop eax + mov cr0, eax + pop eax + mov cr4, eax + popfd + + popad + ret diff --git a/UefiCpuPkg/Library/MpInitLib/Microcode.c b/UefiCpuPkg/Library/MpInitLib/Microcode.c new file mode 100644 index 000000000..15629591e --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c @@ -0,0 +1,681 @@ +/** @file + Implementation of loading microcode on processors. + + Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" + +/** + Get microcode update signature of currently loaded microcode update. + + @return Microcode signature. +**/ +UINT32 +GetCurrentMicrocodeSignature ( + VOID + ) +{ + MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr; + + AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); + BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); + return BiosSignIdMsr.Bits.MicrocodeUpdateSignature; +} + +/** + Detect whether specified processor can find matching microcode patch and load it. + + Microcode Payload as the following format: + +----------------------------------------+------------------+ + | CPU_MICROCODE_HEADER | | + +----------------------------------------+ CheckSum Part1 | + | Microcode Binary | | + +----------------------------------------+------------------+ + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | + +----------------------------------------+ CheckSum Part2 | + | CPU_MICROCODE_EXTENDED_TABLE | | + | ... | | + +----------------------------------------+------------------+ + + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. + + When we are trying to verify the CheckSum32 with extended table. + We should use the fields of exnteded table to replace the corresponding + fields in CPU_MICROCODE_HEADER structure, and recalculate the + CheckSum32 with CPU_MICROCODE_HEADER + Microcode Binary. We named + it as CheckSum Part3. + + The CheckSum Part2 is used to verify the CPU_MICROCODE_EXTENDED_TABLE_HEADER + and CPU_MICROCODE_EXTENDED_TABLE parts. We should make sure CheckSum Part2 + is correct before we are going to verify each CPU_MICROCODE_EXTENDED_TABLE. + + Only ProcessorSignature, ProcessorFlag and CheckSum are different between + CheckSum Part1 and CheckSum Part3. To avoid multiple computing CheckSum Part3. + Save an in-complete CheckSum32 from CheckSum Part1 for common parts. + When we are going to calculate CheckSum32, just should use the corresponding part + of the ProcessorSignature, ProcessorFlag and CheckSum with in-complete CheckSum32. + + Notes: CheckSum32 is not a strong verification. + It does not guarantee that the data has not been modified. + CPU has its own mechanism to verify Microcode Binary part. + + @param[in] CpuMpData The pointer to CPU MP Data structure. + @param[in] ProcessorNumber The handle number of the processor. The range is + from 0 to the total number of logical processors + minus 1. +**/ +VOID +MicrocodeDetect ( + IN CPU_MP_DATA *CpuMpData, + IN UINTN ProcessorNumber + ) +{ + UINT32 ExtendedTableLength; + UINT32 ExtendedTableCount; + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN MicrocodeEnd; + UINTN Index; + UINT8 PlatformId; + CPUID_VERSION_INFO_EAX Eax; + CPU_AP_DATA *CpuData; + UINT32 CurrentRevision; + UINT32 LatestRevision; + UINTN TotalSize; + UINT32 CheckSum32; + UINT32 InCompleteCheckSum32; + BOOLEAN CorrectMicrocode; + VOID *MicrocodeData; + MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr; + UINT32 ThreadId; + BOOLEAN IsBspCallIn; + + if (CpuMpData->MicrocodePatchRegionSize == 0) { + // + // There is no microcode patches + // + return; + } + + CurrentRevision = GetCurrentMicrocodeSignature (); + IsBspCallIn = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE; + + GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId); + if (ThreadId != 0) { + // + // Skip loading microcode if it is not the first thread in one core. + // + return; + } + + ExtendedTableLength = 0; + // + // Here data of CPUID leafs have not been collected into context buffer, so + // GetProcessorCpuid() cannot be used here to retrieve CPUID data. + // + AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL); + + // + // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID + // + PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID); + PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId; + + + // + // Check whether AP has same processor with BSP. + // If yes, direct use microcode info saved by BSP. + // + if (!IsBspCallIn) { + // + // Get the CPU data for BSP + // + CpuData = &(CpuMpData->CpuData[CpuMpData->BspNumber]); + if ((CpuData->ProcessorSignature == Eax.Uint32) && + (CpuData->PlatformId == PlatformId) && + (CpuData->MicrocodeEntryAddr != 0)) { + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN) CpuData->MicrocodeEntryAddr; + MicrocodeData = (VOID *) (MicrocodeEntryPoint + 1); + LatestRevision = MicrocodeEntryPoint->UpdateRevision; + goto Done; + } + } + + LatestRevision = 0; + MicrocodeData = NULL; + MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize); + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->MicrocodePatchAddress; + + do { + // + // Check if the microcode is for the Cpu and the version is newer + // and the update can be processed on the platform + // + CorrectMicrocode = FALSE; + + if (MicrocodeEntryPoint->DataSize == 0) { + TotalSize = sizeof (CPU_MICROCODE_HEADER) + 2000; + } else { + TotalSize = sizeof (CPU_MICROCODE_HEADER) + MicrocodeEntryPoint->DataSize; + } + + /// + /// 0x0 MicrocodeBegin MicrocodeEntry MicrocodeEnd 0xffffffff + /// |--------------|---------------|---------------|---------------| + /// valid TotalSize + /// TotalSize is only valid between 0 and (MicrocodeEnd - MicrocodeEntry). + /// And it should be aligned with 4 bytes. + /// If the TotalSize is invalid, skip 1KB to check next entry. + /// + if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || + ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || + (TotalSize & 0x3) != 0 + ) { + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + continue; + } + + // + // Save an in-complete CheckSum32 from CheckSum Part1 for common parts. + // + InCompleteCheckSum32 = CalculateSum32 ( + (UINT32 *) MicrocodeEntryPoint, + TotalSize + ); + InCompleteCheckSum32 -= MicrocodeEntryPoint->ProcessorSignature.Uint32; + InCompleteCheckSum32 -= MicrocodeEntryPoint->ProcessorFlags; + InCompleteCheckSum32 -= MicrocodeEntryPoint->Checksum; + + if (MicrocodeEntryPoint->HeaderVersion == 0x1) { + // + // It is the microcode header. It is not the padding data between microcode patches + // because the padding data should not include 0x00000001 and it should be the repeated + // byte format (like 0xXYXYXYXY....). + // + if (MicrocodeEntryPoint->ProcessorSignature.Uint32 == Eax.Uint32 && + MicrocodeEntryPoint->UpdateRevision > LatestRevision && + (MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId)) + ) { + // + // Calculate CheckSum Part1. + // + CheckSum32 = InCompleteCheckSum32; + CheckSum32 += MicrocodeEntryPoint->ProcessorSignature.Uint32; + CheckSum32 += MicrocodeEntryPoint->ProcessorFlags; + CheckSum32 += MicrocodeEntryPoint->Checksum; + if (CheckSum32 == 0) { + CorrectMicrocode = TRUE; + } + } else if ((MicrocodeEntryPoint->DataSize != 0) && + (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) { + ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + + sizeof (CPU_MICROCODE_HEADER)); + if (ExtendedTableLength != 0) { + // + // Extended Table exist, check if the CPU in support list + // + ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + + MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)); + // + // Calculate Extended Checksum + // + if ((ExtendedTableLength % 4) == 0) { + // + // Calculate CheckSum Part2. + // + CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength); + if (CheckSum32 == 0) { + // + // Checksum correct + // + ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; + ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1); + for (Index = 0; Index < ExtendedTableCount; Index ++) { + // + // Calculate CheckSum Part3. + // + CheckSum32 = InCompleteCheckSum32; + CheckSum32 += ExtendedTable->ProcessorSignature.Uint32; + CheckSum32 += ExtendedTable->ProcessorFlag; + CheckSum32 += ExtendedTable->Checksum; + if (CheckSum32 == 0) { + // + // Verify Header + // + if ((ExtendedTable->ProcessorSignature.Uint32 == Eax.Uint32) && + (ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) { + // + // Find one + // + CorrectMicrocode = TRUE; + break; + } + } + ExtendedTable ++; + } + } + } + } + } + } else { + // + // It is the padding data between the microcode patches for microcode patches alignment. + // Because the microcode patch is the multiple of 1-KByte, the padding data should not + // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode + // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to + // find the next possible microcode patch header. + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + continue; + } + // + // Get the next patch. + // + if (MicrocodeEntryPoint->DataSize == 0) { + TotalSize = 2048; + } else { + TotalSize = MicrocodeEntryPoint->TotalSize; + } + + if (CorrectMicrocode) { + LatestRevision = MicrocodeEntryPoint->UpdateRevision; + MicrocodeData = (VOID *) ((UINTN) MicrocodeEntryPoint + sizeof (CPU_MICROCODE_HEADER)); + } + + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); + } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + +Done: + if (LatestRevision != 0) { + // + // Save the detected microcode patch entry address (including the + // microcode patch header) for each processor. + // It will be used when building the microcode patch cache HOB. + // + CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr = + (UINTN) MicrocodeData - sizeof (CPU_MICROCODE_HEADER); + } + + if (LatestRevision > CurrentRevision) { + // + // BIOS only authenticate updates that contain a numerically larger revision + // than the currently loaded revision, where Current Signature < New Update + // Revision. A processor with no loaded update is considered to have a + // revision equal to zero. + // + ASSERT (MicrocodeData != NULL); + AsmWriteMsr64 ( + MSR_IA32_BIOS_UPDT_TRIG, + (UINT64) (UINTN) MicrocodeData + ); + // + // Get and check new microcode signature + // + CurrentRevision = GetCurrentMicrocodeSignature (); + if (CurrentRevision != LatestRevision) { + AcquireSpinLock(&CpuMpData->MpLock); + DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \ + loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision)); + ReleaseSpinLock(&CpuMpData->MpLock); + } + } +} + +/** + Determine if a microcode patch matchs the specific processor signature and flag. + + @param[in] CpuMpData The pointer to CPU MP Data structure. + @param[in] ProcessorSignature The processor signature field value + supported by a microcode patch. + @param[in] ProcessorFlags The prcessor flags field value supported by + a microcode patch. + + @retval TRUE The specified microcode patch will be loaded. + @retval FALSE The specified microcode patch will not be loaded. +**/ +BOOLEAN +IsProcessorMatchedMicrocodePatch ( + IN CPU_MP_DATA *CpuMpData, + IN UINT32 ProcessorSignature, + IN UINT32 ProcessorFlags + ) +{ + UINTN Index; + CPU_AP_DATA *CpuData; + + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + CpuData = &CpuMpData->CpuData[Index]; + if ((ProcessorSignature == CpuData->ProcessorSignature) && + (ProcessorFlags & (1 << CpuData->PlatformId)) != 0) { + return TRUE; + } + } + + return FALSE; +} + +/** + Check the 'ProcessorSignature' and 'ProcessorFlags' of the microcode + patch header with the CPUID and PlatformID of the processors within + system to decide if it will be copied into memory. + + @param[in] CpuMpData The pointer to CPU MP Data structure. + @param[in] MicrocodeEntryPoint The pointer to the microcode patch header. + + @retval TRUE The specified microcode patch need to be loaded. + @retval FALSE The specified microcode patch dosen't need to be loaded. +**/ +BOOLEAN +IsMicrocodePatchNeedLoad ( + IN CPU_MP_DATA *CpuMpData, + CPU_MICROCODE_HEADER *MicrocodeEntryPoint + ) +{ + BOOLEAN NeedLoad; + UINTN DataSize; + UINTN TotalSize; + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; + UINT32 ExtendedTableCount; + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; + UINTN Index; + + // + // Check the 'ProcessorSignature' and 'ProcessorFlags' in microcode patch header. + // + NeedLoad = IsProcessorMatchedMicrocodePatch ( + CpuMpData, + MicrocodeEntryPoint->ProcessorSignature.Uint32, + MicrocodeEntryPoint->ProcessorFlags + ); + + // + // If the Extended Signature Table exists, check if the processor is in the + // support list + // + DataSize = MicrocodeEntryPoint->DataSize; + TotalSize = (DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize; + if ((!NeedLoad) && (DataSize != 0) && + (TotalSize - DataSize > sizeof (CPU_MICROCODE_HEADER) + + sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER))) { + ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + + DataSize + sizeof (CPU_MICROCODE_HEADER)); + ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; + ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1); + + for (Index = 0; Index < ExtendedTableCount; Index ++) { + // + // Check the 'ProcessorSignature' and 'ProcessorFlag' of the Extended + // Signature Table entry with the CPUID and PlatformID of the processors + // within system to decide if it will be copied into memory + // + NeedLoad = IsProcessorMatchedMicrocodePatch ( + CpuMpData, + ExtendedTable->ProcessorSignature.Uint32, + ExtendedTable->ProcessorFlag + ); + if (NeedLoad) { + break; + } + ExtendedTable ++; + } + } + + return NeedLoad; +} + + +/** + Actual worker function that shadows the required microcode patches into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + @param[in] Patches The pointer to an array of information on + the microcode patches that will be loaded + into memory. + @param[in] PatchCount The number of microcode patches that will + be loaded into memory. + @param[in] TotalLoadSize The total size of all the microcode patches + to be loaded. +**/ +VOID +ShadowMicrocodePatchWorker ( + IN OUT CPU_MP_DATA *CpuMpData, + IN MICROCODE_PATCH_INFO *Patches, + IN UINTN PatchCount, + IN UINTN TotalLoadSize + ) +{ + UINTN Index; + VOID *MicrocodePatchInRam; + UINT8 *Walker; + + ASSERT ((Patches != NULL) && (PatchCount != 0)); + + MicrocodePatchInRam = AllocatePages (EFI_SIZE_TO_PAGES (TotalLoadSize)); + if (MicrocodePatchInRam == NULL) { + return; + } + + // + // Load all the required microcode patches into memory + // + for (Walker = MicrocodePatchInRam, Index = 0; Index < PatchCount; Index++) { + CopyMem ( + Walker, + (VOID *) Patches[Index].Address, + Patches[Index].Size + ); + Walker += Patches[Index].Size; + } + + // + // Update the microcode patch related fields in CpuMpData + // + CpuMpData->MicrocodePatchAddress = (UINTN) MicrocodePatchInRam; + CpuMpData->MicrocodePatchRegionSize = TotalLoadSize; + + DEBUG (( + DEBUG_INFO, + "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n", + __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize + )); + + return; +} + +/** + Shadow the required microcode patches data into memory according to PCD + PcdCpuMicrocodePatchAddress and PcdCpuMicrocodePatchRegionSize. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +ShadowMicrocodePatchByPcd ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN MicrocodeEnd; + UINTN DataSize; + UINTN TotalSize; + MICROCODE_PATCH_INFO *PatchInfoBuffer; + UINTN MaxPatchNumber; + UINTN PatchCount; + UINTN TotalLoadSize; + + // + // Initialize the microcode patch related fields in CpuMpData as the values + // specified by the PCD pair. If the microcode patches are loaded into memory, + // these fields will be updated. + // + CpuMpData->MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress); + CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize); + + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->MicrocodePatchAddress; + MicrocodeEnd = (UINTN) MicrocodeEntryPoint + + (UINTN) CpuMpData->MicrocodePatchRegionSize; + if ((MicrocodeEntryPoint == NULL) || ((UINTN) MicrocodeEntryPoint == MicrocodeEnd)) { + // + // There is no microcode patches + // + return; + } + + PatchCount = 0; + MaxPatchNumber = DEFAULT_MAX_MICROCODE_PATCH_NUM; + TotalLoadSize = 0; + PatchInfoBuffer = AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO)); + if (PatchInfoBuffer == NULL) { + return; + } + + // + // Process the header of each microcode patch within the region. + // The purpose is to decide which microcode patch(es) will be loaded into memory. + // + do { + if (MicrocodeEntryPoint->HeaderVersion != 0x1) { + // + // Padding data between the microcode patches, skip 1KB to check next entry. + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + continue; + } + + DataSize = MicrocodeEntryPoint->DataSize; + TotalSize = (DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize; + if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || + ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || + (DataSize & 0x3) != 0 || + (TotalSize & (SIZE_1KB - 1)) != 0 || + TotalSize < DataSize + ) { + // + // Not a valid microcode header, skip 1KB to check next entry. + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + continue; + } + + if (IsMicrocodePatchNeedLoad (CpuMpData, MicrocodeEntryPoint)) { + PatchCount++; + if (PatchCount > MaxPatchNumber) { + // + // Current 'PatchInfoBuffer' cannot hold the information, double the size + // and allocate a new buffer. + // + if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) { + // + // Overflow check for MaxPatchNumber + // + goto OnExit; + } + + PatchInfoBuffer = ReallocatePool ( + MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + PatchInfoBuffer + ); + if (PatchInfoBuffer == NULL) { + goto OnExit; + } + MaxPatchNumber = MaxPatchNumber * 2; + } + + // + // Store the information of this microcode patch + // + PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint; + PatchInfoBuffer[PatchCount - 1].Size = TotalSize; + TotalLoadSize += TotalSize; + } + + // + // Process the next microcode patch + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); + } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + + if (PatchCount != 0) { + DEBUG (( + DEBUG_INFO, + "%a: 0x%x microcode patches will be loaded into memory, with size 0x%x.\n", + __FUNCTION__, PatchCount, TotalLoadSize + )); + + ShadowMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, TotalLoadSize); + } + +OnExit: + if (PatchInfoBuffer != NULL) { + FreePool (PatchInfoBuffer); + } + return; +} + +/** + Shadow the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +ShadowMicrocodeUpdatePatch ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + EFI_STATUS Status; + + Status = PlatformShadowMicrocode (CpuMpData); + if (EFI_ERROR (Status)) { + ShadowMicrocodePatchByPcd (CpuMpData); + } +} + +/** + Get the cached microcode patch base address and size from the microcode patch + information cache HOB. + + @param[out] Address Base address of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + @param[out] RegionSize Size of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + + @retval TRUE The microcode patch information cache HOB is found. + @retval FALSE The microcode patch information cache HOB is not found. + +**/ +BOOLEAN +GetMicrocodePatchInfoFromHob ( + UINT64 *Address, + UINT64 *RegionSize + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EDKII_MICROCODE_PATCH_HOB *MicrocodePathHob; + + GuidHob = GetFirstGuidHob (&gEdkiiMicrocodePatchHobGuid); + if (GuidHob == NULL) { + DEBUG((DEBUG_INFO, "%a: Microcode patch cache HOB is not found.\n", __FUNCTION__)); + return FALSE; + } + + MicrocodePathHob = GET_GUID_HOB_DATA (GuidHob); + + *Address = MicrocodePathHob->MicrocodePatchAddress; + *RegionSize = MicrocodePathHob->MicrocodePatchRegionSize; + + DEBUG(( + DEBUG_INFO, "%a: MicrocodeBase = 0x%lx, MicrocodeSize = 0x%lx\n", + __FUNCTION__, *Address, *RegionSize + )); + + return TRUE; +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c new file mode 100644 index 000000000..ab7a8ed66 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -0,0 +1,2590 @@ +/** @file + CPU MP Initialize Library common functions. + + Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020, AMD Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" + +EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; + + +/** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +STATIC +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +/** + The function will check if BSP Execute Disable is enabled. + + DxeIpl may have enabled Execute Disable for BSP, APs need to + get the status and sync up the settings. + If BSP's CR0.Paging is not set, BSP execute Disble feature is + not working actually. + + @retval TRUE BSP Execute Disable is enabled. + @retval FALSE BSP Execute Disable is not enabled. +**/ +BOOLEAN +IsBspExecuteDisableEnabled ( + VOID + ) +{ + UINT32 Eax; + CPUID_EXTENDED_CPU_SIG_EDX Edx; + MSR_IA32_EFER_REGISTER EferMsr; + BOOLEAN Enabled; + IA32_CR0 Cr0; + + Enabled = FALSE; + Cr0.UintN = AsmReadCr0 (); + if (Cr0.Bits.PG != 0) { + // + // If CR0 Paging bit is set + // + AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL); + if (Eax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &Edx.Uint32); + // + // CPUID 0x80000001 + // Bit 20: Execute Disable Bit available. + // + if (Edx.Bits.NX != 0) { + EferMsr.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + // + // MSR 0xC0000080 + // Bit 11: Execute Disable Bit enable. + // + if (EferMsr.Bits.NXE != 0) { + Enabled = TRUE; + } + } + } + } + + return Enabled; +} + +/** + Worker function for SwitchBSP(). + + Worker function for SwitchBSP(), assigned to the AP which is intended + to become BSP. + + @param[in] Buffer Pointer to CPU MP Data +**/ +VOID +EFIAPI +FutureBSPProc ( + IN VOID *Buffer + ) +{ + CPU_MP_DATA *DataInHob; + + DataInHob = (CPU_MP_DATA *) Buffer; + AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo); +} + +/** + Get the Application Processors state. + + @param[in] CpuData The pointer to CPU_AP_DATA of specified AP + + @return The AP status +**/ +CPU_STATE +GetApState ( + IN CPU_AP_DATA *CpuData + ) +{ + return CpuData->State; +} + +/** + Set the Application Processors state. + + @param[in] CpuData The pointer to CPU_AP_DATA of specified AP + @param[in] State The AP status +**/ +VOID +SetApState ( + IN CPU_AP_DATA *CpuData, + IN CPU_STATE State + ) +{ + AcquireSpinLock (&CpuData->ApLock); + CpuData->State = State; + ReleaseSpinLock (&CpuData->ApLock); +} + +/** + Save BSP's local APIC timer setting. + + @param[in] CpuMpData Pointer to CPU MP Data +**/ +VOID +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 (); +} + +/** + Sync local APIC timer setting from BSP to AP. + + @param[in] CpuMpData Pointer to CPU MP Data +**/ +VOID +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 (); +} + +/** + Save the volatile registers required to be restored following INIT IPI. + + @param[out] VolatileRegisters Returns buffer saved the volatile resisters +**/ +VOID +SaveVolatileRegisters ( + OUT CPU_VOLATILE_REGISTERS *VolatileRegisters + ) +{ + CPUID_VERSION_INFO_EDX VersionInfoEdx; + + VolatileRegisters->Cr0 = AsmReadCr0 (); + VolatileRegisters->Cr3 = AsmReadCr3 (); + VolatileRegisters->Cr4 = AsmReadCr4 (); + + 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 + // + VolatileRegisters->Dr0 = AsmReadDr0 (); + VolatileRegisters->Dr1 = AsmReadDr1 (); + VolatileRegisters->Dr2 = AsmReadDr2 (); + VolatileRegisters->Dr3 = AsmReadDr3 (); + VolatileRegisters->Dr6 = AsmReadDr6 (); + VolatileRegisters->Dr7 = AsmReadDr7 (); + } + + AsmReadGdtr (&VolatileRegisters->Gdtr); + AsmReadIdtr (&VolatileRegisters->Idtr); + VolatileRegisters->Tr = AsmReadTr (); +} + +/** + 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 + ) +{ + CPUID_VERSION_INFO_EDX VersionInfoEdx; + IA32_TSS_DESCRIPTOR *Tss; + + AsmWriteCr3 (VolatileRegisters->Cr3); + 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); + } + } + + AsmWriteGdtr (&VolatileRegisters->Gdtr); + AsmWriteIdtr (&VolatileRegisters->Idtr); + if (VolatileRegisters->Tr != 0 && + VolatileRegisters->Tr < VolatileRegisters->Gdtr.Limit) { + Tss = (IA32_TSS_DESCRIPTOR *)(VolatileRegisters->Gdtr.Base + + VolatileRegisters->Tr); + if (Tss->Bits.P == 1) { + Tss->Bits.Type &= 0xD; // 1101 - Clear busy bit just in case + AsmWriteTr (VolatileRegisters->Tr); + } + } +} + +/** + Detect whether Mwait-monitor feature is supported. + + @retval TRUE Mwait-monitor feature is supported. + @retval FALSE Mwait-monitor feature is not supported. +**/ +BOOLEAN +IsMwaitSupport ( + VOID + ) +{ + CPUID_VERSION_INFO_ECX VersionInfoEcx; + + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL); + return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE; +} + +/** + Get AP loop mode. + + @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes. + + @return The AP loop mode. +**/ +UINT8 +GetApLoopMode ( + OUT UINT32 *MonitorFilterSize + ) +{ + UINT8 ApLoopMode; + CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx; + + ASSERT (MonitorFilterSize != NULL); + + ApLoopMode = PcdGet8 (PcdCpuApLoopMode); + ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop); + if (ApLoopMode == ApInMwaitLoop) { + if (!IsMwaitSupport ()) { + // + // If processor does not support MONITOR/MWAIT feature, + // force AP in Hlt-loop mode + // + ApLoopMode = ApInHltLoop; + } + } + + if (ApLoopMode != ApInMwaitLoop) { + *MonitorFilterSize = sizeof (UINT32); + } else { + // + // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes + // CPUID.[EAX=05H].EDX: C-states supported using MWAIT + // + AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &MonitorMwaitEbx.Uint32, NULL, NULL); + *MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize; + } + + return ApLoopMode; +} + +/** + Sort the APIC ID of all processors. + + This function sorts the APIC ID of all processors so that processor number is + assigned in the ascending order of APIC ID which eases MP debugging. + + @param[in] CpuMpData Pointer to PEI CPU MP Data +**/ +VOID +SortApicId ( + IN CPU_MP_DATA *CpuMpData + ) +{ + UINTN Index1; + UINTN Index2; + UINTN Index3; + UINT32 ApicId; + CPU_INFO_IN_HOB CpuInfo; + UINT32 ApCount; + CPU_INFO_IN_HOB *CpuInfoInHob; + volatile UINT32 *StartupApSignal; + + ApCount = CpuMpData->CpuCount - 1; + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + if (ApCount != 0) { + for (Index1 = 0; Index1 < ApCount; Index1++) { + Index3 = Index1; + // + // Sort key is the hardware default APIC ID + // + ApicId = CpuInfoInHob[Index1].ApicId; + for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) { + if (ApicId > CpuInfoInHob[Index2].ApicId) { + Index3 = Index2; + ApicId = CpuInfoInHob[Index2].ApicId; + } + } + if (Index3 != Index1) { + CopyMem (&CpuInfo, &CpuInfoInHob[Index3], sizeof (CPU_INFO_IN_HOB)); + CopyMem ( + &CpuInfoInHob[Index3], + &CpuInfoInHob[Index1], + sizeof (CPU_INFO_IN_HOB) + ); + CopyMem (&CpuInfoInHob[Index1], &CpuInfo, sizeof (CPU_INFO_IN_HOB)); + + // + // Also exchange the StartupApSignal. + // + StartupApSignal = CpuMpData->CpuData[Index3].StartupApSignal; + CpuMpData->CpuData[Index3].StartupApSignal = + CpuMpData->CpuData[Index1].StartupApSignal; + CpuMpData->CpuData[Index1].StartupApSignal = StartupApSignal; + } + } + + // + // Get the processor number for the BSP + // + ApicId = GetInitialApicId (); + for (Index1 = 0; Index1 < CpuMpData->CpuCount; Index1++) { + if (CpuInfoInHob[Index1].ApicId == ApicId) { + CpuMpData->BspNumber = (UINT32) Index1; + break; + } + } + } +} + +/** + Enable x2APIC mode on APs. + + @param[in, out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +ApFuncEnableX2Apic ( + IN OUT VOID *Buffer + ) +{ + SetApicMode (LOCAL_APIC_MODE_X2APIC); +} + +/** + Do sync on APs. + + @param[in, out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +ApInitializeSync ( + IN OUT VOID *Buffer + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN ProcessorNumber; + EFI_STATUS Status; + + CpuMpData = (CPU_MP_DATA *) Buffer; + Status = GetProcessorNumber (CpuMpData, &ProcessorNumber); + ASSERT_EFI_ERROR (Status); + // + // Load microcode on AP + // + MicrocodeDetect (CpuMpData, ProcessorNumber); + // + // Sync BSP's MTRR table to AP + // + MtrrSetAllMtrrs (&CpuMpData->MtrrTable); +} + +/** + Find the current Processor number by APIC ID. + + @param[in] CpuMpData Pointer to PEI CPU MP Data + @param[out] ProcessorNumber Return the pocessor number found + + @retval EFI_SUCCESS ProcessorNumber is found and returned. + @retval EFI_NOT_FOUND ProcessorNumber is not found. +**/ +EFI_STATUS +GetProcessorNumber ( + IN CPU_MP_DATA *CpuMpData, + OUT UINTN *ProcessorNumber + ) +{ + UINTN TotalProcessorNumber; + UINTN Index; + CPU_INFO_IN_HOB *CpuInfoInHob; + UINT32 CurrentApicId; + + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + + TotalProcessorNumber = CpuMpData->CpuCount; + CurrentApicId = GetApicId (); + for (Index = 0; Index < TotalProcessorNumber; Index ++) { + if (CpuInfoInHob[Index].ApicId == CurrentApicId) { + *ProcessorNumber = Index; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + 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 + ) +{ + 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; + ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + // + // Wait for all APs finished the initialization + // + while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) { + CpuPause (); + } + + + // + // 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. + // + X2Apic = FALSE; + if (CpuMpData->CpuCount > 255) { + // + // If there are more than 255 processor found, force to enable X2APIC + // + X2Apic = TRUE; + } else { + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + if (CpuInfoInHob[Index].InitialApicId >= 0xFF) { + X2Apic = TRUE; + break; + } + } + } + + if (X2Apic) { + DEBUG ((DEBUG_INFO, "Force x2APIC mode!\n")); + // + // Wakeup all APs to enable x2APIC mode + // + WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL, TRUE); + // + // Wait for all known APs finished + // + while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) { + CpuPause (); + } + // + // Enable x2APIC on BSP + // + SetApicMode (LOCAL_APIC_MODE_X2APIC); + // + // Set BSP/Aps state to IDLE + // + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); + } + } + DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ())); + // + // Sort BSP/Aps by CPU APIC ID in ascending order + // + SortApicId (CpuMpData); + + DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount)); + + return CpuMpData->CpuCount; +} + +/** + Initialize CPU AP Data when AP is wakeup at the first time. + + @param[in, out] CpuMpData Pointer to PEI CPU MP Data + @param[in] ProcessorNumber The handle number of processor + @param[in] BistData Processor BIST data + @param[in] ApTopOfStack Top of AP stack + +**/ +VOID +InitializeApData ( + IN OUT CPU_MP_DATA *CpuMpData, + IN UINTN ProcessorNumber, + IN UINT32 BistData, + IN UINT64 ApTopOfStack + ) +{ + CPU_INFO_IN_HOB *CpuInfoInHob; + MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr; + + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId (); + CpuInfoInHob[ProcessorNumber].ApicId = GetApicId (); + CpuInfoInHob[ProcessorNumber].Health = BistData; + CpuInfoInHob[ProcessorNumber].ApTopOfStack = ApTopOfStack; + + CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE; + CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE; + + // + // NOTE: PlatformId is not relevant on AMD platforms. + // + if (!StandardSignatureIsAuthenticAMD ()) { + PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID); + CpuMpData->CpuData[ProcessorNumber].PlatformId = (UINT8)PlatformIdMsr.Bits.PlatformId; + } + + AsmCpuid ( + CPUID_VERSION_INFO, + &CpuMpData->CpuData[ProcessorNumber].ProcessorSignature, + NULL, + NULL, + NULL + ); + + InitializeSpinLock(&CpuMpData->CpuData[ProcessorNumber].ApLock); + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle); +} + +/** + This function will be called from AP reset code if BSP uses WakeUpAP. + + @param[in] ExchangeInfo Pointer to the MP exchange info buffer + @param[in] ApIndex Number of current executing AP +**/ +VOID +EFIAPI +ApWakeupFunction ( + IN MP_CPU_EXCHANGE_INFO *ExchangeInfo, + IN UINTN ApIndex + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN ProcessorNumber; + EFI_AP_PROCEDURE Procedure; + VOID *Parameter; + UINT32 BistData; + volatile UINT32 *ApStartupSignalBuffer; + CPU_INFO_IN_HOB *CpuInfoInHob; + UINT64 ApTopOfStack; + UINTN CurrentApicMode; + + // + // AP finished assembly code and begin to execute C code + // + CpuMpData = ExchangeInfo->CpuMpData; + + // + // AP's local APIC settings will be lost after received INIT IPI + // We need to re-initialize them at here + // + ProgramVirtualWireMode (); + // + // Mask the LINT0 and LINT1 so that AP doesn't enter the system timer interrupt handler. + // + DisableLvtInterrupts (); + SyncLocalApicTimerSetting (CpuMpData); + + CurrentApicMode = GetApicMode (); + while (TRUE) { + if (CpuMpData->InitFlag == ApInitConfig) { + // + // Add CPU number + // + InterlockedIncrement ((UINT32 *) &CpuMpData->CpuCount); + ProcessorNumber = ApIndex; + // + // This is first time AP wakeup, get BIST information from AP stack + // + ApTopOfStack = CpuMpData->Buffer + (ProcessorNumber + 1) * CpuMpData->CpuApStackSize; + BistData = *(UINT32 *) ((UINTN) ApTopOfStack - sizeof (UINTN)); + // + // CpuMpData->CpuData[0].VolatileRegisters is initialized based on BSP environment, + // to initialize AP in InitConfig path. + // NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a different IDT shared by all APs. + // + RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE); + InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack); + ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; + + InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting); + } else { + // + // Execute AP function if AP is ready + // + GetProcessorNumber (CpuMpData, &ProcessorNumber); + // + // Clear AP start-up signal when AP waken up + // + ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; + InterlockedCompareExchange32 ( + (UINT32 *) ApStartupSignalBuffer, + WAKEUP_AP_SIGNAL, + 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[0].VolatileRegisters points to a + // different IDT shared by all APs. + // + RestoreVolatileRegisters (&CpuMpData->CpuData[0].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 (); + } + } + + if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) { + Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction; + Parameter = (VOID *) CpuMpData->CpuData[ProcessorNumber].ApFunctionArgument; + if (Procedure != NULL) { + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateBusy); + // + // Enable source debugging on AP function + // + EnableDebugAgent (); + // + // Invoke AP function here + // + Procedure (Parameter); + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + if (CpuMpData->SwitchBspFlag) { + // + // Re-get the processor number due to BSP/AP maybe exchange in AP function + // + GetProcessorNumber (CpuMpData, &ProcessorNumber); + CpuMpData->CpuData[ProcessorNumber].ApFunction = 0; + CpuMpData->CpuData[ProcessorNumber].ApFunctionArgument = 0; + ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal; + CpuInfoInHob[ProcessorNumber].ApTopOfStack = CpuInfoInHob[CpuMpData->NewBspNumber].ApTopOfStack; + } else { + if (CpuInfoInHob[ProcessorNumber].ApicId != GetApicId () || + CpuInfoInHob[ProcessorNumber].InitialApicId != GetInitialApicId ()) { + if (CurrentApicMode != GetApicMode ()) { + // + // If APIC mode change happened during AP function execution, + // we do not support APIC ID value changed. + // + ASSERT (FALSE); + CpuDeadLoop (); + } else { + // + // Re-get the CPU APICID and Initial APICID if they are changed + // + CpuInfoInHob[ProcessorNumber].ApicId = GetApicId (); + CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId (); + } + } + } + } + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateFinished); + } + } + + // + // AP finished executing C code + // + InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount); + + // + // Place AP is specified loop mode + // + if (CpuMpData->ApLoopMode == ApInHltLoop) { + // + // Save AP volatile registers + // + SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters); + // + // Place AP in HLT-loop + // + while (TRUE) { + DisableInterrupts (); + CpuSleep (); + CpuPause (); + } + } + while (TRUE) { + DisableInterrupts (); + if (CpuMpData->ApLoopMode == ApInMwaitLoop) { + // + // Place AP in MWAIT-loop + // + AsmMonitor ((UINTN) ApStartupSignalBuffer, 0, 0); + if (*ApStartupSignalBuffer != WAKEUP_AP_SIGNAL) { + // + // Check AP start-up signal again. + // If AP start-up signal is not set, place AP into + // the specified C-state + // + AsmMwait (CpuMpData->ApTargetCState << 4, 0); + } + } else if (CpuMpData->ApLoopMode == ApInRunLoop) { + // + // Place AP in Run-loop + // + CpuPause (); + } else { + ASSERT (FALSE); + } + + // + // If AP start-up signal is written, AP is waken up + // otherwise place AP in loop again + // + if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) { + break; + } + } + } +} + +/** + Wait for AP wakeup and write AP start-up signal till AP is waken up. + + @param[in] ApStartupSignalBuffer Pointer to AP wakeup signal +**/ +VOID +WaitApWakeup ( + IN volatile UINT32 *ApStartupSignalBuffer + ) +{ + // + // If AP is waken up, StartupApSignal should be cleared. + // Otherwise, write StartupApSignal again till AP waken up. + // + while (InterlockedCompareExchange32 ( + (UINT32 *) ApStartupSignalBuffer, + WAKEUP_AP_SIGNAL, + WAKEUP_AP_SIGNAL + ) != 0) { + CpuPause (); + } +} + +/** + This function will fill the exchange info structure. + + @param[in] CpuMpData Pointer to CPU MP Data + +**/ +VOID +FillExchangeInfoData ( + IN CPU_MP_DATA *CpuMpData + ) +{ + volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo; + UINTN Size; + IA32_SEGMENT_DESCRIPTOR *Selector; + IA32_CR4 Cr4; + + ExchangeInfo = CpuMpData->MpCpuExchangeInfo; + ExchangeInfo->Lock = 0; + ExchangeInfo->StackStart = CpuMpData->Buffer; + ExchangeInfo->StackSize = CpuMpData->CpuApStackSize; + ExchangeInfo->BufferStart = CpuMpData->WakeupBuffer; + ExchangeInfo->ModeOffset = CpuMpData->AddressMap.ModeEntryOffset; + + ExchangeInfo->CodeSegment = AsmReadCs (); + ExchangeInfo->DataSegment = AsmReadDs (); + + ExchangeInfo->Cr3 = AsmReadCr3 (); + + ExchangeInfo->CFunction = (UINTN) ApWakeupFunction; + ExchangeInfo->ApIndex = 0; + ExchangeInfo->NumApsExecuting = 0; + ExchangeInfo->InitFlag = (UINTN) CpuMpData->InitFlag; + ExchangeInfo->CpuInfo = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + ExchangeInfo->CpuMpData = CpuMpData; + + ExchangeInfo->EnableExecuteDisable = IsBspExecuteDisableEnabled (); + + ExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits; + + // + // We can check either CPUID(7).ECX[bit16] or check CR4.LA57[bit12] + // to determin whether 5-Level Paging is enabled. + // CPUID(7).ECX[bit16] shows CPU's capability, CR4.LA57[bit12] shows + // current system setting. + // Using latter way is simpler because it also eliminates the needs to + // check whether platform wants to enable it. + // + Cr4.UintN = AsmReadCr4 (); + ExchangeInfo->Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging)); + + // + // Get the BSP's data of GDT and IDT + // + AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile); + AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile); + + // + // Find a 32-bit code segment + // + Selector = (IA32_SEGMENT_DESCRIPTOR *)ExchangeInfo->GdtrProfile.Base; + Size = ExchangeInfo->GdtrProfile.Limit + 1; + while (Size > 0) { + if (Selector->Bits.L == 0 && Selector->Bits.Type >= 8) { + ExchangeInfo->ModeTransitionSegment = + (UINT16)((UINTN)Selector - ExchangeInfo->GdtrProfile.Base); + break; + } + Selector += 1; + Size -= sizeof (IA32_SEGMENT_DESCRIPTOR); + } + + // + // Copy all 32-bit code and 64-bit code into memory with type of + // EfiBootServicesCode to avoid page fault if NX memory protection is enabled. + // + if (CpuMpData->WakeupBufferHigh != 0) { + Size = CpuMpData->AddressMap.RendezvousFunnelSize - + CpuMpData->AddressMap.ModeTransitionOffset; + CopyMem ( + (VOID *)CpuMpData->WakeupBufferHigh, + CpuMpData->AddressMap.RendezvousFunnelAddress + + CpuMpData->AddressMap.ModeTransitionOffset, + Size + ); + + ExchangeInfo->ModeTransitionMemory = (UINT32)CpuMpData->WakeupBufferHigh; + } else { + ExchangeInfo->ModeTransitionMemory = (UINT32) + (ExchangeInfo->BufferStart + CpuMpData->AddressMap.ModeTransitionOffset); + } + + ExchangeInfo->ModeHighMemory = ExchangeInfo->ModeTransitionMemory + + (UINT32)ExchangeInfo->ModeOffset - + (UINT32)CpuMpData->AddressMap.ModeTransitionOffset; + ExchangeInfo->ModeHighSegment = (UINT16)ExchangeInfo->CodeSegment; +} + +/** + Helper function that waits until the finished AP count reaches the specified + limit, or the specified timeout elapses (whichever comes first). + + @param[in] CpuMpData Pointer to CPU MP Data. + @param[in] FinishedApLimit The number of finished APs to wait for. + @param[in] TimeLimit The number of microseconds to wait for. +**/ +VOID +TimedWaitForApFinish ( + IN CPU_MP_DATA *CpuMpData, + IN UINT32 FinishedApLimit, + IN UINT32 TimeLimit + ); + +/** + Get available system memory below 1MB by specified size. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +BackupAndPrepareWakeupBuffer( + IN CPU_MP_DATA *CpuMpData + ) +{ + CopyMem ( + (VOID *) CpuMpData->BackupBuffer, + (VOID *) CpuMpData->WakeupBuffer, + CpuMpData->BackupBufferSize + ); + CopyMem ( + (VOID *) CpuMpData->WakeupBuffer, + (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, + CpuMpData->AddressMap.RendezvousFunnelSize + ); +} + +/** + Restore wakeup buffer data. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +RestoreWakeupBuffer( + IN CPU_MP_DATA *CpuMpData + ) +{ + CopyMem ( + (VOID *) CpuMpData->WakeupBuffer, + (VOID *) CpuMpData->BackupBuffer, + CpuMpData->BackupBufferSize + ); +} + +/** + Allocate reset vector buffer. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +AllocateResetVector ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + UINTN ApResetVectorSize; + + if (CpuMpData->WakeupBuffer == (UINTN) -1) { + ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + + sizeof (MP_CPU_EXCHANGE_INFO); + + CpuMpData->WakeupBuffer = GetWakeupBuffer (ApResetVectorSize); + CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) + (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize); + CpuMpData->WakeupBufferHigh = GetModeTransitionBuffer ( + CpuMpData->AddressMap.RendezvousFunnelSize - + CpuMpData->AddressMap.ModeTransitionOffset + ); + } + BackupAndPrepareWakeupBuffer (CpuMpData); +} + +/** + Free AP reset vector buffer. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +FreeResetVector ( + IN CPU_MP_DATA *CpuMpData + ) +{ + RestoreWakeupBuffer (CpuMpData); +} + +/** + This function will be called by BSP to wakeup AP. + + @param[in] CpuMpData Pointer to CPU MP Data + @param[in] Broadcast TRUE: Send broadcast IPI to all APs + FALSE: Send IPI to AP by ApicId + @param[in] ProcessorNumber The handle number of specified processor + @param[in] Procedure The function to be invoked by AP + @param[in] ProcedureArgument The argument to be passed into AP function + @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode. +**/ +VOID +WakeUpAP ( + IN CPU_MP_DATA *CpuMpData, + IN BOOLEAN Broadcast, + IN UINTN ProcessorNumber, + IN EFI_AP_PROCEDURE Procedure, OPTIONAL + IN VOID *ProcedureArgument, OPTIONAL + IN BOOLEAN WakeUpDisabledAps + ) +{ + volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo; + UINTN Index; + CPU_AP_DATA *CpuData; + BOOLEAN ResetVectorRequired; + CPU_INFO_IN_HOB *CpuInfoInHob; + + CpuMpData->FinishedCount = 0; + ResetVectorRequired = FALSE; + + if (CpuMpData->WakeUpByInitSipiSipi || + CpuMpData->InitFlag != ApInitDone) { + ResetVectorRequired = TRUE; + AllocateResetVector (CpuMpData); + FillExchangeInfoData (CpuMpData); + SaveLocalApicTimerSetting (CpuMpData); + } + + if (CpuMpData->ApLoopMode == ApInMwaitLoop) { + // + // Get AP target C-state each time when waking up AP, + // for it maybe updated by platform again + // + CpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate); + } + + ExchangeInfo = CpuMpData->MpCpuExchangeInfo; + + if (Broadcast) { + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + if (Index != CpuMpData->BspNumber) { + CpuData = &CpuMpData->CpuData[Index]; + // + // All AP(include disabled AP) will be woke up by INIT-SIPI-SIPI, but + // the AP procedure will be skipped for disabled AP because AP state + // is not CpuStateReady. + // + if (GetApState (CpuData) == CpuStateDisabled && !WakeUpDisabledAps) { + continue; + } + + CpuData->ApFunction = (UINTN) Procedure; + CpuData->ApFunctionArgument = (UINTN) ProcedureArgument; + SetApState (CpuData, CpuStateReady); + if (CpuMpData->InitFlag != ApInitConfig) { + *(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL; + } + } + } + if (ResetVectorRequired) { + // + // Wakeup all APs + // + SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart); + } + if (CpuMpData->InitFlag == ApInitConfig) { + if (PcdGet32 (PcdCpuBootLogicalProcessorNumber) > 0) { + // + // The AP enumeration algorithm below is suitable only when the + // platform can tell us the *exact* boot CPU count in advance. + // + // The wait below finishes only when the detected AP count reaches + // (PcdCpuBootLogicalProcessorNumber - 1), regardless of how long that + // takes. If at least one AP fails to check in (meaning a platform + // hardware bug), the detection hangs forever, by design. If the actual + // boot CPU count in the system is higher than + // PcdCpuBootLogicalProcessorNumber (meaning a platform + // misconfiguration), then some APs may complete initialization after + // the wait finishes, and cause undefined behavior. + // + TimedWaitForApFinish ( + CpuMpData, + PcdGet32 (PcdCpuBootLogicalProcessorNumber) - 1, + MAX_UINT32 // approx. 71 minutes + ); + } else { + // + // The AP enumeration algorithm below is suitable for two use cases. + // + // (1) The check-in time for an individual AP is bounded, and APs run + // through their initialization routines strongly concurrently. In + // particular, the number of concurrently running APs + // ("NumApsExecuting") is never expected to fall to zero + // *temporarily* -- it is expected to fall to zero only when all + // APs have checked-in. + // + // In this case, the platform is supposed to set + // PcdCpuApInitTimeOutInMicroSeconds to a low-ish value (just long + // enough for one AP to start initialization). The timeout will be + // reached soon, and remaining APs are collected by watching + // NumApsExecuting fall to zero. If NumApsExecuting falls to zero + // mid-process, while some APs have not completed initialization, + // the behavior is undefined. + // + // (2) The check-in time for an individual AP is unbounded, and/or APs + // may complete their initializations widely spread out. In + // particular, some APs may finish initialization before some APs + // even start. + // + // In this case, the platform is supposed to set + // PcdCpuApInitTimeOutInMicroSeconds to a high-ish value. The AP + // enumeration will always take that long (except when the boot CPU + // count happens to be maximal, that is, + // PcdCpuMaxLogicalProcessorNumber). All APs are expected to + // check-in before the timeout, and NumApsExecuting is assumed zero + // at timeout. APs that miss the time-out may cause undefined + // behavior. + // + TimedWaitForApFinish ( + CpuMpData, + PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1, + PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds) + ); + + while (CpuMpData->MpCpuExchangeInfo->NumApsExecuting != 0) { + CpuPause(); + } + } + } else { + // + // Wait all APs waken up if this is not the 1st broadcast of SIPI + // + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + CpuData = &CpuMpData->CpuData[Index]; + if (Index != CpuMpData->BspNumber) { + WaitApWakeup (CpuData->StartupApSignal); + } + } + } + } else { + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + CpuData->ApFunction = (UINTN) Procedure; + CpuData->ApFunctionArgument = (UINTN) ProcedureArgument; + SetApState (CpuData, CpuStateReady); + // + // Wakeup specified AP + // + ASSERT (CpuMpData->InitFlag != ApInitConfig); + *(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL; + if (ResetVectorRequired) { + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + SendInitSipiSipi ( + CpuInfoInHob[ProcessorNumber].ApicId, + (UINT32) ExchangeInfo->BufferStart + ); + } + // + // Wait specified AP waken up + // + WaitApWakeup (CpuData->StartupApSignal); + } + + if (ResetVectorRequired) { + FreeResetVector (CpuMpData); + } + + // + // After one round of Wakeup Ap actions, need to re-sync ApLoopMode with + // WakeUpByInitSipiSipi flag. WakeUpByInitSipiSipi flag maybe changed by + // S3SmmInitDone Ppi. + // + CpuMpData->WakeUpByInitSipiSipi = (CpuMpData->ApLoopMode == ApInHltLoop); +} + +/** + Calculate timeout value and return the current performance counter value. + + Calculate the number of performance counter ticks required for a timeout. + If TimeoutInMicroseconds is 0, return value is also 0, which is recognized + as infinity. + + @param[in] TimeoutInMicroseconds Timeout value in microseconds. + @param[out] CurrentTime Returns the current value of the performance counter. + + @return Expected time stamp counter for timeout. + If TimeoutInMicroseconds is 0, return value is also 0, which is recognized + as infinity. + +**/ +UINT64 +CalculateTimeout ( + IN UINTN TimeoutInMicroseconds, + OUT UINT64 *CurrentTime + ) +{ + UINT64 TimeoutInSeconds; + UINT64 TimestampCounterFreq; + + // + // Read the current value of the performance counter + // + *CurrentTime = GetPerformanceCounter (); + + // + // If TimeoutInMicroseconds is 0, return value is also 0, which is recognized + // as infinity. + // + if (TimeoutInMicroseconds == 0) { + return 0; + } + + // + // GetPerformanceCounterProperties () returns the timestamp counter's frequency + // in Hz. + // + TimestampCounterFreq = GetPerformanceCounterProperties (NULL, NULL); + + // + // Check the potential overflow before calculate the number of ticks for the timeout value. + // + if (DivU64x64Remainder (MAX_UINT64, TimeoutInMicroseconds, NULL) < TimestampCounterFreq) { + // + // Convert microseconds into seconds if direct multiplication overflows + // + TimeoutInSeconds = DivU64x32 (TimeoutInMicroseconds, 1000000); + // + // Assertion if the final tick count exceeds MAX_UINT64 + // + ASSERT (DivU64x64Remainder (MAX_UINT64, TimeoutInSeconds, NULL) >= TimestampCounterFreq); + return MultU64x64 (TimestampCounterFreq, TimeoutInSeconds); + } else { + // + // No overflow case, multiply the return value with TimeoutInMicroseconds and then divide + // it by 1,000,000, to get the number of ticks for the timeout value. + // + return DivU64x32 ( + MultU64x64 ( + TimestampCounterFreq, + TimeoutInMicroseconds + ), + 1000000 + ); + } +} + +/** + Checks whether timeout expires. + + Check whether the number of elapsed performance counter ticks required for + a timeout condition has been reached. + If Timeout is zero, which means infinity, return value is always FALSE. + + @param[in, out] PreviousTime On input, the value of the performance counter + when it was last read. + On output, the current value of the performance + counter + @param[in] TotalTime The total amount of elapsed time in performance + counter ticks. + @param[in] Timeout The number of performance counter ticks required + to reach a timeout condition. + + @retval TRUE A timeout condition has been reached. + @retval FALSE A timeout condition has not been reached. + +**/ +BOOLEAN +CheckTimeout ( + IN OUT UINT64 *PreviousTime, + IN UINT64 *TotalTime, + IN UINT64 Timeout + ) +{ + UINT64 Start; + UINT64 End; + UINT64 CurrentTime; + INT64 Delta; + INT64 Cycle; + + if (Timeout == 0) { + return FALSE; + } + GetPerformanceCounterProperties (&Start, &End); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + CurrentTime = GetPerformanceCounter(); + Delta = (INT64) (CurrentTime - *PreviousTime); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + *TotalTime += Delta; + *PreviousTime = CurrentTime; + if (*TotalTime > Timeout) { + return TRUE; + } + return FALSE; +} + +/** + Helper function that waits until the finished AP count reaches the specified + limit, or the specified timeout elapses (whichever comes first). + + @param[in] CpuMpData Pointer to CPU MP Data. + @param[in] FinishedApLimit The number of finished APs to wait for. + @param[in] TimeLimit The number of microseconds to wait for. +**/ +VOID +TimedWaitForApFinish ( + IN CPU_MP_DATA *CpuMpData, + IN UINT32 FinishedApLimit, + IN UINT32 TimeLimit + ) +{ + // + // CalculateTimeout() and CheckTimeout() consider a TimeLimit of 0 + // "infinity", so check for (TimeLimit == 0) explicitly. + // + if (TimeLimit == 0) { + return; + } + + CpuMpData->TotalTime = 0; + CpuMpData->ExpectedTime = CalculateTimeout ( + TimeLimit, + &CpuMpData->CurrentTime + ); + while (CpuMpData->FinishedCount < FinishedApLimit && + !CheckTimeout ( + &CpuMpData->CurrentTime, + &CpuMpData->TotalTime, + CpuMpData->ExpectedTime + )) { + CpuPause (); + } + + if (CpuMpData->FinishedCount >= FinishedApLimit) { + DEBUG (( + DEBUG_VERBOSE, + "%a: reached FinishedApLimit=%u in %Lu microseconds\n", + __FUNCTION__, + FinishedApLimit, + DivU64x64Remainder ( + MultU64x32 (CpuMpData->TotalTime, 1000000), + GetPerformanceCounterProperties (NULL, NULL), + NULL + ) + )); + } +} + +/** + Reset an AP to Idle state. + + Any task being executed by the AP will be aborted and the AP + will be waiting for a new task in Wait-For-SIPI state. + + @param[in] ProcessorNumber The handle number of processor. +**/ +VOID +ResetProcessorToIdleState ( + IN UINTN ProcessorNumber + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + + CpuMpData->InitFlag = ApInitReconfig; + WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE); + while (CpuMpData->FinishedCount < 1) { + CpuPause (); + } + CpuMpData->InitFlag = ApInitDone; + + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle); +} + +/** + Searches for the next waiting AP. + + Search for the next AP that is put in waiting state by single-threaded StartupAllAPs(). + + @param[out] NextProcessorNumber Pointer to the processor number of the next waiting AP. + + @retval EFI_SUCCESS The next waiting AP has been found. + @retval EFI_NOT_FOUND No waiting AP exists. + +**/ +EFI_STATUS +GetNextWaitingProcessorNumber ( + OUT UINTN *NextProcessorNumber + ) +{ + UINTN ProcessorNumber; + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + + for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) { + if (CpuMpData->CpuData[ProcessorNumber].Waiting) { + *NextProcessorNumber = ProcessorNumber; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** Checks status of specified AP. + + This function checks whether the specified AP has finished the task assigned + by StartupThisAP(), and whether timeout expires. + + @param[in] ProcessorNumber The handle number of processor. + + @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckThisAP ( + IN UINTN ProcessorNumber + ) +{ + CPU_MP_DATA *CpuMpData; + CPU_AP_DATA *CpuData; + + CpuMpData = GetCpuMpData (); + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + + // + // Check the CPU state of AP. If it is CpuStateIdle, then the AP has finished its task. + // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the + // value of state after setting the it to CpuStateIdle, so BSP can safely make use of its value. + // + // + // If the AP finishes for StartupThisAP(), return EFI_SUCCESS. + // + if (GetApState(CpuData) == CpuStateFinished) { + if (CpuData->Finished != NULL) { + *(CpuData->Finished) = TRUE; + } + SetApState (CpuData, CpuStateIdle); + return EFI_SUCCESS; + } else { + // + // If timeout expires for StartupThisAP(), report timeout. + // + if (CheckTimeout (&CpuData->CurrentTime, &CpuData->TotalTime, CpuData->ExpectedTime)) { + if (CpuData->Finished != NULL) { + *(CpuData->Finished) = FALSE; + } + // + // Reset failed AP to idle state + // + ResetProcessorToIdleState (ProcessorNumber); + + return EFI_TIMEOUT; + } + } + return EFI_NOT_READY; +} + +/** + Checks status of all APs. + + This function checks whether all APs have finished task assigned by StartupAllAPs(), + and whether timeout expires. + + @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY APs have not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckAllAPs ( + VOID + ) +{ + UINTN ProcessorNumber; + UINTN NextProcessorNumber; + UINTN ListIndex; + EFI_STATUS Status; + CPU_MP_DATA *CpuMpData; + CPU_AP_DATA *CpuData; + + CpuMpData = GetCpuMpData (); + + NextProcessorNumber = 0; + + // + // Go through all APs that are responsible for the StartupAllAPs(). + // + for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) { + if (!CpuMpData->CpuData[ProcessorNumber].Waiting) { + continue; + } + + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + // + // Check the CPU state of AP. If it is CpuStateIdle, then the AP has finished its task. + // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the + // value of state after setting the it to CpuStateIdle, so BSP can safely make use of its value. + // + if (GetApState(CpuData) == CpuStateFinished) { + CpuMpData->RunningCount --; + CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE; + SetApState(CpuData, CpuStateIdle); + + // + // If in Single Thread mode, then search for the next waiting AP for execution. + // + if (CpuMpData->SingleThread) { + Status = GetNextWaitingProcessorNumber (&NextProcessorNumber); + + if (!EFI_ERROR (Status)) { + WakeUpAP ( + CpuMpData, + FALSE, + (UINT32) NextProcessorNumber, + CpuMpData->Procedure, + CpuMpData->ProcArguments, + TRUE + ); + } + } + } + } + + // + // If all APs finish, return EFI_SUCCESS. + // + if (CpuMpData->RunningCount == 0) { + return EFI_SUCCESS; + } + + // + // If timeout expires, report timeout. + // + if (CheckTimeout ( + &CpuMpData->CurrentTime, + &CpuMpData->TotalTime, + CpuMpData->ExpectedTime) + ) { + // + // If FailedCpuList is not NULL, record all failed APs in it. + // + if (CpuMpData->FailedCpuList != NULL) { + *CpuMpData->FailedCpuList = + AllocatePool ((CpuMpData->RunningCount + 1) * sizeof (UINTN)); + ASSERT (*CpuMpData->FailedCpuList != NULL); + } + ListIndex = 0; + + for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) { + // + // Check whether this processor is responsible for StartupAllAPs(). + // + if (CpuMpData->CpuData[ProcessorNumber].Waiting) { + // + // Reset failed APs to idle state + // + ResetProcessorToIdleState (ProcessorNumber); + CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE; + if (CpuMpData->FailedCpuList != NULL) { + (*CpuMpData->FailedCpuList)[ListIndex++] = ProcessorNumber; + } + } + } + if (CpuMpData->FailedCpuList != NULL) { + (*CpuMpData->FailedCpuList)[ListIndex] = END_OF_CPU_LIST; + } + return EFI_TIMEOUT; + } + return EFI_NOT_READY; +} + +/** + MP Initialize Library initialization. + + This service will allocate AP reset vector and wakeup all APs to do APs + initialization. + + This service must be invoked before all other MP Initialize Library + service are invoked. + + @retval EFI_SUCCESS MP initialization succeeds. + @retval Others MP initialization fails. + +**/ +EFI_STATUS +EFIAPI +MpInitLibInitialize ( + VOID + ) +{ + CPU_MP_DATA *OldCpuMpData; + CPU_INFO_IN_HOB *CpuInfoInHob; + UINT32 MaxLogicalProcessorNumber; + UINT32 ApStackSize; + MP_ASSEMBLY_ADDRESS_MAP AddressMap; + CPU_VOLATILE_REGISTERS VolatileRegisters; + UINTN BufferSize; + UINT32 MonitorFilterSize; + VOID *MpBuffer; + UINTN Buffer; + CPU_MP_DATA *CpuMpData; + UINT8 ApLoopMode; + UINT8 *MonitorBuffer; + UINTN Index; + UINTN ApResetVectorSize; + UINTN BackupBufferAddr; + UINTN ApIdtBase; + + OldCpuMpData = GetCpuMpDataFromGuidedHob (); + if (OldCpuMpData == NULL) { + MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber); + } else { + MaxLogicalProcessorNumber = OldCpuMpData->CpuCount; + } + ASSERT (MaxLogicalProcessorNumber != 0); + + AsmGetAddressMap (&AddressMap); + ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO); + ApStackSize = PcdGet32(PcdCpuApStackSize); + ApLoopMode = GetApLoopMode (&MonitorFilterSize); + + // + // Save BSP's Control registers for APs. + // + SaveVolatileRegisters (&VolatileRegisters); + + BufferSize = ApStackSize * MaxLogicalProcessorNumber; + BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber; + BufferSize += ApResetVectorSize; + BufferSize = ALIGN_VALUE (BufferSize, 8); + BufferSize += VolatileRegisters.Idtr.Limit + 1; + BufferSize += sizeof (CPU_MP_DATA); + BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber; + MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize)); + ASSERT (MpBuffer != NULL); + ZeroMem (MpBuffer, BufferSize); + Buffer = (UINTN) MpBuffer; + + // + // The layout of the Buffer is as below: + // + // +--------------------+ <-- Buffer + // AP Stacks (N) + // +--------------------+ <-- MonitorBuffer + // AP Monitor Filters (N) + // +--------------------+ <-- BackupBufferAddr (CpuMpData->BackupBuffer) + // Backup Buffer + // +--------------------+ + // Padding + // +--------------------+ <-- ApIdtBase (8-byte boundary) + // AP IDT All APs share one separate IDT. So AP can get address of CPU_MP_DATA from IDT Base. + // +--------------------+ <-- CpuMpData + // CPU_MP_DATA + // +--------------------+ <-- CpuMpData->CpuData + // CPU_AP_DATA (N) + // +--------------------+ <-- CpuMpData->CpuInfoInHob + // CPU_INFO_IN_HOB (N) + // +--------------------+ + // + MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber); + BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber; + ApIdtBase = ALIGN_VALUE (BackupBufferAddr + ApResetVectorSize, 8); + CpuMpData = (CPU_MP_DATA *) (ApIdtBase + VolatileRegisters.Idtr.Limit + 1); + CpuMpData->Buffer = Buffer; + CpuMpData->CpuApStackSize = ApStackSize; + CpuMpData->BackupBuffer = BackupBufferAddr; + CpuMpData->BackupBufferSize = ApResetVectorSize; + CpuMpData->WakeupBuffer = (UINTN) -1; + CpuMpData->CpuCount = 1; + CpuMpData->BspNumber = 0; + CpuMpData->WaitEvent = NULL; + CpuMpData->SwitchBspFlag = FALSE; + CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1); + CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber); + InitializeSpinLock(&CpuMpData->MpLock); + + // + // Make sure no memory usage outside of the allocated buffer. + // + ASSERT ((CpuMpData->CpuInfoInHob + sizeof (CPU_INFO_IN_HOB) * MaxLogicalProcessorNumber) == + Buffer + BufferSize); + + // + // Duplicate BSP's IDT to APs. + // All APs share one separate IDT. So AP can get the address of CpuMpData by using IDTR.BASE + IDTR.LIMIT + 1 + // + CopyMem ((VOID *)ApIdtBase, (VOID *)VolatileRegisters.Idtr.Base, VolatileRegisters.Idtr.Limit + 1); + VolatileRegisters.Idtr.Base = ApIdtBase; + // + // Don't pass BSP's TR to APs to avoid AP init failure. + // + VolatileRegisters.Tr = 0; + CopyMem (&CpuMpData->CpuData[0].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters)); + // + // Set BSP basic information + // + InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer + ApStackSize); + // + // Save assembly code information + // + CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP)); + // + // Finally set AP loop mode + // + CpuMpData->ApLoopMode = ApLoopMode; + DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode)); + + CpuMpData->WakeUpByInitSipiSipi = (CpuMpData->ApLoopMode == ApInHltLoop); + + // + // Set up APs wakeup signal buffer + // + for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) { + CpuMpData->CpuData[Index].StartupApSignal = + (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index); + } + // + // Enable the local APIC for Virtual Wire Mode. + // + ProgramVirtualWireMode (); + + if (OldCpuMpData == NULL) { + if (MaxLogicalProcessorNumber > 1) { + // + // Wakeup all APs and calculate the processor count in system + // + CollectProcessorCount (CpuMpData); + } + } else { + // + // APs have been wakeup before, just get the CPU Information + // from HOB + // + CpuMpData->CpuCount = OldCpuMpData->CpuCount; + CpuMpData->BspNumber = OldCpuMpData->BspNumber; + CpuMpData->CpuInfoInHob = OldCpuMpData->CpuInfoInHob; + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock); + CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE; + CpuMpData->CpuData[Index].ApFunction = 0; + } + } + + if (!GetMicrocodePatchInfoFromHob ( + &CpuMpData->MicrocodePatchAddress, + &CpuMpData->MicrocodePatchRegionSize + )) { + // + // The microcode patch information cache HOB does not exist, which means + // the microcode patches data has not been loaded into memory yet + // + ShadowMicrocodeUpdatePatch (CpuMpData); + } + + // + // Detect and apply Microcode on BSP + // + MicrocodeDetect (CpuMpData, CpuMpData->BspNumber); + // + // Store BSP's MTRR setting + // + MtrrGetAllMtrrs (&CpuMpData->MtrrTable); + + // + // Wakeup APs to do some AP initialize sync (Microcode & MTRR) + // + if (CpuMpData->CpuCount > 1) { + if (OldCpuMpData != 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 + // + while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) { + CpuPause (); + } + if (OldCpuMpData != NULL) { + CpuMpData->InitFlag = ApInitDone; + } + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); + } + } + + // + // Initialize global data for MP support + // + InitMpGlobalData (CpuMpData); + + return EFI_SUCCESS; +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN CallerNumber; + CPU_INFO_IN_HOB *CpuInfoInHob; + UINTN OriginalProcessorNumber; + + CpuMpData = GetCpuMpData (); + CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + + // + // Lower 24 bits contains the actual processor number. + // + OriginalProcessorNumber = ProcessorNumber; + ProcessorNumber &= BIT24 - 1; + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + if (ProcessorInfoBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (ProcessorNumber >= CpuMpData->CpuCount) { + return EFI_NOT_FOUND; + } + + ProcessorInfoBuffer->ProcessorId = (UINT64) CpuInfoInHob[ProcessorNumber].ApicId; + ProcessorInfoBuffer->StatusFlag = 0; + if (ProcessorNumber == CpuMpData->BspNumber) { + ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT; + } + if (CpuMpData->CpuData[ProcessorNumber].CpuHealthy) { + ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT; + } + if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateDisabled) { + ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT; + } else { + ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT; + } + + // + // Get processor location information + // + GetProcessorLocationByApicId ( + CpuInfoInHob[ProcessorNumber].ApicId, + &ProcessorInfoBuffer->Location.Package, + &ProcessorInfoBuffer->Location.Core, + &ProcessorInfoBuffer->Location.Thread + ); + + if ((OriginalProcessorNumber & CPU_V2_EXTENDED_TOPOLOGY) != 0) { + GetProcessorLocation2ByApicId ( + CpuInfoInHob[ProcessorNumber].ApicId, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Package, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Die, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Tile, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Module, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Core, + &ProcessorInfoBuffer->ExtendedInformation.Location2.Thread + ); + } + + if (HealthData != NULL) { + HealthData->Uint32 = CpuInfoInHob[ProcessorNumber].Health; + } + + return EFI_SUCCESS; +} + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval others Failed to switch BSP. + +**/ +EFI_STATUS +SwitchBSPWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN CallerNumber; + CPU_STATE State; + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + BOOLEAN OldInterruptState; + BOOLEAN OldTimerInterruptState; + + // + // Save and Disable Local APIC timer interrupt + // + OldTimerInterruptState = GetApicTimerInterruptState (); + DisableApicTimerInterrupt (); + // + // Before send both BSP and AP to a procedure to exchange their roles, + // interrupt must be disabled. This is because during the exchange role + // process, 2 CPU may use 1 stack. If interrupt happens, the stack will + // be corrupted, since interrupt return address will be pushed to stack + // by hardware. + // + OldInterruptState = SaveAndDisableInterrupts (); + + // + // Mask LINT0 & LINT1 for the old BSP + // + DisableLvtInterrupts (); + + CpuMpData = GetCpuMpData (); + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + if (ProcessorNumber >= CpuMpData->CpuCount) { + return EFI_NOT_FOUND; + } + + // + // Check whether specified AP is disabled + // + State = GetApState (&CpuMpData->CpuData[ProcessorNumber]); + if (State == CpuStateDisabled) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether ProcessorNumber specifies the current BSP + // + if (ProcessorNumber == CpuMpData->BspNumber) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether specified AP is busy + // + if (State == CpuStateBusy) { + return EFI_NOT_READY; + } + + CpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE; + CpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE; + CpuMpData->SwitchBspFlag = TRUE; + CpuMpData->NewBspNumber = ProcessorNumber; + + // + // Clear the BSP bit of MSR_IA32_APIC_BASE + // + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Bits.BSP = 0; + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + + // + // Need to wakeUp AP (future BSP). + // + WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData, TRUE); + + AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); + + // + // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP + // + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Bits.BSP = 1; + AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + ProgramVirtualWireMode (); + + // + // Wait for old BSP finished AP task + // + while (GetApState (&CpuMpData->CpuData[CallerNumber]) != CpuStateFinished) { + CpuPause (); + } + + CpuMpData->SwitchBspFlag = FALSE; + // + // Set old BSP enable state + // + if (!EnableOldBSP) { + SetApState (&CpuMpData->CpuData[CallerNumber], CpuStateDisabled); + } else { + SetApState (&CpuMpData->CpuData[CallerNumber], CpuStateIdle); + } + // + // Save new BSP number + // + CpuMpData->BspNumber = (UINT32) ProcessorNumber; + + // + // Restore interrupt state. + // + SetInterruptState (OldInterruptState); + + if (OldTimerInterruptState) { + EnableApicTimerInterrupt (); + } + + return EFI_SUCCESS; +} + +/** + Worker function to let the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval others Failed to Enable/Disable AP. + +**/ +EFI_STATUS +EnableDisableApWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN CallerNumber; + + CpuMpData = GetCpuMpData (); + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + if (ProcessorNumber == CpuMpData->BspNumber) { + return EFI_INVALID_PARAMETER; + } + + if (ProcessorNumber >= CpuMpData->CpuCount) { + return EFI_NOT_FOUND; + } + + if (!EnableAP) { + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateDisabled); + } else { + ResetProcessorToIdleState (ProcessorNumber); + } + + if (HealthFlag != NULL) { + CpuMpData->CpuData[ProcessorNumber].CpuHealthy = + (BOOLEAN) ((*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT) != 0); + } + + return EFI_SUCCESS; +} + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibWhoAmI ( + OUT UINTN *ProcessorNumber + ) +{ + CPU_MP_DATA *CpuMpData; + + if (ProcessorNumber == NULL) { + return EFI_INVALID_PARAMETER; + } + + CpuMpData = GetCpuMpData (); + + return GetProcessorNumber (CpuMpData, ProcessorNumber); +} + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ) +{ + CPU_MP_DATA *CpuMpData; + UINTN CallerNumber; + UINTN ProcessorNumber; + UINTN EnabledProcessorNumber; + UINTN Index; + + CpuMpData = GetCpuMpData (); + + if ((NumberOfProcessors == NULL) && (NumberOfEnabledProcessors == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + ProcessorNumber = CpuMpData->CpuCount; + EnabledProcessorNumber = 0; + for (Index = 0; Index < ProcessorNumber; Index++) { + if (GetApState (&CpuMpData->CpuData[Index]) != CpuStateDisabled) { + EnabledProcessorNumber ++; + } + } + + if (NumberOfProcessors != NULL) { + *NumberOfProcessors = ProcessorNumber; + } + if (NumberOfEnabledProcessors != NULL) { + *NumberOfEnabledProcessors = EnabledProcessorNumber; + } + + return EFI_SUCCESS; +} + + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] ExcludeBsp Whether let BSP also trig this task. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval others Failed to Startup all APs. + +**/ +EFI_STATUS +StartupAllCPUsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN BOOLEAN ExcludeBsp, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ) +{ + EFI_STATUS Status; + CPU_MP_DATA *CpuMpData; + UINTN ProcessorCount; + UINTN ProcessorNumber; + UINTN CallerNumber; + CPU_AP_DATA *CpuData; + BOOLEAN HasEnabledAp; + CPU_STATE ApState; + + CpuMpData = GetCpuMpData (); + + if (FailedCpuList != NULL) { + *FailedCpuList = NULL; + } + + if (CpuMpData->CpuCount == 1 && ExcludeBsp) { + return EFI_NOT_STARTED; + } + + if (Procedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + // + // Update AP state + // + CheckAndUpdateApsStatus (); + + ProcessorCount = CpuMpData->CpuCount; + HasEnabledAp = FALSE; + // + // Check whether all enabled APs are idle. + // If any enabled AP is not idle, return EFI_NOT_READY. + // + for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) { + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + if (ProcessorNumber != CpuMpData->BspNumber) { + ApState = GetApState (CpuData); + if (ApState != CpuStateDisabled) { + HasEnabledAp = TRUE; + if (ApState != CpuStateIdle) { + // + // If any enabled APs are busy, return EFI_NOT_READY. + // + return EFI_NOT_READY; + } + } + } + } + + if (!HasEnabledAp && ExcludeBsp) { + // + // If no enabled AP exists and not include Bsp to do the procedure, return EFI_NOT_STARTED. + // + return EFI_NOT_STARTED; + } + + CpuMpData->RunningCount = 0; + for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) { + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + CpuData->Waiting = FALSE; + if (ProcessorNumber != CpuMpData->BspNumber) { + if (CpuData->State == CpuStateIdle) { + // + // Mark this processor as responsible for current calling. + // + CpuData->Waiting = TRUE; + CpuMpData->RunningCount++; + } + } + } + + CpuMpData->Procedure = Procedure; + CpuMpData->ProcArguments = ProcedureArgument; + CpuMpData->SingleThread = SingleThread; + CpuMpData->FinishedCount = 0; + CpuMpData->FailedCpuList = FailedCpuList; + CpuMpData->ExpectedTime = CalculateTimeout ( + TimeoutInMicroseconds, + &CpuMpData->CurrentTime + ); + CpuMpData->TotalTime = 0; + CpuMpData->WaitEvent = WaitEvent; + + if (!SingleThread) { + WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument, FALSE); + } else { + for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) { + if (ProcessorNumber == CallerNumber) { + continue; + } + if (CpuMpData->CpuData[ProcessorNumber].Waiting) { + WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument, TRUE); + break; + } + } + } + + if (!ExcludeBsp) { + // + // Start BSP. + // + Procedure (ProcedureArgument); + } + + Status = EFI_SUCCESS; + if (WaitEvent == NULL) { + do { + Status = CheckAllAPs (); + } while (Status == EFI_NOT_READY); + } + + return Status; +} + +/** + Worker function to let the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] ProcessorNumber The handle number of the AP. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] Finished If AP returns from Procedure before the + timeout expires, its content is set to TRUE. + Otherwise, the value is set to FALSE. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval others Failed to Startup AP. + +**/ +EFI_STATUS +StartupThisAPWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ) +{ + EFI_STATUS Status; + CPU_MP_DATA *CpuMpData; + CPU_AP_DATA *CpuData; + UINTN CallerNumber; + + CpuMpData = GetCpuMpData (); + + if (Finished != NULL) { + *Finished = FALSE; + } + + // + // Check whether caller processor is BSP + // + MpInitLibWhoAmI (&CallerNumber); + if (CallerNumber != CpuMpData->BspNumber) { + return EFI_DEVICE_ERROR; + } + + // + // Check whether processor with the handle specified by ProcessorNumber exists + // + if (ProcessorNumber >= CpuMpData->CpuCount) { + return EFI_NOT_FOUND; + } + + // + // Check whether specified processor is BSP + // + if (ProcessorNumber == CpuMpData->BspNumber) { + return EFI_INVALID_PARAMETER; + } + + // + // Check parameter Procedure + // + if (Procedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Update AP state + // + CheckAndUpdateApsStatus (); + + // + // Check whether specified AP is disabled + // + if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateDisabled) { + return EFI_INVALID_PARAMETER; + } + + // + // If WaitEvent is not NULL, execute in non-blocking mode. + // BSP saves data for CheckAPsStatus(), and returns EFI_SUCCESS. + // CheckAPsStatus() will check completion and timeout periodically. + // + CpuData = &CpuMpData->CpuData[ProcessorNumber]; + CpuData->WaitEvent = WaitEvent; + CpuData->Finished = Finished; + CpuData->ExpectedTime = CalculateTimeout (TimeoutInMicroseconds, &CpuData->CurrentTime); + CpuData->TotalTime = 0; + + WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument, TRUE); + + // + // If WaitEvent is NULL, execute in blocking mode. + // BSP checks AP's state until it finishes or TimeoutInMicrosecsond expires. + // + Status = EFI_SUCCESS; + if (WaitEvent == NULL) { + do { + Status = CheckThisAP (ProcessorNumber); + } while (Status == EFI_NOT_READY); + } + + return Status; +} + +/** + Get pointer to CPU MP Data structure from GUIDed HOB. + + @return The pointer to CPU MP Data structure. +**/ +CPU_MP_DATA * +GetCpuMpDataFromGuidedHob ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + VOID *DataInHob; + CPU_MP_DATA *CpuMpData; + + CpuMpData = NULL; + GuidHob = GetFirstGuidHob (&mCpuInitMpLibHobGuid); + if (GuidHob != NULL) { + DataInHob = GET_GUID_HOB_DATA (GuidHob); + CpuMpData = (CPU_MP_DATA *) (*(UINTN *) DataInHob); + } + return CpuMpData; +} + +/** + This service executes a caller provided function on all enabled CPUs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. TimeoutInMicroseconds is ignored + for BSP. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + + @retval EFI_SUCCESS In blocking mode, all CPUs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled CPUs. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllCPUs ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + return StartupAllCPUsWorker ( + Procedure, + FALSE, + FALSE, + NULL, + TimeoutInMicroseconds, + ProcedureArgument, + NULL + ); +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h new file mode 100644 index 000000000..a8ca03efb --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -0,0 +1,678 @@ +/** @file + Common header file for MP Initialize Library. + + Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020, AMD Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MP_LIB_H_ +#define _MP_LIB_H_ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') + +#define CPU_INIT_MP_LIB_HOB_GUID \ + { \ + 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \ + } + +// +// The MP data for switch BSP +// +#define CPU_SWITCH_STATE_IDLE 0 +#define CPU_SWITCH_STATE_STORED 1 +#define CPU_SWITCH_STATE_LOADED 2 + +// +// Default maximum number of entries to store the microcode patches information +// +#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 + +// +// Data structure for microcode patch information +// +typedef struct { + UINTN Address; + UINTN Size; +} MICROCODE_PATCH_INFO; + +// +// CPU exchange information for switch BSP +// +typedef struct { + UINT8 State; // offset 0 + UINTN StackPointer; // offset 4 / 8 + IA32_DESCRIPTOR Gdtr; // offset 8 / 16 + IA32_DESCRIPTOR Idtr; // offset 14 / 26 +} CPU_EXCHANGE_ROLE_INFO; + +// +// AP loop state when APs are in idle state +// It's value is the same with PcdCpuApLoopMode +// +typedef enum { + ApInHltLoop = 1, + ApInMwaitLoop = 2, + ApInRunLoop = 3 +} AP_LOOP_MODE; + +// +// AP initialization state during APs wakeup +// +typedef enum { + ApInitConfig = 1, + ApInitReconfig = 2, + ApInitDone = 3 +} AP_INIT_STATE; + +// +// AP state +// +// The state transitions for an AP when it process a procedure are: +// Idle ----> Ready ----> Busy ----> Idle +// [BSP] [AP] [AP] +// +typedef enum { + CpuStateIdle, + CpuStateReady, + CpuStateBusy, + CpuStateFinished, + CpuStateDisabled +} CPU_STATE; + +// +// CPU volatile registers around INIT-SIPI-SIPI +// +typedef struct { + UINTN Cr0; + UINTN Cr3; + UINTN Cr4; + UINTN Dr0; + UINTN Dr1; + UINTN Dr2; + UINTN Dr3; + UINTN Dr6; + UINTN Dr7; + IA32_DESCRIPTOR Gdtr; + IA32_DESCRIPTOR Idtr; + UINT16 Tr; +} CPU_VOLATILE_REGISTERS; + +// +// AP related data +// +typedef struct { + SPIN_LOCK ApLock; + volatile UINT32 *StartupApSignal; + volatile UINTN ApFunction; + volatile UINTN ApFunctionArgument; + BOOLEAN CpuHealthy; + volatile CPU_STATE State; + CPU_VOLATILE_REGISTERS VolatileRegisters; + BOOLEAN Waiting; + BOOLEAN *Finished; + UINT64 ExpectedTime; + UINT64 CurrentTime; + UINT64 TotalTime; + EFI_EVENT WaitEvent; + UINT32 ProcessorSignature; + UINT8 PlatformId; + UINT64 MicrocodeEntryAddr; +} CPU_AP_DATA; + +// +// Basic CPU information saved in Guided HOB. +// Because the contents will be shard between PEI and DXE, +// we need to make sure the each fields offset same in different +// architecture. +// +#pragma pack (1) +typedef struct { + UINT32 InitialApicId; + UINT32 ApicId; + UINT32 Health; + UINT64 ApTopOfStack; +} CPU_INFO_IN_HOB; +#pragma pack () + +// +// AP reset code information including code address and size, +// this structure will be shared be C code and assembly code. +// It is natural aligned by design. +// +typedef struct { + UINT8 *RendezvousFunnelAddress; + UINTN ModeEntryOffset; + UINTN RendezvousFunnelSize; + UINT8 *RelocateApLoopFuncAddress; + UINTN RelocateApLoopFuncSize; + UINTN ModeTransitionOffset; +} MP_ASSEMBLY_ADDRESS_MAP; + +typedef struct _CPU_MP_DATA CPU_MP_DATA; + +#pragma pack(1) + +// +// MP CPU exchange information for AP reset code +// This structure is required to be packed because fixed field offsets +// into this structure are used in assembly code in this module +// +typedef struct { + UINTN Lock; + UINTN StackStart; + UINTN StackSize; + UINTN CFunction; + IA32_DESCRIPTOR GdtrProfile; + IA32_DESCRIPTOR IdtrProfile; + UINTN BufferStart; + UINTN ModeOffset; + UINTN ApIndex; + UINTN CodeSegment; + UINTN DataSegment; + UINTN EnableExecuteDisable; + UINTN Cr3; + UINTN InitFlag; + CPU_INFO_IN_HOB *CpuInfo; + UINTN NumApsExecuting; + CPU_MP_DATA *CpuMpData; + UINTN InitializeFloatingPointUnitsAddress; + UINT32 ModeTransitionMemory; + UINT16 ModeTransitionSegment; + UINT32 ModeHighMemory; + UINT16 ModeHighSegment; + // + // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode. + // + BOOLEAN Enable5LevelPaging; +} MP_CPU_EXCHANGE_INFO; + +#pragma pack() + +// +// CPU MP Data save in memory +// +struct _CPU_MP_DATA { + UINT64 CpuInfoInHob; + UINT32 CpuCount; + UINT32 BspNumber; + // + // The above fields data will be passed from PEI to DXE + // Please make sure the fields offset same in the different + // architecture. + // + SPIN_LOCK MpLock; + UINTN Buffer; + UINTN CpuApStackSize; + MP_ASSEMBLY_ADDRESS_MAP AddressMap; + UINTN WakeupBuffer; + UINTN WakeupBufferHigh; + UINTN BackupBuffer; + UINTN BackupBufferSize; + + volatile UINT32 FinishedCount; + UINT32 RunningCount; + BOOLEAN SingleThread; + EFI_AP_PROCEDURE Procedure; + VOID *ProcArguments; + BOOLEAN *Finished; + UINT64 ExpectedTime; + UINT64 CurrentTime; + UINT64 TotalTime; + EFI_EVENT WaitEvent; + UINTN **FailedCpuList; + + AP_INIT_STATE InitFlag; + BOOLEAN SwitchBspFlag; + UINTN NewBspNumber; + CPU_EXCHANGE_ROLE_INFO BSPInfo; + CPU_EXCHANGE_ROLE_INFO APInfo; + MTRR_SETTINGS MtrrTable; + UINT8 ApLoopMode; + UINT8 ApTargetCState; + UINT16 PmCodeSegment; + CPU_AP_DATA *CpuData; + volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo; + + UINT32 CurrentTimerCount; + UINTN DivideValue; + UINT8 Vector; + BOOLEAN PeriodicMode; + BOOLEAN TimerInterruptState; + UINT64 MicrocodePatchAddress; + UINT64 MicrocodePatchRegionSize; + + // + // Whether need to use Init-Sipi-Sipi to wake up the APs. + // Two cases need to set this value to TRUE. One is in HLT + // loop mode, the other is resume from S3 which loop mode + // will be hardcode change to HLT mode by PiSmmCpuDxeSmm + // driver. + // + BOOLEAN WakeUpByInitSipiSipi; +}; + +extern EFI_GUID mCpuInitMpLibHobGuid; + +/** + Assembly code to place AP into safe loop mode. + + Place AP into targeted C-State if MONITOR is supported, otherwise + place AP into hlt state. + Place AP in protected mode if the current is long mode. Due to AP maybe + wakeup by some hardware event. It could avoid accessing page table that + may not available during booting to OS. + + @param[in] MwaitSupport TRUE indicates MONITOR is supported. + FALSE indicates MONITOR is not supported. + @param[in] ApTargetCState Target C-State value. + @param[in] PmCodeSegment Protected mode code segment value. +**/ +typedef +VOID +(EFIAPI * ASM_RELOCATE_AP_LOOP) ( + IN BOOLEAN MwaitSupport, + IN UINTN ApTargetCState, + IN UINTN PmCodeSegment, + IN UINTN TopOfApStack, + IN UINTN NumberToFinish + ); + +/** + Assembly code to get starting address and size of the rendezvous entry for APs. + Information for fixing a jump instruction in the code is also returned. + + @param[out] AddressMap Output buffer for address map information. +**/ +VOID +EFIAPI +AsmGetAddressMap ( + OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap + ); + +/** + This function is called by both the BSP and the AP which is to become the BSP to + Exchange execution context including stack between them. After return from this + function, the BSP becomes AP and the AP becomes the BSP. + + @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor. + @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer. + +**/ +VOID +EFIAPI +AsmExchangeRole ( + IN CPU_EXCHANGE_ROLE_INFO *MyInfo, + IN CPU_EXCHANGE_ROLE_INFO *OthersInfo + ); + +/** + Get the pointer to CPU MP Data structure. + + @return The pointer to CPU MP Data structure. +**/ +CPU_MP_DATA * +GetCpuMpData ( + VOID + ); + +/** + Save the pointer to CPU MP Data structure. + + @param[in] CpuMpData The pointer to CPU MP Data structure will be saved. +**/ +VOID +SaveCpuMpData ( + IN CPU_MP_DATA *CpuMpData + ); + + +/** + Get available system memory below 1MB by specified size. + + @param[in] WakeupBufferSize Wakeup buffer size required + + @retval other Return wakeup buffer address below 1MB. + @retval -1 Cannot find free memory below 1MB. +**/ +UINTN +GetWakeupBuffer ( + IN UINTN WakeupBufferSize + ); + +/** + Get available EfiBootServicesCode memory below 4GB by specified size. + + This buffer is required to safely transfer AP from real address mode to + protected mode or long mode, due to the fact that the buffer returned by + GetWakeupBuffer() may be marked as non-executable. + + @param[in] BufferSize Wakeup transition buffer size. + + @retval other Return wakeup transition buffer address below 4GB. + @retval 0 Cannot find free memory below 4GB. +**/ +UINTN +GetModeTransitionBuffer ( + IN UINTN BufferSize + ); + +/** + This function will be called by BSP to wakeup AP. + + @param[in] CpuMpData Pointer to CPU MP Data + @param[in] Broadcast TRUE: Send broadcast IPI to all APs + FALSE: Send IPI to AP by ApicId + @param[in] ProcessorNumber The handle number of specified processor + @param[in] Procedure The function to be invoked by AP + @param[in] ProcedureArgument The argument to be passed into AP function + @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode. +**/ +VOID +WakeUpAP ( + IN CPU_MP_DATA *CpuMpData, + IN BOOLEAN Broadcast, + IN UINTN ProcessorNumber, + IN EFI_AP_PROCEDURE Procedure, OPTIONAL + IN VOID *ProcedureArgument, OPTIONAL + IN BOOLEAN WakeUpDisabledAps OPTIONAL + ); + +/** + Initialize global data for MP support. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +InitMpGlobalData ( + IN CPU_MP_DATA *CpuMpData + ); + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] ExcludeBsp Whether let BSP also trig this task. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval others Failed to Startup all APs. + +**/ +EFI_STATUS +StartupAllCPUsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN BOOLEAN ExcludeBsp, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + Worker function to let the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] ProcessorNumber The handle number of the AP. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] Finished If AP returns from Procedure before the + timeout expires, its content is set to TRUE. + Otherwise, the value is set to FALSE. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval others Failed to Startup AP. + +**/ +EFI_STATUS +StartupThisAPWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval others Failed to switch BSP. + +**/ +EFI_STATUS +SwitchBSPWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + Worker function to let the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval others Failed to Enable/Disable AP. + +**/ +EFI_STATUS +EnableDisableApWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + Get pointer to CPU MP Data structure from GUIDed HOB. + + @return The pointer to CPU MP Data structure. +**/ +CPU_MP_DATA * +GetCpuMpDataFromGuidedHob ( + VOID + ); + +/** Checks status of specified AP. + + This function checks whether the specified AP has finished the task assigned + by StartupThisAP(), and whether timeout expires. + + @param[in] ProcessorNumber The handle number of processor. + + @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckThisAP ( + IN UINTN ProcessorNumber + ); + +/** + Checks status of all APs. + + This function checks whether all APs have finished task assigned by StartupAllAPs(), + and whether timeout expires. + + @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY APs have not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckAllAPs ( + VOID + ); + +/** + Checks APs status and updates APs status if needed. + +**/ +VOID +CheckAndUpdateApsStatus ( + VOID + ); + +/** + Detect whether specified processor can find matching microcode patch and load it. + + @param[in] CpuMpData The pointer to CPU MP Data structure. + @param[in] ProcessorNumber The handle number of the processor. The range is + from 0 to the total number of logical processors + minus 1. +**/ +VOID +MicrocodeDetect ( + IN CPU_MP_DATA *CpuMpData, + IN UINTN ProcessorNumber + ); + +/** + Shadow the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +ShadowMicrocodeUpdatePatch ( + IN OUT CPU_MP_DATA *CpuMpData + ); + +/** + Get the cached microcode patch base address and size from the microcode patch + information cache HOB. + + @param[out] Address Base address of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + @param[out] RegionSize Size of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + + @retval TRUE The microcode patch information cache HOB is found. + @retval FALSE The microcode patch information cache HOB is not found. + +**/ +BOOLEAN +GetMicrocodePatchInfoFromHob ( + UINT64 *Address, + UINT64 *RegionSize + ); + +/** + Detect whether Mwait-monitor feature is supported. + + @retval TRUE Mwait-monitor feature is supported. + @retval FALSE Mwait-monitor feature is not supported. +**/ +BOOLEAN +IsMwaitSupport ( + VOID + ); + +/** + Enable Debug Agent to support source debugging on AP function. + +**/ +VOID +EnableDebugAgent ( + VOID + ); + +/** + Find the current Processor number by APIC ID. + + @param[in] CpuMpData Pointer to PEI CPU MP Data + @param[out] ProcessorNumber Return the pocessor number found + + @retval EFI_SUCCESS ProcessorNumber is found and returned. + @retval EFI_NOT_FOUND ProcessorNumber is not found. +**/ +EFI_STATUS +GetProcessorNumber ( + IN CPU_MP_DATA *CpuMpData, + OUT UINTN *ProcessorNumber + ); + +/** + This funtion will try to invoke platform specific microcode shadow logic to + relocate microcode update patches into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + + @retval EFI_SUCCESS Shadow microcode success. + @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation. + @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow + PPI/Protocol. +**/ +EFI_STATUS +PlatformShadowMicrocode ( + IN OUT CPU_MP_DATA *CpuMpData + ); + +#endif + diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf new file mode 100644 index 000000000..89ee9a79d --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -0,0 +1,70 @@ +## @file +# MP Initialize Library instance for PEI driver. +# +# Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiMpInitLib + MODULE_UNI_FILE = PeiMpInitLib.uni + FILE_GUID = B00F6090-7739-4830-B906-E0032D388987 + MODULE_TYPE = PEIM + VERSION_STRING = 1.1 + LIBRARY_CLASS = MpInitLib|PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.IA32] + Ia32/MpEqu.inc + Ia32/MpFuncs.nasm + +[Sources.X64] + X64/MpEqu.inc + X64/MpFuncs.nasm + +[Sources.common] + PeiMpLib.c + MpLib.c + MpLib.h + Microcode.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + LocalApicLib + MemoryAllocationLib + HobLib + MtrrLib + CpuLib + UefiCpuLib + SynchronizationLib + PeiServicesLib + PcdLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES + +[Ppis] + gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES + +[Guids] + gEdkiiS3SmmInitDoneGuid + gEdkiiMicrocodePatchHobGuid diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni new file mode 100644 index 000000000..81eca4e06 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni @@ -0,0 +1,16 @@ +// /** @file +// MP Initialize Library instance for PEI driver. +// +// MP Initialize Library instance for PEI driver. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "MP Initialize Library instance for PEI driver." + +#string STR_MODULE_DESCRIPTION #language en-US "MP Initialize Library instance for PEI driver." + diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c new file mode 100644 index 000000000..a548fed23 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -0,0 +1,710 @@ +/** @file + MP initialize support functions for PEI phase. + + Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" +#include +#include +#include + +/** + S3 SMM Init Done notification function. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDesc Address of the notification descriptor data structure. + @param InvokePpi Address of the PPI that was invoked. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +NotifyOnS3SmmInitDonePpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ); + + +// +// Global function +// +EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEdkiiS3SmmInitDoneGuid, + NotifyOnS3SmmInitDonePpi +}; + +/** + S3 SMM Init Done notification function. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDesc Address of the notification descriptor data structure. + @param InvokePpi Address of the PPI that was invoked. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +NotifyOnS3SmmInitDonePpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ) +{ + CPU_MP_DATA *CpuMpData; + + CpuMpData = GetCpuMpData (); + + // + // PiSmmCpuDxeSmm driver hardcode change the loop mode to HLT mode. + // So in this notify function, code need to check the current loop + // mode, if it is not HLT mode, code need to change loop mode back + // to the original mode. + // + if (CpuMpData->ApLoopMode != ApInHltLoop) { + CpuMpData->WakeUpByInitSipiSipi = TRUE; + } + + return EFI_SUCCESS; +} + + +/** + Enable Debug Agent to support source debugging on AP function. + +**/ +VOID +EnableDebugAgent ( + VOID + ) +{ +} + +/** + Get pointer to CPU MP Data structure. + For BSP, the pointer is retrieved from HOB. + For AP, the structure is just after IDT. + + @return The pointer to CPU MP Data structure. +**/ +CPU_MP_DATA * +GetCpuMpData ( + VOID + ) +{ + CPU_MP_DATA *CpuMpData; + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; + IA32_DESCRIPTOR Idtr; + + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + if (ApicBaseMsr.Bits.BSP == 1) { + CpuMpData = GetCpuMpDataFromGuidedHob (); + ASSERT (CpuMpData != NULL); + } else { + AsmReadIdtr (&Idtr); + CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1); + } + return CpuMpData; +} + +/** + Save the pointer to CPU MP Data structure. + + @param[in] CpuMpData The pointer to CPU MP Data structure will be saved. +**/ +VOID +SaveCpuMpData ( + IN CPU_MP_DATA *CpuMpData + ) +{ + UINT64 Data64; + // + // Build location of CPU MP DATA buffer in HOB + // + Data64 = (UINT64) (UINTN) CpuMpData; + BuildGuidDataHob ( + &mCpuInitMpLibHobGuid, + (VOID *) &Data64, + sizeof (UINT64) + ); +} + +/** + Check if AP wakeup buffer is overlapped with existing allocated buffer. + + @param[in] WakeupBufferStart AP wakeup buffer start address. + @param[in] WakeupBufferEnd AP wakeup buffer end address. + + @retval TRUE There is overlap. + @retval FALSE There is no overlap. +**/ +BOOLEAN +CheckOverlapWithAllocatedBuffer ( + IN UINT64 WakeupBufferStart, + IN UINT64 WakeupBufferEnd + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryHob; + BOOLEAN Overlapped; + UINT64 MemoryStart; + UINT64 MemoryEnd; + + Overlapped = FALSE; + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + MemoryHob = Hob.MemoryAllocation; + MemoryStart = MemoryHob->AllocDescriptor.MemoryBaseAddress; + MemoryEnd = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength; + if (!((WakeupBufferStart >= MemoryEnd) || (WakeupBufferEnd <= MemoryStart))) { + Overlapped = TRUE; + break; + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + return Overlapped; +} + +/** + Get available system memory below 1MB by specified size. + + @param[in] WakeupBufferSize Wakeup buffer size required + + @retval other Return wakeup buffer address below 1MB. + @retval -1 Cannot find free memory below 1MB. +**/ +UINTN +GetWakeupBuffer ( + IN UINTN WakeupBufferSize + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT64 WakeupBufferStart; + UINT64 WakeupBufferEnd; + + WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1); + + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if ((Hob.ResourceDescriptor->PhysicalStart < BASE_1MB) && + (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && + ((Hob.ResourceDescriptor->ResourceAttribute & + (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | + EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | + EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED + )) == 0) + ) { + // + // Need memory under 1MB to be collected here + // + WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength; + if (WakeupBufferEnd > BASE_1MB) { + // + // Wakeup buffer should be under 1MB + // + WakeupBufferEnd = BASE_1MB; + } + while (WakeupBufferEnd > WakeupBufferSize) { + // + // Wakeup buffer should be aligned on 4KB + // + WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1); + if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) { + break; + } + if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) { + // + // If this range is overlapped with existing allocated buffer, skip it + // and find the next range + // + WakeupBufferEnd -= WakeupBufferSize; + continue; + } + DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n", + WakeupBufferStart, WakeupBufferSize)); + return (UINTN)WakeupBufferStart; + } + } + } + // + // Find the next HOB + // + Hob.Raw = GET_NEXT_HOB (Hob); + } + + return (UINTN) -1; +} + +/** + Get available EfiBootServicesCode memory below 4GB by specified size. + + This buffer is required to safely transfer AP from real address mode to + protected mode or long mode, due to the fact that the buffer returned by + GetWakeupBuffer() may be marked as non-executable. + + @param[in] BufferSize Wakeup transition buffer size. + + @retval other Return wakeup transition buffer address below 4GB. + @retval 0 Cannot find free memory below 4GB. +**/ +UINTN +GetModeTransitionBuffer ( + IN UINTN BufferSize + ) +{ + // + // PEI phase doesn't need to do such transition. So simply return 0. + // + return 0; +} + +/** + Checks APs status and updates APs status if needed. + +**/ +VOID +CheckAndUpdateApsStatus ( + VOID + ) +{ +} + +/** + Build the microcode patch HOB that contains the base address and size of the + microcode patch stored in the memory. + + @param[in] CpuMpData Pointer to the CPU_MP_DATA structure. + +**/ +VOID +BuildMicrocodeCacheHob ( + IN CPU_MP_DATA *CpuMpData + ) +{ + EDKII_MICROCODE_PATCH_HOB *MicrocodeHob; + UINTN HobDataLength; + UINT32 Index; + + HobDataLength = sizeof (EDKII_MICROCODE_PATCH_HOB) + + sizeof (UINT64) * CpuMpData->CpuCount; + + MicrocodeHob = AllocatePool (HobDataLength); + if (MicrocodeHob == NULL) { + ASSERT (FALSE); + return; + } + + // + // Store the information of the memory region that holds the microcode patches. + // + MicrocodeHob->MicrocodePatchAddress = CpuMpData->MicrocodePatchAddress; + MicrocodeHob->MicrocodePatchRegionSize = CpuMpData->MicrocodePatchRegionSize; + + // + // Store the detected microcode patch for each processor as well. + // + MicrocodeHob->ProcessorCount = CpuMpData->CpuCount; + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + if (CpuMpData->CpuData[Index].MicrocodeEntryAddr != 0) { + MicrocodeHob->ProcessorSpecificPatchOffset[Index] = + CpuMpData->CpuData[Index].MicrocodeEntryAddr - CpuMpData->MicrocodePatchAddress; + } else { + MicrocodeHob->ProcessorSpecificPatchOffset[Index] = MAX_UINT64; + } + } + + BuildGuidDataHob ( + &gEdkiiMicrocodePatchHobGuid, + MicrocodeHob, + HobDataLength + ); + + return; +} + +/** + Initialize global data for MP support. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +InitMpGlobalData ( + IN CPU_MP_DATA *CpuMpData + ) +{ + EFI_STATUS Status; + + BuildMicrocodeCacheHob (CpuMpData); + SaveCpuMpData (CpuMpData); + + /// + /// Install Notify + /// + Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc); + ASSERT_EFI_ERROR (Status); +} + +/** + This service executes a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by MpInitLibStartupAllAPs() or + MPInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Initialization + library, and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllAPs ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ) +{ + if (WaitEvent != NULL) { + return EFI_UNSUPPORTED; + } + + return StartupAllCPUsWorker ( + Procedure, + SingleThread, + TRUE, + NULL, + TimeoutInMicroseconds, + ProcedureArgument, + FailedCpuList + ); +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by MpInitLibStartupAllAPs() or + MpInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupThisAP ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ) +{ + if (WaitEvent != NULL) { + return EFI_UNSUPPORTED; + } + + return StartupThisAPWorker ( + Procedure, + ProcessorNumber, + NULL, + TimeoutInMicroseconds, + ProcedureArgument, + Finished + ); +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibSwitchBSP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + return SwitchBSPWorker (ProcessorNumber, EnableOldBSP); +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibEnableDisableAP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag); +} + +/** + This funtion will try to invoke platform specific microcode shadow logic to + relocate microcode update patches into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + + @retval EFI_SUCCESS Shadow microcode success. + @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation. + @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow + PPI/Protocol. +**/ +EFI_STATUS +PlatformShadowMicrocode ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + EFI_STATUS Status; + EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi; + UINTN CpuCount; + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId; + UINTN Index; + UINTN BufferSize; + VOID *Buffer; + + Status = PeiServicesLocatePpi ( + &gEdkiiPeiShadowMicrocodePpiGuid, + 0, + NULL, + (VOID **) &ShadowMicrocodePpi + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + CpuCount = CpuMpData->CpuCount; + MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount); + if (MicrocodeCpuId == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + MicrocodeCpuId[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature; + MicrocodeCpuId[Index].PlatformId = CpuMpData->CpuData[Index].PlatformId; + } + + Status = ShadowMicrocodePpi->ShadowMicrocode ( + ShadowMicrocodePpi, + CpuCount, + MicrocodeCpuId, + &BufferSize, + &Buffer + ); + FreePool (MicrocodeCpuId); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + CpuMpData->MicrocodePatchAddress = (UINTN) Buffer; + CpuMpData->MicrocodePatchRegionSize = BufferSize; + + DEBUG (( + DEBUG_INFO, + "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n", + __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize + )); + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc new file mode 100644 index 000000000..58ef36934 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpEqu.inc +; +; Abstract: +; +; This is the equates file for Multiple Processor support +; +;------------------------------------------------------------------------------- + +VacantFlag equ 00h +NotVacantFlag equ 0ffh + +CPU_SWITCH_STATE_IDLE equ 0 +CPU_SWITCH_STATE_STORED equ 1 +CPU_SWITCH_STATE_LOADED equ 2 + +LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart) +StackStartAddressLocation equ LockLocation + 08h +StackSizeLocation equ LockLocation + 10h +ApProcedureLocation equ LockLocation + 18h +GdtrLocation equ LockLocation + 20h +IdtrLocation equ LockLocation + 2Ah +BufferStartLocation equ LockLocation + 34h +ModeOffsetLocation equ LockLocation + 3Ch +ApIndexLocation equ LockLocation + 44h +CodeSegmentLocation equ LockLocation + 4Ch +DataSegmentLocation equ LockLocation + 54h +EnableExecuteDisableLocation equ LockLocation + 5Ch +Cr3Location equ LockLocation + 64h +InitFlagLocation equ LockLocation + 6Ch +CpuInfoLocation equ LockLocation + 74h +NumApsExecutingLocation equ LockLocation + 7Ch +InitializeFloatingPointUnitsAddress equ LockLocation + 8Ch +ModeTransitionMemoryLocation equ LockLocation + 94h +ModeTransitionSegmentLocation equ LockLocation + 98h +ModeHighMemoryLocation equ LockLocation + 9Ah +ModeHighSegmentLocation equ LockLocation + 9Eh +Enable5LevelPagingLocation equ LockLocation + 0A0h diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm new file mode 100644 index 000000000..87f2523e8 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm @@ -0,0 +1,433 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpFuncs.nasm +; +; Abstract: +; +; This is the assembly code for MP support +; +;------------------------------------------------------------------------------- + +%include "MpEqu.inc" +extern ASM_PFX(InitializeFloatingPointUnits) + +DEFAULT REL + +SECTION .text + +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc procedure follows. All APs execute their procedure. This +;procedure serializes all the AP processors through an Init sequence. It must be +;noted that APs arrive here very raw...ie: real mode, no stack. +;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC +;IS IN MACHINE CODE. +;------------------------------------------------------------------------------------- +global ASM_PFX(RendezvousFunnelProc) +ASM_PFX(RendezvousFunnelProc): +RendezvousFunnelProcStart: +; At this point CS = 0x(vv00) and ip= 0x0. +; Save BIST information to ebp firstly + +BITS 16 + mov ebp, eax ; Save BIST information + + mov ax, cs + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + + mov si, BufferStartLocation + mov ebx, [si] + + mov si, DataSegmentLocation + mov edx, [si] + + ; + ; Get start address of 32-bit code in low memory (<1MB) + ; + mov edi, ModeTransitionMemoryLocation + + mov si, GdtrLocation +o32 lgdt [cs:si] + + mov si, IdtrLocation +o32 lidt [cs:si] + + ; + ; Switch to protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 000000003h ; Set PE bit (bit #0) & MP + mov cr0, eax + + ; Switch to 32-bit code (>1MB) +o32 jmp far [cs:di] + +; +; Following code must be copied to memory with type of EfiBootServicesCode. +; This is required if NX is enabled for EfiBootServicesCode of memory. +; +BITS 32 +Flat32Start: ; protected mode entry point + mov ds, dx + mov es, dx + mov fs, dx + mov gs, dx + mov ss, dx + + ; + ; Enable execute disable bit + ; + mov esi, EnableExecuteDisableLocation + cmp byte [ebx + esi], 0 + jz SkipEnableExecuteDisableBit + + mov ecx, 0c0000080h ; EFER MSR number + rdmsr ; Read EFER + bts eax, 11 ; Enable Execute Disable Bit + wrmsr ; Write EFER + +SkipEnableExecuteDisableBit: + ; + ; Enable PAE + ; + mov eax, cr4 + bts eax, 5 + + mov esi, Enable5LevelPagingLocation + cmp byte [ebx + esi], 0 + jz SkipEnable5LevelPaging + + ; + ; Enable 5 Level Paging + ; + bts eax, 12 ; Set LA57=1. + +SkipEnable5LevelPaging: + + mov cr4, eax + + ; + ; Load page table + ; + mov esi, Cr3Location ; Save CR3 in ecx + mov ecx, [ebx + esi] + mov cr3, ecx ; Load CR3 + + ; + ; Enable long mode + ; + mov ecx, 0c0000080h ; EFER MSR number + rdmsr ; Read EFER + bts eax, 8 ; Set LME=1 + wrmsr ; Write EFER + + ; + ; Enable paging + ; + mov eax, cr0 ; Read CR0 + bts eax, 31 ; Set PG=1 + mov cr0, eax ; Write CR0 + + ; + ; Far jump to 64-bit code + ; + mov edi, ModeHighMemoryLocation + add edi, ebx + jmp far [edi] + +BITS 64 +LongModeStart: + mov esi, ebx + lea edi, [esi + InitFlagLocation] + cmp qword [edi], 1 ; ApInitConfig + jnz GetApicId + + ; Increment the number of APs executing here as early as possible + ; This is decremented in C code when AP is finished executing + mov edi, esi + add edi, NumApsExecutingLocation + lock inc dword [edi] + + ; AP init + mov edi, esi + add edi, LockLocation + mov rax, NotVacantFlag + +TestLock: + xchg qword [edi], rax + cmp rax, NotVacantFlag + jz TestLock + + lea ecx, [esi + ApIndexLocation] + inc dword [ecx] + mov ebx, [ecx] + +Releaselock: + mov rax, VacantFlag + xchg qword [edi], rax + ; program stack + mov edi, esi + add edi, StackSizeLocation + mov eax, dword [edi] + mov ecx, ebx + inc ecx + mul ecx ; EAX = StackSize * (CpuNumber + 1) + mov edi, esi + add edi, StackStartAddressLocation + add rax, qword [edi] + mov rsp, rax + jmp CProcedureInvoke + +GetApicId: + mov eax, 0 + cpuid + cmp eax, 0bh + jb NoX2Apic ; CPUID level below CPUID_EXTENDED_TOPOLOGY + + mov eax, 0bh + xor ecx, ecx + cpuid + test ebx, 0ffffh + jz NoX2Apic ; CPUID.0BH:EBX[15:0] is zero + + ; Processor is x2APIC capable; 32-bit x2APIC ID is already in EDX + jmp GetProcessorNumber + +NoX2Apic: + ; Processor is not x2APIC capable, so get 8-bit APIC ID + mov eax, 1 + cpuid + shr ebx, 24 + mov edx, ebx + +GetProcessorNumber: + ; + ; Get processor number for this AP + ; Note that BSP may become an AP due to SwitchBsp() + ; + xor ebx, ebx + lea eax, [esi + CpuInfoLocation] + mov edi, [eax] + +GetNextProcNumber: + cmp dword [edi], edx ; APIC ID match? + jz ProgramStack + add edi, 20 + inc ebx + jmp GetNextProcNumber + +ProgramStack: + mov rsp, qword [edi + 12] + +CProcedureInvoke: + push rbp ; Push BIST data at top of AP stack + xor rbp, rbp ; Clear ebp for call stack trace + push rbp + mov rbp, rsp + + mov rax, qword [esi + InitializeFloatingPointUnitsAddress] + sub rsp, 20h + call rax ; Call assembly function to initialize FPU per UEFI spec + add rsp, 20h + + mov edx, ebx ; edx is ApIndex + mov ecx, esi + add ecx, LockLocation ; rcx is address of exchange info data buffer + + mov edi, esi + add edi, ApProcedureLocation + mov rax, qword [edi] + + sub rsp, 20h + call rax ; Invoke C function + add rsp, 20h + jmp $ ; Should never reach here + +RendezvousFunnelProcEnd: + +;------------------------------------------------------------------------------------- +; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmRelocateApLoop) +ASM_PFX(AsmRelocateApLoop): +AsmRelocateApLoopStart: + cli ; Disable interrupt before switching to 32-bit mode + mov rax, [rsp + 40] ; CountTofinish + lock dec dword [rax] ; (*CountTofinish)-- + mov rsp, r9 + push rcx + push rdx + + lea rsi, [PmEntry] ; rsi <- The start address of transition code + + push r8 + push rsi + DB 0x48 + retf +BITS 32 +PmEntry: + mov eax, cr0 + btr eax, 31 ; Clear CR0.PG + mov cr0, eax ; Disable paging and caches + + mov ebx, edx ; Save EntryPoint to rbx, for rdmsr will overwrite rdx + mov ecx, 0xc0000080 + rdmsr + and ah, ~ 1 ; Clear LME + wrmsr + mov eax, cr4 + and al, ~ (1 << 5) ; Clear PAE + mov cr4, eax + + pop edx + add esp, 4 + pop ecx, + add esp, 4 + cmp cl, 1 ; Check mwait-monitor support + jnz HltLoop + mov ebx, edx ; Save C-State to ebx +MwaitLoop: + cli + mov eax, esp ; Set Monitor Address + xor ecx, ecx ; ecx = 0 + xor edx, edx ; edx = 0 + monitor + mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4] + shl eax, 4 + mwait + jmp MwaitLoop +HltLoop: + cli + hlt + jmp HltLoop +BITS 64 +AsmRelocateApLoopEnd: + +;------------------------------------------------------------------------------------- +; AsmGetAddressMap (&AddressMap); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmGetAddressMap) +ASM_PFX(AsmGetAddressMap): + lea rax, [ASM_PFX(RendezvousFunnelProc)] + mov qword [rcx], rax + mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart + mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart + lea rax, [ASM_PFX(AsmRelocateApLoop)] + mov qword [rcx + 18h], rax + mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart + mov qword [rcx + 28h], Flat32Start - RendezvousFunnelProcStart + ret + +;------------------------------------------------------------------------------------- +;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is +;about to become an AP. It switches its stack with the current AP. +;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmExchangeRole) +ASM_PFX(AsmExchangeRole): + ; DO NOT call other functions in this function, since 2 CPU may use 1 stack + ; at the same time. If 1 CPU try to call a function, stack will be corrupted. + + push rax + push rbx + push rcx + push rdx + push rsi + push rdi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov rax, cr0 + push rax + + mov rax, cr4 + push rax + + ; rsi contains MyInfo pointer + mov rsi, rcx + + ; rdi contains OthersInfo pointer + mov rdi, rdx + + ;Store EFLAGS, GDTR and IDTR regiter to stack + pushfq + sgdt [rsi + 16] + sidt [rsi + 26] + + ; Store the its StackPointer + mov [rsi + 8], rsp + + ; update its switch state to STORED + mov byte [rsi], CPU_SWITCH_STATE_STORED + +WaitForOtherStored: + ; wait until the other CPU finish storing its state + cmp byte [rdi], CPU_SWITCH_STATE_STORED + jz OtherStored + pause + jmp WaitForOtherStored + +OtherStored: + ; Since another CPU already stored its state, load them + ; load GDTR value + lgdt [rdi + 16] + + ; load IDTR value + lidt [rdi + 26] + + ; load its future StackPointer + mov rsp, [rdi + 8] + + ; update the other CPU's switch state to LOADED + mov byte [rdi], CPU_SWITCH_STATE_LOADED + +WaitForOtherLoaded: + ; wait until the other CPU finish loading new state, + ; otherwise the data in stack may corrupt + cmp byte [rsi], CPU_SWITCH_STATE_LOADED + jz OtherLoaded + pause + jmp WaitForOtherLoaded + +OtherLoaded: + ; since the other CPU already get the data it want, leave this procedure + popfq + + pop rax + mov cr4, rax + + pop rax + mov cr0, rax + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rdi + pop rsi + pop rdx + pop rcx + pop rbx + pop rax + + ret diff --git a/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.c b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.c new file mode 100644 index 000000000..b4024ee1a --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.c @@ -0,0 +1,442 @@ +/** @file + Multiple-Processor initialization Library for uniprocessor platforms. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +/** + MP Initialize Library initialization. + + This service will allocate AP reset vector and wakeup all APs to do APs + initialization. + + This service must be invoked before all other MP Initialize Library + service are invoked. + + @retval EFI_SUCCESS MP initialization succeeds. + @retval Others MP initialization fails. + +**/ +EFI_STATUS +EFIAPI +MpInitLibInitialize ( + VOID + ) +{ + // + // Enable the local APIC for Virtual Wire Mode. + // + ProgramVirtualWireMode (); + + return EFI_SUCCESS; +} + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ) +{ + *NumberOfProcessors = 1; + *NumberOfEnabledProcessors = 1; + return EFI_SUCCESS; +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation; + + if (ProcessorInfoBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + if (ProcessorNumber != 0) { + return EFI_NOT_FOUND; + } + ProcessorInfoBuffer->ProcessorId = 0; + ProcessorInfoBuffer->StatusFlag = PROCESSOR_AS_BSP_BIT | + PROCESSOR_ENABLED_BIT | + PROCESSOR_HEALTH_STATUS_BIT; + ProcessorInfoBuffer->Location.Package = 0; + ProcessorInfoBuffer->Location.Core = 0; + ProcessorInfoBuffer->Location.Thread = 0; + if (HealthData != NULL) { + GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid); + if (GuidHob != NULL) { + SecPlatformInformation = GET_GUID_HOB_DATA (GuidHob); + HealthData->Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32; + } else { + DEBUG ((DEBUG_INFO, "Does not find any HOB stored CPU BIST information!\n")); + HealthData->Uint32 = 0; + } + } + return EFI_SUCCESS; +} + +/** + This service executes a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by MpInitLibStartupAllAPs() or + MPInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Initialization + library, and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllAPs ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ) +{ + return EFI_NOT_STARTED; +} + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by MpInitLibStartupAllAPs() or + MpInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupThisAP ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ) +{ + return EFI_INVALID_PARAMETER; +} + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibSwitchBSP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibEnableDisableAP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibWhoAmI ( + OUT UINTN *ProcessorNumber + ) +{ + if (ProcessorNumber == NULL) { + return EFI_INVALID_PARAMETER; + } + *ProcessorNumber = 0; + return EFI_SUCCESS; +} + +/** + This service executes a caller provided function on all enabled CPUs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. TimeoutInMicroseconds is ignored + for BSP. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + + @retval EFI_SUCCESS CPU have finished the procedure. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllCPUs ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ) +{ + if (Procedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + Procedure (ProcedureArgument); + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf new file mode 100644 index 000000000..24ad29c03 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf @@ -0,0 +1,37 @@ +## @file +# MP Initialize Library instance for uniprocessor platforms. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MpInitLibUp + MODULE_UNI_FILE = MpInitLibUp.uni + FILE_GUID = 70E9818C-A4F0-4061-9FA2-2DFFC7016D6E + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = MpInitLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MpInitLibUp.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + DebugLib + LocalApicLib + HobLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.uni b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.uni new file mode 100644 index 000000000..ca1ab9437 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.uni @@ -0,0 +1,14 @@ +// /** @file +// MP Initialize Library instance for uniprocessor platforms. +// +// MP Initialize Library instance for uniprocessor platforms. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "MP Initialize Library instance for uniprocessor platforms." + +#string STR_MODULE_DESCRIPTION #language en-US "MP Initialize Library instance for uniprocessor platforms." diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c new file mode 100644 index 000000000..dfa848022 --- /dev/null +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -0,0 +1,2898 @@ +/** @file + MTRR setting library + + @par Note: + Most of services in this library instance are suggested to be invoked by BSP only, + except for MtrrSetAllMtrrs() which is used to sync BSP's MTRR setting to APs. + + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define OR_SEED 0x0101010101010101ull +#define CLEAR_SEED 0xFFFFFFFFFFFFFFFFull +#define MAX_WEIGHT MAX_UINT8 +#define SCRATCH_BUFFER_SIZE (4 * SIZE_4KB) +#define MTRR_LIB_ASSERT_ALIGNED(B, L) ASSERT ((B & ~(L - 1)) == B); + +#define M(x,y) ((x) * VertexCount + (y)) +#define O(x,y) ((y) * VertexCount + (x)) + +// +// Context to save and restore when MTRRs are programmed +// +typedef struct { + UINTN Cr4; + BOOLEAN InterruptState; +} MTRR_CONTEXT; + +typedef struct { + UINT64 Address; + UINT64 Alignment; + UINT64 Length; + MTRR_MEMORY_CACHE_TYPE Type : 7; + + // + // Temprary use for calculating the best MTRR settings. + // + BOOLEAN Visited : 1; + UINT8 Weight; + UINT16 Previous; +} MTRR_LIB_ADDRESS; + +// +// This table defines the offset, base and length of the fixed MTRRs +// +CONST FIXED_MTRR mMtrrLibFixedMtrrTable[] = { + { + MSR_IA32_MTRR_FIX64K_00000, + 0, + SIZE_64KB + }, + { + MSR_IA32_MTRR_FIX16K_80000, + 0x80000, + SIZE_16KB + }, + { + MSR_IA32_MTRR_FIX16K_A0000, + 0xA0000, + SIZE_16KB + }, + { + MSR_IA32_MTRR_FIX4K_C0000, + 0xC0000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_C8000, + 0xC8000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_D0000, + 0xD0000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_D8000, + 0xD8000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_E0000, + 0xE0000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_E8000, + 0xE8000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_F0000, + 0xF0000, + SIZE_4KB + }, + { + MSR_IA32_MTRR_FIX4K_F8000, + 0xF8000, + SIZE_4KB + } +}; + +// +// Lookup table used to print MTRRs +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = { + "UC", // CacheUncacheable + "WC", // CacheWriteCombining + "R*", // Invalid + "R*", // Invalid + "WT", // CacheWriteThrough + "WP", // CacheWriteProtected + "WB", // CacheWriteBack + "R*" // Invalid +}; + + +/** + Worker function prints all MTRRs for debugging. + + If MtrrSetting is not NULL, print MTRR settings from input MTRR + settings buffer. + If MtrrSetting is NULL, print MTRR settings from MTRRs. + + @param MtrrSetting A buffer holding all MTRRs content. +**/ +VOID +MtrrDebugPrintAllMtrrsWorker ( + IN MTRR_SETTINGS *MtrrSetting + ); + +/** + Worker function returns the variable MTRR count for the CPU. + + @return Variable MTRR count + +**/ +UINT32 +GetVariableMtrrCountWorker ( + VOID + ) +{ + MSR_IA32_MTRRCAP_REGISTER MtrrCap; + + MtrrCap.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP); + ASSERT (MtrrCap.Bits.VCNT <= ARRAY_SIZE (((MTRR_VARIABLE_SETTINGS *) 0)->Mtrr)); + return MtrrCap.Bits.VCNT; +} + +/** + Returns the variable MTRR count for the CPU. + + @return Variable MTRR count + +**/ +UINT32 +EFIAPI +GetVariableMtrrCount ( + VOID + ) +{ + if (!IsMtrrSupported ()) { + return 0; + } + return GetVariableMtrrCountWorker (); +} + +/** + Worker function returns the firmware usable variable MTRR count for the CPU. + + @return Firmware usable variable MTRR count + +**/ +UINT32 +GetFirmwareVariableMtrrCountWorker ( + VOID + ) +{ + UINT32 VariableMtrrCount; + UINT32 ReservedMtrrNumber; + + VariableMtrrCount = GetVariableMtrrCountWorker (); + ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs); + if (VariableMtrrCount < ReservedMtrrNumber) { + return 0; + } + + return VariableMtrrCount - ReservedMtrrNumber; +} + +/** + Returns the firmware usable variable MTRR count for the CPU. + + @return Firmware usable variable MTRR count + +**/ +UINT32 +EFIAPI +GetFirmwareVariableMtrrCount ( + VOID + ) +{ + if (!IsMtrrSupported ()) { + return 0; + } + return GetFirmwareVariableMtrrCountWorker (); +} + +/** + Worker function returns the default MTRR cache type for the system. + + If MtrrSetting is not NULL, returns the default MTRR cache type from input + MTRR settings buffer. + If MtrrSetting is NULL, returns the default MTRR cache type from MSR. + + @param[in] MtrrSetting A buffer holding all MTRRs content. + + @return The default MTRR cache type. + +**/ +MTRR_MEMORY_CACHE_TYPE +MtrrGetDefaultMemoryTypeWorker ( + IN MTRR_SETTINGS *MtrrSetting + ) +{ + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + + if (MtrrSetting == NULL) { + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + } else { + DefType.Uint64 = MtrrSetting->MtrrDefType; + } + + return (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type; +} + + +/** + Returns the default MTRR cache type for the system. + + @return The default MTRR cache type. + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetDefaultMemoryType ( + VOID + ) +{ + if (!IsMtrrSupported ()) { + return CacheUncacheable; + } + return MtrrGetDefaultMemoryTypeWorker (NULL); +} + +/** + Preparation before programming MTRR. + + This function will do some preparation for programming MTRRs: + disable cache, invalid cache and disable MTRR caching functionality + + @param[out] MtrrContext Pointer to context to save + +**/ +VOID +MtrrLibPreMtrrChange ( + OUT MTRR_CONTEXT *MtrrContext + ) +{ + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + // + // Disable interrupts and save current interrupt state + // + MtrrContext->InterruptState = SaveAndDisableInterrupts(); + + // + // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29) + // + AsmDisableCache (); + + // + // Save original CR4 value and clear PGE flag (Bit 7) + // + MtrrContext->Cr4 = AsmReadCr4 (); + AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7)); + + // + // Flush all TLBs + // + CpuFlushTlb (); + + // + // Disable MTRRs + // + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.E = 0; + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); +} + +/** + Cleaning up after programming MTRRs. + + This function will do some clean up after programming MTRRs: + Flush all TLBs, re-enable caching, restore CR4. + + @param[in] MtrrContext Pointer to context to restore + +**/ +VOID +MtrrLibPostMtrrChangeEnableCache ( + IN MTRR_CONTEXT *MtrrContext + ) +{ + // + // Flush all TLBs + // + CpuFlushTlb (); + + // + // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29) + // + AsmEnableCache (); + + // + // Restore original CR4 value + // + AsmWriteCr4 (MtrrContext->Cr4); + + // + // Restore original interrupt state + // + SetInterruptState (MtrrContext->InterruptState); +} + +/** + Cleaning up after programming MTRRs. + + This function will do some clean up after programming MTRRs: + enable MTRR caching functionality, and enable cache + + @param[in] MtrrContext Pointer to context to restore + +**/ +VOID +MtrrLibPostMtrrChange ( + IN MTRR_CONTEXT *MtrrContext + ) +{ + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + // + // Enable Cache MTRR + // + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.E = 1; + DefType.Bits.FE = 1; + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); + + MtrrLibPostMtrrChangeEnableCache (MtrrContext); +} + +/** + Worker function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @retval The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +MtrrGetFixedMtrrWorker ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + UINT32 Index; + + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + FixedSettings->Mtrr[Index] = + AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); + } + + return FixedSettings; +} + + +/** + This function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @retval The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrGetFixedMtrr ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + if (!IsMtrrSupported ()) { + return FixedSettings; + } + + return MtrrGetFixedMtrrWorker (FixedSettings); +} + + +/** + Worker function will get the raw value in variable MTRRs + + If MtrrSetting is not NULL, gets the variable MTRRs raw value from input + MTRR settings buffer. + If MtrrSetting is NULL, gets the variable MTRRs raw value from MTRRs. + + @param[in] MtrrSetting A buffer holding all MTRRs content. + @param[in] VariableMtrrCount Number of variable MTRRs. + @param[out] VariableSettings A buffer to hold variable MTRRs content. + + @return The VariableSettings input pointer + +**/ +MTRR_VARIABLE_SETTINGS* +MtrrGetVariableMtrrWorker ( + IN MTRR_SETTINGS *MtrrSetting, + IN UINT32 VariableMtrrCount, + OUT MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + UINT32 Index; + + ASSERT (VariableMtrrCount <= ARRAY_SIZE (VariableSettings->Mtrr)); + + for (Index = 0; Index < VariableMtrrCount; Index++) { + if (MtrrSetting == NULL) { + VariableSettings->Mtrr[Index].Base = + AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)); + VariableSettings->Mtrr[Index].Mask = + AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)); + } else { + VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base; + VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask; + } + } + + return VariableSettings; +} + +/** + This function will get the raw value in variable MTRRs + + @param[out] VariableSettings A buffer to hold variable MTRRs content. + + @return The VariableSettings input pointer + +**/ +MTRR_VARIABLE_SETTINGS* +EFIAPI +MtrrGetVariableMtrr ( + OUT MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + if (!IsMtrrSupported ()) { + return VariableSettings; + } + + return MtrrGetVariableMtrrWorker ( + NULL, + GetVariableMtrrCountWorker (), + VariableSettings + ); +} + +/** + Programs fixed MTRRs registers. + + @param[in] Type The memory type to set. + @param[in, out] Base The base address of memory range. + @param[in, out] Length The length of memory range. + @param[in, out] LastMsrIndex On input, the last index of the fixed MTRR MSR to program. + On return, the current index of the fixed MTRR MSR to program. + @param[out] ClearMask The bits to clear in the fixed MTRR MSR. + @param[out] OrMask The bits to set in the fixed MTRR MSR. + + @retval RETURN_SUCCESS The cache type was updated successfully + @retval RETURN_UNSUPPORTED The requested range or cache type was invalid + for the fixed MTRRs. + +**/ +RETURN_STATUS +MtrrLibProgramFixedMtrr ( + IN MTRR_MEMORY_CACHE_TYPE Type, + IN OUT UINT64 *Base, + IN OUT UINT64 *Length, + IN OUT UINT32 *LastMsrIndex, + OUT UINT64 *ClearMask, + OUT UINT64 *OrMask + ) +{ + UINT32 MsrIndex; + UINT32 LeftByteShift; + UINT32 RightByteShift; + UINT64 SubLength; + + // + // Find the fixed MTRR index to be programmed + // + for (MsrIndex = *LastMsrIndex + 1; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) { + if ((*Base >= mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) && + (*Base < + ( + mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress + + (8 * mMtrrLibFixedMtrrTable[MsrIndex].Length) + ) + ) + ) { + break; + } + } + + ASSERT (MsrIndex != ARRAY_SIZE (mMtrrLibFixedMtrrTable)); + + // + // Find the begin offset in fixed MTRR and calculate byte offset of left shift + // + if ((((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) { + // + // Base address should be aligned to the begin of a certain Fixed MTRR range. + // + return RETURN_UNSUPPORTED; + } + LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) / mMtrrLibFixedMtrrTable[MsrIndex].Length; + ASSERT (LeftByteShift < 8); + + // + // Find the end offset in fixed MTRR and calculate byte offset of right shift + // + SubLength = mMtrrLibFixedMtrrTable[MsrIndex].Length * (8 - LeftByteShift); + if (*Length >= SubLength) { + RightByteShift = 0; + } else { + if (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) { + // + // Length should be aligned to the end of a certain Fixed MTRR range. + // + return RETURN_UNSUPPORTED; + } + RightByteShift = 8 - LeftByteShift - (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrIndex].Length; + // + // Update SubLength by actual length + // + SubLength = *Length; + } + + *ClearMask = CLEAR_SEED; + *OrMask = MultU64x32 (OR_SEED, (UINT32) Type); + + if (LeftByteShift != 0) { + // + // Clear the low bits by LeftByteShift + // + *ClearMask &= LShiftU64 (*ClearMask, LeftByteShift * 8); + *OrMask &= LShiftU64 (*OrMask, LeftByteShift * 8); + } + + if (RightByteShift != 0) { + // + // Clear the high bits by RightByteShift + // + *ClearMask &= RShiftU64 (*ClearMask, RightByteShift * 8); + *OrMask &= RShiftU64 (*OrMask, RightByteShift * 8); + } + + *Length -= SubLength; + *Base += SubLength; + + *LastMsrIndex = MsrIndex; + + return RETURN_SUCCESS; +} + + +/** + Worker function gets the attribute of variable MTRRs. + + This function shadows the content of variable MTRRs into an + internal array: VariableMtrr. + + @param[in] VariableSettings The variable MTRR values to shadow + @param[in] VariableMtrrCount The number of variable MTRRs + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs content + + @return Number of MTRRs which has been used. + +**/ +UINT32 +MtrrGetMemoryAttributeInVariableMtrrWorker ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings, + IN UINTN VariableMtrrCount, + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT VARIABLE_MTRR *VariableMtrr + ) +{ + UINTN Index; + UINT32 UsedMtrr; + + ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * ARRAY_SIZE (VariableSettings->Mtrr)); + for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) { + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) { + VariableMtrr[Index].Msr = (UINT32)Index; + VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask); + VariableMtrr[Index].Length = + ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1; + VariableMtrr[Index].Type = (VariableSettings->Mtrr[Index].Base & 0x0ff); + VariableMtrr[Index].Valid = TRUE; + VariableMtrr[Index].Used = TRUE; + UsedMtrr++; + } + } + return UsedMtrr; +} + +/** + Convert variable MTRRs to a RAW MTRR_MEMORY_RANGE array. + One MTRR_MEMORY_RANGE element is created for each MTRR setting. + The routine doesn't remove the overlap or combine the near-by region. + + @param[in] VariableSettings The variable MTRR values to shadow + @param[in] VariableMtrrCount The number of variable MTRRs + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs content + + @return Number of MTRRs which has been used. + +**/ +UINT32 +MtrrLibGetRawVariableRanges ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings, + IN UINTN VariableMtrrCount, + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT MTRR_MEMORY_RANGE *VariableMtrr + ) +{ + UINTN Index; + UINT32 UsedMtrr; + + ZeroMem (VariableMtrr, sizeof (MTRR_MEMORY_RANGE) * ARRAY_SIZE (VariableSettings->Mtrr)); + for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) { + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) { + VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask); + VariableMtrr[Index].Length = + ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1; + VariableMtrr[Index].Type = (MTRR_MEMORY_CACHE_TYPE)(VariableSettings->Mtrr[Index].Base & 0x0ff); + UsedMtrr++; + } + } + return UsedMtrr; +} + +/** + Gets the attribute of variable MTRRs. + + This function shadows the content of variable MTRRs into an + internal array: VariableMtrr. + + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs content + + @return The return value of this parameter indicates the + number of MTRRs which has been used. + +**/ +UINT32 +EFIAPI +MtrrGetMemoryAttributeInVariableMtrr ( + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT VARIABLE_MTRR *VariableMtrr + ) +{ + MTRR_VARIABLE_SETTINGS VariableSettings; + + if (!IsMtrrSupported ()) { + return 0; + } + + MtrrGetVariableMtrrWorker ( + NULL, + GetVariableMtrrCountWorker (), + &VariableSettings + ); + + return MtrrGetMemoryAttributeInVariableMtrrWorker ( + &VariableSettings, + GetFirmwareVariableMtrrCountWorker (), + MtrrValidBitsMask, + MtrrValidAddressMask, + VariableMtrr + ); +} + +/** + Return the biggest alignment (lowest set bit) of address. + The function is equivalent to: 1 << LowBitSet64 (Address). + + @param Address The address to return the alignment. + @param Alignment0 The alignment to return when Address is 0. + + @return The least alignment of the Address. +**/ +UINT64 +MtrrLibBiggestAlignment ( + UINT64 Address, + UINT64 Alignment0 +) +{ + if (Address == 0) { + return Alignment0; + } + + return Address & ((~Address) + 1); +} + +/** + Return whether the left MTRR type precedes the right MTRR type. + + The MTRR type precedence rules are: + 1. UC precedes any other type + 2. WT precedes WB + For further details, please refer the IA32 Software Developer's Manual, + Volume 3, Section "MTRR Precedences". + + @param Left The left MTRR type. + @param Right The right MTRR type. + + @retval TRUE Left precedes Right. + @retval FALSE Left doesn't precede Right. +**/ +BOOLEAN +MtrrLibTypeLeftPrecedeRight ( + IN MTRR_MEMORY_CACHE_TYPE Left, + IN MTRR_MEMORY_CACHE_TYPE Right +) +{ + return (BOOLEAN) (Left == CacheUncacheable || (Left == CacheWriteThrough && Right == CacheWriteBack)); +} + +/** + Initializes the valid bits mask and valid address mask for MTRRs. + + This function initializes the valid bits mask and valid address mask for MTRRs. + + @param[out] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[out] MtrrValidAddressMask The valid address mask for the MTRR + +**/ +VOID +MtrrLibInitializeMtrrMask ( + OUT UINT64 *MtrrValidBitsMask, + OUT UINT64 *MtrrValidAddressMask + ) +{ + UINT32 MaxExtendedFunction; + CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize; + + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL); + + if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL); + } else { + VirPhyAddressSize.Bits.PhysicalAddressBits = 36; + } + + *MtrrValidBitsMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1; + *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL; +} + + +/** + Determines the real attribute of a memory range. + + This function is to arbitrate the real attribute of the memory when + there are 2 MTRRs covers the same memory range. For further details, + please refer the IA32 Software Developer's Manual, Volume 3, + Section "MTRR Precedences". + + @param[in] MtrrType1 The first kind of Memory type + @param[in] MtrrType2 The second kind of memory type + +**/ +MTRR_MEMORY_CACHE_TYPE +MtrrLibPrecedence ( + IN MTRR_MEMORY_CACHE_TYPE MtrrType1, + IN MTRR_MEMORY_CACHE_TYPE MtrrType2 + ) +{ + if (MtrrType1 == MtrrType2) { + return MtrrType1; + } + + ASSERT ( + MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) || + MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1) + ); + + if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) { + return MtrrType1; + } else { + return MtrrType2; + } +} + +/** + Worker function will get the memory cache type of the specific address. + + If MtrrSetting is not NULL, gets the memory cache type from input + MTRR settings buffer. + If MtrrSetting is NULL, gets the memory cache type from MTRRs. + + @param[in] MtrrSetting A buffer holding all MTRRs content. + @param[in] Address The specific address + + @return Memory cache type of the specific address + +**/ +MTRR_MEMORY_CACHE_TYPE +MtrrGetMemoryAttributeByAddressWorker ( + IN MTRR_SETTINGS *MtrrSetting, + IN PHYSICAL_ADDRESS Address + ) +{ + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + UINT64 FixedMtrr; + UINTN Index; + UINTN SubIndex; + MTRR_MEMORY_CACHE_TYPE MtrrType; + MTRR_MEMORY_RANGE VariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)]; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + UINT32 VariableMtrrCount; + MTRR_VARIABLE_SETTINGS VariableSettings; + + // + // Check if MTRR is enabled, if not, return UC as attribute + // + if (MtrrSetting == NULL) { + DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + } else { + DefType.Uint64 = MtrrSetting->MtrrDefType; + } + + if (DefType.Bits.E == 0) { + return CacheUncacheable; + } + + // + // If address is less than 1M, then try to go through the fixed MTRR + // + if (Address < BASE_1MB) { + if (DefType.Bits.FE != 0) { + // + // Go through the fixed MTRR + // + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress && + Address < mMtrrLibFixedMtrrTable[Index].BaseAddress + + (mMtrrLibFixedMtrrTable[Index].Length * 8)) { + SubIndex = + ((UINTN) Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / + mMtrrLibFixedMtrrTable[Index].Length; + if (MtrrSetting == NULL) { + FixedMtrr = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); + } else { + FixedMtrr = MtrrSetting->Fixed.Mtrr[Index]; + } + return (MTRR_MEMORY_CACHE_TYPE) (RShiftU64 (FixedMtrr, SubIndex * 8) & 0xFF); + } + } + } + } + + VariableMtrrCount = GetVariableMtrrCountWorker (); + ASSERT (VariableMtrrCount <= ARRAY_SIZE (MtrrSetting->Variables.Mtrr)); + MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSettings); + + MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); + MtrrLibGetRawVariableRanges ( + &VariableSettings, + VariableMtrrCount, + MtrrValidBitsMask, + MtrrValidAddressMask, + VariableMtrr + ); + + // + // Go through the variable MTRR + // + MtrrType = CacheInvalid; + for (Index = 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Length != 0) { + if (Address >= VariableMtrr[Index].BaseAddress && + Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length) { + if (MtrrType == CacheInvalid) { + MtrrType = (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type; + } else { + MtrrType = MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type); + } + } + } + } + + // + // If there is no MTRR which covers the Address, use the default MTRR type. + // + if (MtrrType == CacheInvalid) { + MtrrType = (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type; + } + + return MtrrType; +} + + +/** + This function will get the memory cache type of the specific address. + + This function is mainly for debug purpose. + + @param[in] Address The specific address + + @return Memory cache type of the specific address + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetMemoryAttribute ( + IN PHYSICAL_ADDRESS Address + ) +{ + if (!IsMtrrSupported ()) { + return CacheUncacheable; + } + + return MtrrGetMemoryAttributeByAddressWorker (NULL, Address); +} + +/** + Update the Ranges array to change the specified range identified by + BaseAddress and Length to Type. + + @param Ranges Array holding memory type settings for all memory regions. + @param Capacity The maximum count of memory ranges the array can hold. + @param Count Return the new memory range count in the array. + @param BaseAddress The base address of the memory range to change type. + @param Length The length of the memory range to change type. + @param Type The new type of the specified memory range. + + @retval RETURN_SUCCESS The type of the specified memory range is + changed successfully. + @retval RETURN_ALREADY_STARTED The type of the specified memory range equals + to the desired type. + @retval RETURN_OUT_OF_RESOURCES The new type set causes the count of memory + range exceeds capacity. +**/ +RETURN_STATUS +MtrrLibSetMemoryType ( + IN MTRR_MEMORY_RANGE *Ranges, + IN UINTN Capacity, + IN OUT UINTN *Count, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type + ) +{ + UINTN Index; + UINT64 Limit; + UINT64 LengthLeft; + UINT64 LengthRight; + UINTN StartIndex; + UINTN EndIndex; + UINTN DeltaCount; + + LengthRight = 0; + LengthLeft = 0; + Limit = BaseAddress + Length; + StartIndex = *Count; + EndIndex = *Count; + for (Index = 0; Index < *Count; Index++) { + if ((StartIndex == *Count) && + (Ranges[Index].BaseAddress <= BaseAddress) && + (BaseAddress < Ranges[Index].BaseAddress + Ranges[Index].Length)) { + StartIndex = Index; + LengthLeft = BaseAddress - Ranges[Index].BaseAddress; + } + + if ((EndIndex == *Count) && + (Ranges[Index].BaseAddress < Limit) && + (Limit <= Ranges[Index].BaseAddress + Ranges[Index].Length)) { + EndIndex = Index; + LengthRight = Ranges[Index].BaseAddress + Ranges[Index].Length - Limit; + break; + } + } + + ASSERT (StartIndex != *Count && EndIndex != *Count); + if (StartIndex == EndIndex && Ranges[StartIndex].Type == Type) { + return RETURN_ALREADY_STARTED; + } + + // + // The type change may cause merging with previous range or next range. + // Update the StartIndex, EndIndex, BaseAddress, Length so that following + // logic doesn't need to consider merging. + // + if (StartIndex != 0) { + if (LengthLeft == 0 && Ranges[StartIndex - 1].Type == Type) { + StartIndex--; + Length += Ranges[StartIndex].Length; + BaseAddress -= Ranges[StartIndex].Length; + } + } + if (EndIndex != (*Count) - 1) { + if (LengthRight == 0 && Ranges[EndIndex + 1].Type == Type) { + EndIndex++; + Length += Ranges[EndIndex].Length; + } + } + + // + // |- 0 -|- 1 -|- 2 -|- 3 -| StartIndex EndIndex DeltaCount Count (Count = 4) + // |++++++++++++++++++| 0 3 1=3-0-2 3 + // |+++++++| 0 1 -1=1-0-2 5 + // |+| 0 0 -2=0-0-2 6 + // |+++| 0 0 -1=0-0-2+1 5 + // + // + DeltaCount = EndIndex - StartIndex - 2; + if (LengthLeft == 0) { + DeltaCount++; + } + if (LengthRight == 0) { + DeltaCount++; + } + if (*Count - DeltaCount > Capacity) { + return RETURN_OUT_OF_RESOURCES; + } + + // + // Reserve (-DeltaCount) space + // + CopyMem (&Ranges[EndIndex + 1 - DeltaCount], &Ranges[EndIndex + 1], (*Count - EndIndex - 1) * sizeof (Ranges[0])); + *Count -= DeltaCount; + + if (LengthLeft != 0) { + Ranges[StartIndex].Length = LengthLeft; + StartIndex++; + } + if (LengthRight != 0) { + Ranges[EndIndex - DeltaCount].BaseAddress = BaseAddress + Length; + Ranges[EndIndex - DeltaCount].Length = LengthRight; + Ranges[EndIndex - DeltaCount].Type = Ranges[EndIndex].Type; + } + Ranges[StartIndex].BaseAddress = BaseAddress; + Ranges[StartIndex].Length = Length; + Ranges[StartIndex].Type = Type; + return RETURN_SUCCESS; +} + +/** + Return the number of memory types in range [BaseAddress, BaseAddress + Length). + + @param Ranges Array holding memory type settings for all memory regions. + @param RangeCount The count of memory ranges the array holds. + @param BaseAddress Base address. + @param Length Length. + @param Types Return bit mask to indicate all memory types in the specified range. + + @retval Number of memory types. +**/ +UINT8 +MtrrLibGetNumberOfTypes ( + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN OUT UINT8 *Types OPTIONAL + ) +{ + UINTN Index; + UINT8 TypeCount; + UINT8 LocalTypes; + + TypeCount = 0; + LocalTypes = 0; + for (Index = 0; Index < RangeCount; Index++) { + if ((Ranges[Index].BaseAddress <= BaseAddress) && + (BaseAddress < Ranges[Index].BaseAddress + Ranges[Index].Length) + ) { + if ((LocalTypes & (1 << Ranges[Index].Type)) == 0) { + LocalTypes |= (UINT8)(1 << Ranges[Index].Type); + TypeCount++; + } + + if (BaseAddress + Length > Ranges[Index].BaseAddress + Ranges[Index].Length) { + Length -= Ranges[Index].BaseAddress + Ranges[Index].Length - BaseAddress; + BaseAddress = Ranges[Index].BaseAddress + Ranges[Index].Length; + } else { + break; + } + } + } + + if (Types != NULL) { + *Types = LocalTypes; + } + return TypeCount; +} + +/** + Calculate the least MTRR number from vertex Start to Stop and update + the Previous of all vertices from Start to Stop is updated to reflect + how the memory range is covered by MTRR. + + @param VertexCount The count of vertices in the graph. + @param Vertices Array holding all vertices. + @param Weight 2-dimention array holding weights between vertices. + @param Start Start vertex. + @param Stop Stop vertex. + @param IncludeOptional TRUE to count the optional weight. +**/ +VOID +MtrrLibCalculateLeastMtrrs ( + IN UINT16 VertexCount, + IN MTRR_LIB_ADDRESS *Vertices, + IN OUT CONST UINT8 *Weight, + IN UINT16 Start, + IN UINT16 Stop, + IN BOOLEAN IncludeOptional + ) +{ + UINT16 Index; + UINT8 MinWeight; + UINT16 MinI; + UINT8 Mandatory; + UINT8 Optional; + + for (Index = Start; Index <= Stop; Index++) { + Vertices[Index].Visited = FALSE; + Mandatory = Weight[M(Start,Index)]; + Vertices[Index].Weight = Mandatory; + if (Mandatory != MAX_WEIGHT) { + Optional = IncludeOptional ? Weight[O(Start, Index)] : 0; + Vertices[Index].Weight += Optional; + ASSERT (Vertices[Index].Weight >= Optional); + } + } + + MinI = Start; + MinWeight = 0; + while (!Vertices[Stop].Visited) { + // + // Update the weight from the shortest vertex to other unvisited vertices + // + for (Index = Start + 1; Index <= Stop; Index++) { + if (!Vertices[Index].Visited) { + Mandatory = Weight[M(MinI, Index)]; + if (Mandatory != MAX_WEIGHT) { + Optional = IncludeOptional ? Weight[O(MinI, Index)] : 0; + if (MinWeight + Mandatory + Optional <= Vertices[Index].Weight) { + Vertices[Index].Weight = MinWeight + Mandatory + Optional; + Vertices[Index].Previous = MinI; // Previous is Start based. + } + } + } + } + + // + // Find the shortest vertex from Start + // + MinI = VertexCount; + MinWeight = MAX_WEIGHT; + for (Index = Start + 1; Index <= Stop; Index++) { + if (!Vertices[Index].Visited && MinWeight > Vertices[Index].Weight) { + MinI = Index; + MinWeight = Vertices[Index].Weight; + } + } + + // + // Mark the shortest vertex from Start as visited + // + Vertices[MinI].Visited = TRUE; + } +} + +/** + Append the MTRR setting to MTRR setting array. + + @param Mtrrs Array holding all MTRR settings. + @param MtrrCapacity Capacity of the MTRR array. + @param MtrrCount The count of MTRR settings in array. + @param BaseAddress Base address. + @param Length Length. + @param Type Memory type. + + @retval RETURN_SUCCESS MTRR setting is appended to array. + @retval RETURN_OUT_OF_RESOURCES Array is full. +**/ +RETURN_STATUS +MtrrLibAppendVariableMtrr ( + IN OUT MTRR_MEMORY_RANGE *Mtrrs, + IN UINT32 MtrrCapacity, + IN OUT UINT32 *MtrrCount, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type + ) +{ + if (*MtrrCount == MtrrCapacity) { + return RETURN_OUT_OF_RESOURCES; + } + + Mtrrs[*MtrrCount].BaseAddress = BaseAddress; + Mtrrs[*MtrrCount].Length = Length; + Mtrrs[*MtrrCount].Type = Type; + (*MtrrCount)++; + return RETURN_SUCCESS; +} + +/** + Return the memory type that has the least precedence. + + @param TypeBits Bit mask of memory type. + + @retval Memory type that has the least precedence. +**/ +MTRR_MEMORY_CACHE_TYPE +MtrrLibLowestType ( + IN UINT8 TypeBits +) +{ + INT8 Type; + + ASSERT (TypeBits != 0); + for (Type = 7; (INT8)TypeBits > 0; Type--, TypeBits <<= 1); + return (MTRR_MEMORY_CACHE_TYPE)Type; +} + +/** + Return TRUE when the Operand is exactly power of 2. + + @retval TRUE Operand is exactly power of 2. + @retval FALSE Operand is not power of 2. +**/ +BOOLEAN +MtrrLibIsPowerOfTwo ( + IN UINT64 Operand +) +{ + ASSERT (Operand != 0); + return (BOOLEAN) ((Operand & (Operand - 1)) == 0); +} + +/** + Calculate the subtractive path from vertex Start to Stop. + + @param DefaultType Default memory type. + @param A0 Alignment to use when base address is 0. + @param Ranges Array holding memory type settings for all memory regions. + @param RangeCount The count of memory ranges the array holds. + @param VertexCount The count of vertices in the graph. + @param Vertices Array holding all vertices. + @param Weight 2-dimention array holding weights between vertices. + @param Start Start vertex. + @param Stop Stop vertex. + @param Types Type bit mask of memory range from Start to Stop. + @param TypeCount Number of different memory types from Start to Stop. + @param Mtrrs Array holding all MTRR settings. + @param MtrrCapacity Capacity of the MTRR array. + @param MtrrCount The count of MTRR settings in array. + + @retval RETURN_SUCCESS The subtractive path is calculated successfully. + @retval RETURN_OUT_OF_RESOURCES The MTRR setting array is full. + +**/ +RETURN_STATUS +MtrrLibCalculateSubtractivePath ( + IN MTRR_MEMORY_CACHE_TYPE DefaultType, + IN UINT64 A0, + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount, + IN UINT16 VertexCount, + IN MTRR_LIB_ADDRESS *Vertices, + IN OUT UINT8 *Weight, + IN UINT16 Start, + IN UINT16 Stop, + IN UINT8 Types, + IN UINT8 TypeCount, + IN OUT MTRR_MEMORY_RANGE *Mtrrs, OPTIONAL + IN UINT32 MtrrCapacity, OPTIONAL + IN OUT UINT32 *MtrrCount OPTIONAL + ) +{ + RETURN_STATUS Status; + UINT64 Base; + UINT64 Length; + UINT8 PrecedentTypes; + UINTN Index; + UINT64 HBase; + UINT64 HLength; + UINT64 SubLength; + UINT16 SubStart; + UINT16 SubStop; + UINT16 Cur; + UINT16 Pre; + MTRR_MEMORY_CACHE_TYPE LowestType; + MTRR_MEMORY_CACHE_TYPE LowestPrecedentType; + + Base = Vertices[Start].Address; + Length = Vertices[Stop].Address - Base; + + LowestType = MtrrLibLowestType (Types); + + // + // Clear the lowest type (highest bit) to get the precedent types + // + PrecedentTypes = ~(1 << LowestType) & Types; + LowestPrecedentType = MtrrLibLowestType (PrecedentTypes); + + if (Mtrrs == NULL) { + Weight[M(Start, Stop)] = ((LowestType == DefaultType) ? 0 : 1); + Weight[O(Start, Stop)] = ((LowestType == DefaultType) ? 1 : 0); + } + + // Add all high level ranges + HBase = MAX_UINT64; + HLength = 0; + for (Index = 0; Index < RangeCount; Index++) { + if (Length == 0) { + break; + } + if ((Base < Ranges[Index].BaseAddress) || (Ranges[Index].BaseAddress + Ranges[Index].Length <= Base)) { + continue; + } + + // + // Base is in the Range[Index] + // + if (Base + Length > Ranges[Index].BaseAddress + Ranges[Index].Length) { + SubLength = Ranges[Index].BaseAddress + Ranges[Index].Length - Base; + } else { + SubLength = Length; + } + if (((1 << Ranges[Index].Type) & PrecedentTypes) != 0) { + // + // Meet a range whose types take precedence. + // Update the [HBase, HBase + HLength) to include the range, + // [HBase, HBase + HLength) may contain sub ranges with 2 different types, and both take precedence. + // + if (HBase == MAX_UINT64) { + HBase = Base; + } + HLength += SubLength; + } + + Base += SubLength; + Length -= SubLength; + + if (HLength == 0) { + continue; + } + + if ((Ranges[Index].Type == LowestType) || (Length == 0)) { // meet low type or end + + // + // Add the MTRRs for each high priority type range + // the range[HBase, HBase + HLength) contains only two types. + // We might use positive or subtractive, depending on which way uses less MTRR + // + for (SubStart = Start; SubStart <= Stop; SubStart++) { + if (Vertices[SubStart].Address == HBase) { + break; + } + } + + for (SubStop = SubStart; SubStop <= Stop; SubStop++) { + if (Vertices[SubStop].Address == HBase + HLength) { + break; + } + } + ASSERT (Vertices[SubStart].Address == HBase); + ASSERT (Vertices[SubStop].Address == HBase + HLength); + + if ((TypeCount == 2) || (SubStart == SubStop - 1)) { + // + // add subtractive MTRRs for [HBase, HBase + HLength) + // [HBase, HBase + HLength) contains only one type. + // while - loop is to split the range to MTRR - compliant aligned range. + // + if (Mtrrs == NULL) { + Weight[M (Start, Stop)] += (UINT8)(SubStop - SubStart); + } else { + while (SubStart != SubStop) { + Status = MtrrLibAppendVariableMtrr ( + Mtrrs, MtrrCapacity, MtrrCount, + Vertices[SubStart].Address, Vertices[SubStart].Length, Vertices[SubStart].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + SubStart++; + } + } + } else { + ASSERT (TypeCount == 3); + MtrrLibCalculateLeastMtrrs (VertexCount, Vertices, Weight, SubStart, SubStop, TRUE); + + if (Mtrrs == NULL) { + Weight[M (Start, Stop)] += Vertices[SubStop].Weight; + } else { + // When we need to collect the optimal path from SubStart to SubStop + while (SubStop != SubStart) { + Cur = SubStop; + Pre = Vertices[Cur].Previous; + SubStop = Pre; + + if (Weight[M (Pre, Cur)] + Weight[O (Pre, Cur)] != 0) { + Status = MtrrLibAppendVariableMtrr ( + Mtrrs, MtrrCapacity, MtrrCount, + Vertices[Pre].Address, Vertices[Cur].Address - Vertices[Pre].Address, + (Pre != Cur - 1) ? LowestPrecedentType : Vertices[Pre].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + if (Pre != Cur - 1) { + Status = MtrrLibCalculateSubtractivePath ( + DefaultType, A0, + Ranges, RangeCount, + VertexCount, Vertices, Weight, + Pre, Cur, PrecedentTypes, 2, + Mtrrs, MtrrCapacity, MtrrCount + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + } + } + + } + // + // Reset HBase, HLength + // + HBase = MAX_UINT64; + HLength = 0; + } + } + return RETURN_SUCCESS; +} + +/** + Calculate MTRR settings to cover the specified memory ranges. + + @param DefaultType Default memory type. + @param A0 Alignment to use when base address is 0. + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + @param Scratch A temporary scratch buffer that is used to perform the calculation. + This is an optional parameter that may be NULL. + @param ScratchSize Pointer to the size in bytes of the scratch buffer. + It may be updated to the actual required size when the calculation + needs more scratch buffer. + @param Mtrrs Array holding all MTRR settings. + @param MtrrCapacity Capacity of the MTRR array. + @param MtrrCount The count of MTRR settings in array. + + @retval RETURN_SUCCESS Variable MTRRs are allocated successfully. + @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity. + @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation. +**/ +RETURN_STATUS +MtrrLibCalculateMtrrs ( + IN MTRR_MEMORY_CACHE_TYPE DefaultType, + IN UINT64 A0, + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount, + IN VOID *Scratch, + IN OUT UINTN *ScratchSize, + IN OUT MTRR_MEMORY_RANGE *Mtrrs, + IN UINT32 MtrrCapacity, + IN OUT UINT32 *MtrrCount + ) +{ + UINT64 Base0; + UINT64 Base1; + UINTN Index; + UINT64 Base; + UINT64 Length; + UINT64 Alignment; + UINT64 SubLength; + MTRR_LIB_ADDRESS *Vertices; + UINT8 *Weight; + UINT32 VertexIndex; + UINT32 VertexCount; + UINTN RequiredScratchSize; + UINT8 TypeCount; + UINT16 Start; + UINT16 Stop; + UINT8 Type; + RETURN_STATUS Status; + + Base0 = Ranges[0].BaseAddress; + Base1 = Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length; + MTRR_LIB_ASSERT_ALIGNED (Base0, Base1 - Base0); + + // + // Count the number of vertices. + // + Vertices = (MTRR_LIB_ADDRESS*)Scratch; + for (VertexIndex = 0, Index = 0; Index < RangeCount; Index++) { + Base = Ranges[Index].BaseAddress; + Length = Ranges[Index].Length; + while (Length != 0) { + Alignment = MtrrLibBiggestAlignment (Base, A0); + SubLength = Alignment; + if (SubLength > Length) { + SubLength = GetPowerOfTwo64 (Length); + } + if (VertexIndex < *ScratchSize / sizeof (*Vertices)) { + Vertices[VertexIndex].Address = Base; + Vertices[VertexIndex].Alignment = Alignment; + Vertices[VertexIndex].Type = Ranges[Index].Type; + Vertices[VertexIndex].Length = SubLength; + } + Base += SubLength; + Length -= SubLength; + VertexIndex++; + } + } + // + // Vertices[VertexIndex] = Base1, so whole vertex count is (VertexIndex + 1). + // + VertexCount = VertexIndex + 1; + DEBUG (( + DEBUG_CACHE, " Count of vertices (%016llx - %016llx) = %d\n", + Ranges[0].BaseAddress, Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length, VertexCount + )); + ASSERT (VertexCount < MAX_UINT16); + + RequiredScratchSize = VertexCount * sizeof (*Vertices) + VertexCount * VertexCount * sizeof (*Weight); + if (*ScratchSize < RequiredScratchSize) { + *ScratchSize = RequiredScratchSize; + return RETURN_BUFFER_TOO_SMALL; + } + Vertices[VertexCount - 1].Address = Base1; + + Weight = (UINT8 *) &Vertices[VertexCount]; + for (VertexIndex = 0; VertexIndex < VertexCount; VertexIndex++) { + // + // Set optional weight between vertices and self->self to 0 + // + SetMem (&Weight[M(VertexIndex, 0)], VertexIndex + 1, 0); + // + // Set mandatory weight between vertices to MAX_WEIGHT + // + SetMem (&Weight[M (VertexIndex, VertexIndex + 1)], VertexCount - VertexIndex - 1, MAX_WEIGHT); + + // Final result looks like: + // 00 FF FF FF + // 00 00 FF FF + // 00 00 00 FF + // 00 00 00 00 + } + + // + // Set mandatory weight and optional weight for adjacent vertices + // + for (VertexIndex = 0; VertexIndex < VertexCount - 1; VertexIndex++) { + if (Vertices[VertexIndex].Type != DefaultType) { + Weight[M (VertexIndex, VertexIndex + 1)] = 1; + Weight[O (VertexIndex, VertexIndex + 1)] = 0; + } else { + Weight[M (VertexIndex, VertexIndex + 1)] = 0; + Weight[O (VertexIndex, VertexIndex + 1)] = 1; + } + } + + for (TypeCount = 2; TypeCount <= 3; TypeCount++) { + for (Start = 0; Start < VertexCount; Start++) { + for (Stop = Start + 2; Stop < VertexCount; Stop++) { + ASSERT (Vertices[Stop].Address > Vertices[Start].Address); + Length = Vertices[Stop].Address - Vertices[Start].Address; + if (Length > Vertices[Start].Alignment) { + // + // Pickup a new Start when [Start, Stop) cannot be described by one MTRR. + // + break; + } + if ((Weight[M(Start, Stop)] == MAX_WEIGHT) && MtrrLibIsPowerOfTwo (Length)) { + if (MtrrLibGetNumberOfTypes ( + Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type + ) == TypeCount) { + // + // Update the Weight[Start, Stop] using subtractive path. + // + MtrrLibCalculateSubtractivePath ( + DefaultType, A0, + Ranges, RangeCount, + (UINT16)VertexCount, Vertices, Weight, + Start, Stop, Type, TypeCount, + NULL, 0, NULL + ); + } else if (TypeCount == 2) { + // + // Pick up a new Start when we expect 2-type range, but 3-type range is met. + // Because no matter how Stop is increased, we always meet 3-type range. + // + break; + } + } + } + } + } + + Status = RETURN_SUCCESS; + MtrrLibCalculateLeastMtrrs ((UINT16) VertexCount, Vertices, Weight, 0, (UINT16) VertexCount - 1, FALSE); + Stop = (UINT16) VertexCount - 1; + while (Stop != 0) { + Start = Vertices[Stop].Previous; + TypeCount = MAX_UINT8; + Type = 0; + if (Weight[M(Start, Stop)] != 0) { + TypeCount = MtrrLibGetNumberOfTypes (Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type); + Status = MtrrLibAppendVariableMtrr ( + Mtrrs, MtrrCapacity, MtrrCount, + Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, + MtrrLibLowestType (Type) + ); + if (RETURN_ERROR (Status)) { + break; + } + } + + if (Start != Stop - 1) { + // + // substractive path + // + if (TypeCount == MAX_UINT8) { + TypeCount = MtrrLibGetNumberOfTypes ( + Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type + ); + } + Status = MtrrLibCalculateSubtractivePath ( + DefaultType, A0, + Ranges, RangeCount, + (UINT16) VertexCount, Vertices, Weight, Start, Stop, + Type, TypeCount, + Mtrrs, MtrrCapacity, MtrrCount + ); + if (RETURN_ERROR (Status)) { + break; + } + } + Stop = Start; + } + return Status; +} + + +/** + Apply the fixed MTRR settings to memory range array. + + @param Fixed The fixed MTRR settings. + @param Ranges Return the memory range array holding memory type + settings for all memory address. + @param RangeCapacity The capacity of memory range array. + @param RangeCount Return the count of memory range. + + @retval RETURN_SUCCESS The memory range array is returned successfully. + @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity. +**/ +RETURN_STATUS +MtrrLibApplyFixedMtrrs ( + IN MTRR_FIXED_SETTINGS *Fixed, + IN OUT MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCapacity, + IN OUT UINTN *RangeCount + ) +{ + RETURN_STATUS Status; + UINTN MsrIndex; + UINTN Index; + MTRR_MEMORY_CACHE_TYPE MemoryType; + UINT64 Base; + + Base = 0; + for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) { + ASSERT (Base == mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress); + for (Index = 0; Index < sizeof (UINT64); Index++) { + MemoryType = (MTRR_MEMORY_CACHE_TYPE)((UINT8 *)(&Fixed->Mtrr[MsrIndex]))[Index]; + Status = MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, Base, mMtrrLibFixedMtrrTable[MsrIndex].Length, MemoryType + ); + if (Status == RETURN_OUT_OF_RESOURCES) { + return Status; + } + Base += mMtrrLibFixedMtrrTable[MsrIndex].Length; + } + } + ASSERT (Base == BASE_1MB); + return RETURN_SUCCESS; +} + +/** + Apply the variable MTRR settings to memory range array. + + @param VariableMtrr The variable MTRR array. + @param VariableMtrrCount The count of variable MTRRs. + @param Ranges Return the memory range array with new MTRR settings applied. + @param RangeCapacity The capacity of memory range array. + @param RangeCount Return the count of memory range. + + @retval RETURN_SUCCESS The memory range array is returned successfully. + @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity. +**/ +RETURN_STATUS +MtrrLibApplyVariableMtrrs ( + IN CONST MTRR_MEMORY_RANGE *VariableMtrr, + IN UINT32 VariableMtrrCount, + IN OUT MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCapacity, + IN OUT UINTN *RangeCount + ) +{ + RETURN_STATUS Status; + UINTN Index; + + // + // WT > WB + // UC > * + // UC > * (except WB, UC) > WB + // + + // + // 1. Set WB + // + for (Index = 0; Index < VariableMtrrCount; Index++) { + if ((VariableMtrr[Index].Length != 0) && (VariableMtrr[Index].Type == CacheWriteBack)) { + Status = MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, VariableMtrr[Index].Type + ); + if (Status == RETURN_OUT_OF_RESOURCES) { + return Status; + } + } + } + + // + // 2. Set other types than WB or UC + // + for (Index = 0; Index < VariableMtrrCount; Index++) { + if ((VariableMtrr[Index].Length != 0) && + (VariableMtrr[Index].Type != CacheWriteBack) && (VariableMtrr[Index].Type != CacheUncacheable)) { + Status = MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, VariableMtrr[Index].Type + ); + if (Status == RETURN_OUT_OF_RESOURCES) { + return Status; + } + } + } + + // + // 3. Set UC + // + for (Index = 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Length != 0 && VariableMtrr[Index].Type == CacheUncacheable) { + Status = MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, VariableMtrr[Index].Type + ); + if (Status == RETURN_OUT_OF_RESOURCES) { + return Status; + } + } + } + return RETURN_SUCCESS; +} + +/** + Return the memory type bit mask that's compatible to first type in the Ranges. + + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + + @return Compatible memory type bit mask. +**/ +UINT8 +MtrrLibGetCompatibleTypes ( + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount + ) +{ + ASSERT (RangeCount != 0); + + switch (Ranges[0].Type) { + case CacheWriteBack: + case CacheWriteThrough: + return (1 << CacheWriteBack) | (1 << CacheWriteThrough) | (1 << CacheUncacheable); + break; + + case CacheWriteCombining: + case CacheWriteProtected: + return (1 << Ranges[0].Type) | (1 << CacheUncacheable); + break; + + case CacheUncacheable: + if (RangeCount == 1) { + return (1 << CacheUncacheable); + } + return MtrrLibGetCompatibleTypes (&Ranges[1], RangeCount - 1); + break; + + case CacheInvalid: + default: + ASSERT (FALSE); + break; + } + return 0; +} + +/** + Overwrite the destination MTRR settings with the source MTRR settings. + This routine is to make sure the modification to destination MTRR settings + is as small as possible. + + @param DstMtrrs Destination MTRR settings. + @param DstMtrrCount Count of destination MTRR settings. + @param SrcMtrrs Source MTRR settings. + @param SrcMtrrCount Count of source MTRR settings. + @param Modified Flag array to indicate which destination MTRR setting is modified. +**/ +VOID +MtrrLibMergeVariableMtrr ( + MTRR_MEMORY_RANGE *DstMtrrs, + UINT32 DstMtrrCount, + MTRR_MEMORY_RANGE *SrcMtrrs, + UINT32 SrcMtrrCount, + BOOLEAN *Modified + ) +{ + UINT32 DstIndex; + UINT32 SrcIndex; + + ASSERT (SrcMtrrCount <= DstMtrrCount); + + for (DstIndex = 0; DstIndex < DstMtrrCount; DstIndex++) { + Modified[DstIndex] = FALSE; + + if (DstMtrrs[DstIndex].Length == 0) { + continue; + } + for (SrcIndex = 0; SrcIndex < SrcMtrrCount; SrcIndex++) { + if (DstMtrrs[DstIndex].BaseAddress == SrcMtrrs[SrcIndex].BaseAddress && + DstMtrrs[DstIndex].Length == SrcMtrrs[SrcIndex].Length && + DstMtrrs[DstIndex].Type == SrcMtrrs[SrcIndex].Type) { + break; + } + } + + if (SrcIndex == SrcMtrrCount) { + // + // Remove the one from DstMtrrs which is not in SrcMtrrs + // + DstMtrrs[DstIndex].Length = 0; + Modified[DstIndex] = TRUE; + } else { + // + // Remove the one from SrcMtrrs which is also in DstMtrrs + // + SrcMtrrs[SrcIndex].Length = 0; + } + } + + // + // Now valid MTRR only exists in either DstMtrrs or SrcMtrrs. + // Merge MTRRs from SrcMtrrs to DstMtrrs + // + DstIndex = 0; + for (SrcIndex = 0; SrcIndex < SrcMtrrCount; SrcIndex++) { + if (SrcMtrrs[SrcIndex].Length != 0) { + + // + // Find the empty slot in DstMtrrs + // + while (DstIndex < DstMtrrCount) { + if (DstMtrrs[DstIndex].Length == 0) { + break; + } + DstIndex++; + } + ASSERT (DstIndex < DstMtrrCount); + CopyMem (&DstMtrrs[DstIndex], &SrcMtrrs[SrcIndex], sizeof (SrcMtrrs[0])); + Modified[DstIndex] = TRUE; + } + } +} + +/** + Calculate the variable MTRR settings for all memory ranges. + + @param DefaultType Default memory type. + @param A0 Alignment to use when base address is 0. + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + @param Scratch Scratch buffer to be used in MTRR calculation. + @param ScratchSize Pointer to the size of scratch buffer. + @param VariableMtrr Array holding all MTRR settings. + @param VariableMtrrCapacity Capacity of the MTRR array. + @param VariableMtrrCount The count of MTRR settings in array. + + @retval RETURN_SUCCESS Variable MTRRs are allocated successfully. + @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity. + @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation. + The required scratch buffer size is returned through ScratchSize. +**/ +RETURN_STATUS +MtrrLibSetMemoryRanges ( + IN MTRR_MEMORY_CACHE_TYPE DefaultType, + IN UINT64 A0, + IN MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount, + IN VOID *Scratch, + IN OUT UINTN *ScratchSize, + OUT MTRR_MEMORY_RANGE *VariableMtrr, + IN UINT32 VariableMtrrCapacity, + OUT UINT32 *VariableMtrrCount + ) +{ + RETURN_STATUS Status; + UINT32 Index; + UINT64 Base0; + UINT64 Base1; + UINT64 Alignment; + UINT8 CompatibleTypes; + UINT64 Length; + UINT32 End; + UINTN ActualScratchSize; + UINTN BiggestScratchSize; + + *VariableMtrrCount = 0; + + // + // Since the whole ranges need multiple calls of MtrrLibCalculateMtrrs(). + // Each call needs different scratch buffer size. + // When the provided scratch buffer size is not sufficient in any call, + // set the GetActualScratchSize to TRUE, and following calls will only + // calculate the actual scratch size for the caller. + // + BiggestScratchSize = 0; + + for (Index = 0; Index < RangeCount;) { + Base0 = Ranges[Index].BaseAddress; + + // + // Full step is optimal + // + while (Index < RangeCount) { + ASSERT (Ranges[Index].BaseAddress == Base0); + Alignment = MtrrLibBiggestAlignment (Base0, A0); + while (Base0 + Alignment <= Ranges[Index].BaseAddress + Ranges[Index].Length) { + if ((BiggestScratchSize <= *ScratchSize) && (Ranges[Index].Type != DefaultType)) { + Status = MtrrLibAppendVariableMtrr ( + VariableMtrr, VariableMtrrCapacity, VariableMtrrCount, + Base0, Alignment, Ranges[Index].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + Base0 += Alignment; + Alignment = MtrrLibBiggestAlignment (Base0, A0); + } + + // + // Remove the above range from Ranges[Index] + // + Ranges[Index].Length -= Base0 - Ranges[Index].BaseAddress; + Ranges[Index].BaseAddress = Base0; + if (Ranges[Index].Length != 0) { + break; + } else { + Index++; + } + } + + if (Index == RangeCount) { + break; + } + + // + // Find continous ranges [Base0, Base1) which could be combined by MTRR. + // Per SDM, the compatible types between[B0, B1) are: + // UC, * + // WB, WT + // UC, WB, WT + // + CompatibleTypes = MtrrLibGetCompatibleTypes (&Ranges[Index], RangeCount - Index); + + End = Index; // End points to last one that matches the CompatibleTypes. + while (End + 1 < RangeCount) { + if (((1 << Ranges[End + 1].Type) & CompatibleTypes) == 0) { + break; + } + End++; + } + Alignment = MtrrLibBiggestAlignment (Base0, A0); + Length = GetPowerOfTwo64 (Ranges[End].BaseAddress + Ranges[End].Length - Base0); + Base1 = Base0 + MIN (Alignment, Length); + + // + // Base1 may not in Ranges[End]. Update End to the range Base1 belongs to. + // + End = Index; + while (End + 1 < RangeCount) { + if (Base1 <= Ranges[End + 1].BaseAddress) { + break; + } + End++; + } + + Length = Ranges[End].Length; + Ranges[End].Length = Base1 - Ranges[End].BaseAddress; + ActualScratchSize = *ScratchSize; + Status = MtrrLibCalculateMtrrs ( + DefaultType, A0, + &Ranges[Index], End + 1 - Index, + Scratch, &ActualScratchSize, + VariableMtrr, VariableMtrrCapacity, VariableMtrrCount + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + BiggestScratchSize = MAX (BiggestScratchSize, ActualScratchSize); + // + // Ignore this error, because we need to calculate the biggest + // scratch buffer size. + // + Status = RETURN_SUCCESS; + } + if (RETURN_ERROR (Status)) { + return Status; + } + + if (Length != Ranges[End].Length) { + Ranges[End].BaseAddress = Base1; + Ranges[End].Length = Length - Ranges[End].Length; + Index = End; + } else { + Index = End + 1; + } + } + + if (*ScratchSize < BiggestScratchSize) { + *ScratchSize = BiggestScratchSize; + return RETURN_BUFFER_TOO_SMALL; + } + return RETURN_SUCCESS; +} + +/** + Set the below-1MB memory attribute to fixed MTRR buffer. + Modified flag array indicates which fixed MTRR is modified. + + @param [in, out] ClearMasks The bits (when set) to clear in the fixed MTRR MSR. + @param [in, out] OrMasks The bits to set in the fixed MTRR MSR. + @param [in] BaseAddress Base address. + @param [in] Length Length. + @param [in] Type Memory type. + + @retval RETURN_SUCCESS The memory attribute is set successfully. + @retval RETURN_UNSUPPORTED The requested range or cache type was invalid + for the fixed MTRRs. +**/ +RETURN_STATUS +MtrrLibSetBelow1MBMemoryAttribute ( + IN OUT UINT64 *ClearMasks, + IN OUT UINT64 *OrMasks, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type + ) +{ + RETURN_STATUS Status; + UINT32 MsrIndex; + UINT64 ClearMask; + UINT64 OrMask; + + ASSERT (BaseAddress < BASE_1MB); + + MsrIndex = (UINT32)-1; + while ((BaseAddress < BASE_1MB) && (Length != 0)) { + Status = MtrrLibProgramFixedMtrr (Type, &BaseAddress, &Length, &MsrIndex, &ClearMask, &OrMask); + if (RETURN_ERROR (Status)) { + return Status; + } + ClearMasks[MsrIndex] = ClearMasks[MsrIndex] | ClearMask; + OrMasks[MsrIndex] = (OrMasks[MsrIndex] & ~ClearMask) | OrMask; + } + return RETURN_SUCCESS; +} + +/** + This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] Scratch A temporary scratch buffer that is used to perform the calculation. + @param[in, out] ScratchSize Pointer to the size in bytes of the scratch buffer. + It may be updated to the actual required size when the calculation + needs more scratch buffer. + @param[in] Ranges Pointer to an array of MTRR_MEMORY_RANGE. + When range overlap happens, the last one takes higher priority. + When the function returns, either all the attributes are set successfully, + or none of them is set. + @param[in] RangeCount Count of MTRR_MEMORY_RANGE. + + @retval RETURN_SUCCESS The attributes were set for all the memory ranges. + @retval RETURN_INVALID_PARAMETER Length in any range is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length in any range. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length in any range. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource ranges. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributesInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN VOID *Scratch, + IN OUT UINTN *ScratchSize, + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount + ) +{ + RETURN_STATUS Status; + UINT32 Index; + UINT64 BaseAddress; + UINT64 Length; + BOOLEAN Above1MbExist; + + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + MTRR_MEMORY_CACHE_TYPE DefaultType; + MTRR_VARIABLE_SETTINGS VariableSettings; + MTRR_MEMORY_RANGE WorkingRanges[2 * ARRAY_SIZE (MtrrSetting->Variables.Mtrr) + 2]; + UINTN WorkingRangeCount; + BOOLEAN Modified; + MTRR_VARIABLE_SETTING VariableSetting; + UINT32 OriginalVariableMtrrCount; + UINT32 FirmwareVariableMtrrCount; + UINT32 WorkingVariableMtrrCount; + MTRR_MEMORY_RANGE OriginalVariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)]; + MTRR_MEMORY_RANGE WorkingVariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)]; + BOOLEAN VariableSettingModified[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)]; + + UINT64 ClearMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)]; + UINT64 OrMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)]; + + MTRR_CONTEXT MtrrContext; + BOOLEAN MtrrContextValid; + + Status = RETURN_SUCCESS; + MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); + + // + // TRUE indicating the accordingly Variable setting needs modificaiton in OriginalVariableMtrr. + // + SetMem (VariableSettingModified, ARRAY_SIZE (VariableSettingModified), FALSE); + + // + // TRUE indicating the caller requests to set variable MTRRs. + // + Above1MbExist = FALSE; + OriginalVariableMtrrCount = 0; + + // + // 0. Dump the requests. + // + DEBUG_CODE ( + DEBUG ((DEBUG_CACHE, "Mtrr: Set Mem Attribute to %a, ScratchSize = %x%a", + (MtrrSetting == NULL) ? "Hardware" : "Buffer", *ScratchSize, + (RangeCount <= 1) ? "," : "\n" + )); + for (Index = 0; Index < RangeCount; Index++) { + DEBUG ((DEBUG_CACHE, " %a: [%016lx, %016lx)\n", + mMtrrMemoryCacheTypeShortName[MIN (Ranges[Index].Type, CacheInvalid)], + Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length + )); + } + ); + + // + // 1. Validate the parameters. + // + if (!IsMtrrSupported ()) { + Status = RETURN_UNSUPPORTED; + goto Exit; + } + + for (Index = 0; Index < RangeCount; Index++) { + if (Ranges[Index].Length == 0) { + Status = RETURN_INVALID_PARAMETER; + goto Exit; + } + if (((Ranges[Index].BaseAddress & ~MtrrValidAddressMask) != 0) || + ((((Ranges[Index].BaseAddress + Ranges[Index].Length) & ~MtrrValidAddressMask) != 0) && + (Ranges[Index].BaseAddress + Ranges[Index].Length) != MtrrValidBitsMask + 1) + ) { + // + // Either the BaseAddress or the Limit doesn't follow the alignment requirement. + // Note: It's still valid if Limit doesn't follow the alignment requirement but equals to MAX Address. + // + Status = RETURN_UNSUPPORTED; + goto Exit; + } + if ((Ranges[Index].Type != CacheUncacheable) && + (Ranges[Index].Type != CacheWriteCombining) && + (Ranges[Index].Type != CacheWriteThrough) && + (Ranges[Index].Type != CacheWriteProtected) && + (Ranges[Index].Type != CacheWriteBack)) { + Status = RETURN_INVALID_PARAMETER; + goto Exit; + } + if (Ranges[Index].BaseAddress + Ranges[Index].Length > BASE_1MB) { + Above1MbExist = TRUE; + } + } + + // + // 2. Apply the above-1MB memory attribute settings. + // + if (Above1MbExist) { + // + // 2.1. Read all variable MTRRs and convert to Ranges. + // + OriginalVariableMtrrCount = GetVariableMtrrCountWorker (); + MtrrGetVariableMtrrWorker (MtrrSetting, OriginalVariableMtrrCount, &VariableSettings); + MtrrLibGetRawVariableRanges ( + &VariableSettings, OriginalVariableMtrrCount, + MtrrValidBitsMask, MtrrValidAddressMask, OriginalVariableMtrr + ); + + DefaultType = MtrrGetDefaultMemoryTypeWorker (MtrrSetting); + WorkingRangeCount = 1; + WorkingRanges[0].BaseAddress = 0; + WorkingRanges[0].Length = MtrrValidBitsMask + 1; + WorkingRanges[0].Type = DefaultType; + + Status = MtrrLibApplyVariableMtrrs ( + OriginalVariableMtrr, OriginalVariableMtrrCount, + WorkingRanges, ARRAY_SIZE (WorkingRanges), &WorkingRangeCount); + ASSERT_RETURN_ERROR (Status); + + ASSERT (OriginalVariableMtrrCount >= PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs)); + FirmwareVariableMtrrCount = OriginalVariableMtrrCount - PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs); + ASSERT (WorkingRangeCount <= 2 * FirmwareVariableMtrrCount + 1); + + // + // 2.2. Force [0, 1M) to UC, so that it doesn't impact subtraction algorithm. + // + Status = MtrrLibSetMemoryType ( + WorkingRanges, ARRAY_SIZE (WorkingRanges), &WorkingRangeCount, + 0, SIZE_1MB, CacheUncacheable + ); + ASSERT (Status != RETURN_OUT_OF_RESOURCES); + + // + // 2.3. Apply the new memory attribute settings to Ranges. + // + Modified = FALSE; + for (Index = 0; Index < RangeCount; Index++) { + BaseAddress = Ranges[Index].BaseAddress; + Length = Ranges[Index].Length; + if (BaseAddress < BASE_1MB) { + if (Length <= BASE_1MB - BaseAddress) { + continue; + } + Length -= BASE_1MB - BaseAddress; + BaseAddress = BASE_1MB; + } + Status = MtrrLibSetMemoryType ( + WorkingRanges, ARRAY_SIZE (WorkingRanges), &WorkingRangeCount, + BaseAddress, Length, Ranges[Index].Type + ); + if (Status == RETURN_ALREADY_STARTED) { + Status = RETURN_SUCCESS; + } else if (Status == RETURN_OUT_OF_RESOURCES) { + goto Exit; + } else { + ASSERT_RETURN_ERROR (Status); + Modified = TRUE; + } + } + + if (Modified) { + // + // 2.4. Calculate the Variable MTRR settings based on the Ranges. + // Buffer Too Small may be returned if the scratch buffer size is insufficient. + // + Status = MtrrLibSetMemoryRanges ( + DefaultType, LShiftU64 (1, (UINTN)HighBitSet64 (MtrrValidBitsMask)), WorkingRanges, WorkingRangeCount, + Scratch, ScratchSize, + WorkingVariableMtrr, FirmwareVariableMtrrCount + 1, &WorkingVariableMtrrCount + ); + if (RETURN_ERROR (Status)) { + goto Exit; + } + + // + // 2.5. Remove the [0, 1MB) MTRR if it still exists (not merged with other range) + // + for (Index = 0; Index < WorkingVariableMtrrCount; Index++) { + if (WorkingVariableMtrr[Index].BaseAddress == 0 && WorkingVariableMtrr[Index].Length == SIZE_1MB) { + ASSERT (WorkingVariableMtrr[Index].Type == CacheUncacheable); + WorkingVariableMtrrCount--; + CopyMem ( + &WorkingVariableMtrr[Index], &WorkingVariableMtrr[Index + 1], + (WorkingVariableMtrrCount - Index) * sizeof (WorkingVariableMtrr[0]) + ); + break; + } + } + + if (WorkingVariableMtrrCount > FirmwareVariableMtrrCount) { + Status = RETURN_OUT_OF_RESOURCES; + goto Exit; + } + + // + // 2.6. Merge the WorkingVariableMtrr to OriginalVariableMtrr + // Make sure least modification is made to OriginalVariableMtrr. + // + MtrrLibMergeVariableMtrr ( + OriginalVariableMtrr, OriginalVariableMtrrCount, + WorkingVariableMtrr, WorkingVariableMtrrCount, + VariableSettingModified + ); + } + } + + // + // 3. Apply the below-1MB memory attribute settings. + // + // (Value & ~0 | 0) still equals to (Value) + // + ZeroMem (ClearMasks, sizeof (ClearMasks)); + ZeroMem (OrMasks, sizeof (OrMasks)); + for (Index = 0; Index < RangeCount; Index++) { + if (Ranges[Index].BaseAddress >= BASE_1MB) { + continue; + } + + Status = MtrrLibSetBelow1MBMemoryAttribute ( + ClearMasks, OrMasks, + Ranges[Index].BaseAddress, Ranges[Index].Length, Ranges[Index].Type + ); + if (RETURN_ERROR (Status)) { + goto Exit; + } + } + + MtrrContextValid = FALSE; + // + // 4. Write fixed MTRRs that have been modified + // + for (Index = 0; Index < ARRAY_SIZE (ClearMasks); Index++) { + if (ClearMasks[Index] != 0) { + if (MtrrSetting != NULL) { + MtrrSetting->Fixed.Mtrr[Index] = (MtrrSetting->Fixed.Mtrr[Index] & ~ClearMasks[Index]) | OrMasks[Index]; + } else { + if (!MtrrContextValid) { + MtrrLibPreMtrrChange (&MtrrContext); + MtrrContextValid = TRUE; + } + AsmMsrAndThenOr64 (mMtrrLibFixedMtrrTable[Index].Msr, ~ClearMasks[Index], OrMasks[Index]); + } + } + } + + // + // 5. Write variable MTRRs that have been modified + // + for (Index = 0; Index < OriginalVariableMtrrCount; Index++) { + if (VariableSettingModified[Index]) { + if (OriginalVariableMtrr[Index].Length != 0) { + VariableSetting.Base = (OriginalVariableMtrr[Index].BaseAddress & MtrrValidAddressMask) + | (UINT8)OriginalVariableMtrr[Index].Type; + VariableSetting.Mask = ((~(OriginalVariableMtrr[Index].Length - 1)) & MtrrValidAddressMask) | BIT11; + } else { + VariableSetting.Base = 0; + VariableSetting.Mask = 0; + } + if (MtrrSetting != NULL) { + CopyMem (&MtrrSetting->Variables.Mtrr[Index], &VariableSetting, sizeof (VariableSetting)); + } else { + if (!MtrrContextValid) { + MtrrLibPreMtrrChange (&MtrrContext); + MtrrContextValid = TRUE; + } + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), + VariableSetting.Base + ); + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), + VariableSetting.Mask + ); + } + } + } + + if (MtrrSetting != NULL) { + ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType)->Bits.E = 1; + ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType)->Bits.FE = 1; + } else { + if (MtrrContextValid) { + MtrrLibPostMtrrChange (&MtrrContext); + } + } + +Exit: + DEBUG ((DEBUG_CACHE, " Result = %r\n", Status)); + if (!RETURN_ERROR (Status)) { + MtrrDebugPrintAllMtrrsWorker (MtrrSetting); + } + return Status; +} + +/** + This function attempts to set the attributes into MTRR setting buffer for a memory range. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] BaseAddress The physical address that is the start address + of a memory range. + @param[in] Length The size in bytes of the memory range. + @param[in] Attribute The bit mask of attributes to set for the + memory range. + + @retval RETURN_SUCCESS The attributes were set for the memory range. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributeInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ) +{ + UINT8 Scratch[SCRATCH_BUFFER_SIZE]; + UINTN ScratchSize; + MTRR_MEMORY_RANGE Range; + + Range.BaseAddress = BaseAddress; + Range.Length = Length; + Range.Type = Attribute; + ScratchSize = sizeof (Scratch); + return MtrrSetMemoryAttributesInMtrrSettings (MtrrSetting, Scratch, &ScratchSize, &Range, 1); +} + +/** + This function attempts to set the attributes for a memory range. + + @param[in] BaseAddress The physical address that is the start + address of a memory range. + @param[in] Length The size in bytes of the memory range. + @param[in] Attributes The bit mask of attributes to set for the + memory range. + + @retval RETURN_SUCCESS The attributes were set for the memory + range. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or + more bytes of the memory resource range + specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support + for the memory resource range specified + by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource + range specified by BaseAddress and Length + cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to + modify the attributes of the memory + resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttribute ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ) +{ + return MtrrSetMemoryAttributeInMtrrSettings (NULL, BaseAddress, Length, Attribute); +} + +/** + Worker function setting variable MTRRs + + @param[in] VariableSettings A buffer to hold variable MTRRs content. + +**/ +VOID +MtrrSetVariableMtrrWorker ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + UINT32 Index; + UINT32 VariableMtrrCount; + + VariableMtrrCount = GetVariableMtrrCountWorker (); + ASSERT (VariableMtrrCount <= ARRAY_SIZE (VariableSettings->Mtrr)); + + for (Index = 0; Index < VariableMtrrCount; Index++) { + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), + VariableSettings->Mtrr[Index].Base + ); + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), + VariableSettings->Mtrr[Index].Mask + ); + } +} + + +/** + This function sets variable MTRRs + + @param[in] VariableSettings A buffer to hold variable MTRRs content. + + @return The pointer of VariableSettings + +**/ +MTRR_VARIABLE_SETTINGS* +EFIAPI +MtrrSetVariableMtrr ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + MTRR_CONTEXT MtrrContext; + + if (!IsMtrrSupported ()) { + return VariableSettings; + } + + MtrrLibPreMtrrChange (&MtrrContext); + MtrrSetVariableMtrrWorker (VariableSettings); + MtrrLibPostMtrrChange (&MtrrContext); + MtrrDebugPrintAllMtrrs (); + + return VariableSettings; +} + +/** + Worker function setting fixed MTRRs + + @param[in] FixedSettings A buffer to hold fixed MTRRs content. + +**/ +VOID +MtrrSetFixedMtrrWorker ( + IN MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + UINT32 Index; + + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + AsmWriteMsr64 ( + mMtrrLibFixedMtrrTable[Index].Msr, + FixedSettings->Mtrr[Index] + ); + } +} + + +/** + This function sets fixed MTRRs + + @param[in] FixedSettings A buffer to hold fixed MTRRs content. + + @retval The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrSetFixedMtrr ( + IN MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + MTRR_CONTEXT MtrrContext; + + if (!IsMtrrSupported ()) { + return FixedSettings; + } + + MtrrLibPreMtrrChange (&MtrrContext); + MtrrSetFixedMtrrWorker (FixedSettings); + MtrrLibPostMtrrChange (&MtrrContext); + MtrrDebugPrintAllMtrrs (); + + return FixedSettings; +} + + +/** + This function gets the content in all MTRRs (variable and fixed) + + @param[out] MtrrSetting A buffer to hold all MTRRs content. + + @retval the pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrGetAllMtrrs ( + OUT MTRR_SETTINGS *MtrrSetting + ) +{ + if (!IsMtrrSupported ()) { + return MtrrSetting; + } + + // + // Get fixed MTRRs + // + MtrrGetFixedMtrrWorker (&MtrrSetting->Fixed); + + // + // Get variable MTRRs + // + MtrrGetVariableMtrrWorker ( + NULL, + GetVariableMtrrCountWorker (), + &MtrrSetting->Variables + ); + + // + // Get MTRR_DEF_TYPE value + // + MtrrSetting->MtrrDefType = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + + return MtrrSetting; +} + + +/** + This function sets all MTRRs (variable and fixed) + + @param[in] MtrrSetting A buffer holding all MTRRs content. + + @retval The pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrSetAllMtrrs ( + IN MTRR_SETTINGS *MtrrSetting + ) +{ + MTRR_CONTEXT MtrrContext; + + if (!IsMtrrSupported ()) { + return MtrrSetting; + } + + MtrrLibPreMtrrChange (&MtrrContext); + + // + // Set fixed MTRRs + // + MtrrSetFixedMtrrWorker (&MtrrSetting->Fixed); + + // + // Set variable MTRRs + // + MtrrSetVariableMtrrWorker (&MtrrSetting->Variables); + + // + // Set MTRR_DEF_TYPE value + // + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); + + MtrrLibPostMtrrChangeEnableCache (&MtrrContext); + + return MtrrSetting; +} + + +/** + Checks if MTRR is supported. + + @retval TRUE MTRR is supported. + @retval FALSE MTRR is not supported. + +**/ +BOOLEAN +EFIAPI +IsMtrrSupported ( + VOID + ) +{ + CPUID_VERSION_INFO_EDX Edx; + MSR_IA32_MTRRCAP_REGISTER MtrrCap; + + // + // Check CPUID(1).EDX[12] for MTRR capability + // + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32); + if (Edx.Bits.MTRR == 0) { + return FALSE; + } + + // + // Check number of variable MTRRs and fixed MTRRs existence. + // If number of variable MTRRs is zero, or fixed MTRRs do not + // exist, return false. + // + MtrrCap.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP); + if ((MtrrCap.Bits.VCNT == 0) || (MtrrCap.Bits.FIX == 0)) { + return FALSE; + } + return TRUE; +} + + +/** + Worker function prints all MTRRs for debugging. + + If MtrrSetting is not NULL, print MTRR settings from input MTRR + settings buffer. + If MtrrSetting is NULL, print MTRR settings from MTRRs. + + @param MtrrSetting A buffer holding all MTRRs content. +**/ +VOID +MtrrDebugPrintAllMtrrsWorker ( + IN MTRR_SETTINGS *MtrrSetting + ) +{ + DEBUG_CODE ( + MTRR_SETTINGS LocalMtrrs; + MTRR_SETTINGS *Mtrrs; + UINTN Index; + UINTN RangeCount; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + UINT32 VariableMtrrCount; + BOOLEAN ContainVariableMtrr; + MTRR_MEMORY_RANGE Ranges[ + ARRAY_SIZE (mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1 + ]; + MTRR_MEMORY_RANGE RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)]; + + if (!IsMtrrSupported ()) { + return; + } + + VariableMtrrCount = GetVariableMtrrCountWorker (); + + if (MtrrSetting != NULL) { + Mtrrs = MtrrSetting; + } else { + MtrrGetAllMtrrs (&LocalMtrrs); + Mtrrs = &LocalMtrrs; + } + + // + // Dump RAW MTRR contents + // + DEBUG ((DEBUG_CACHE, "MTRR Settings:\n")); + DEBUG ((DEBUG_CACHE, "=============\n")); + DEBUG ((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType)); + for (Index = 0; Index < ARRAY_SIZE (mMtrrLibFixedMtrrTable); Index++) { + DEBUG ((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index])); + } + ContainVariableMtrr = FALSE; + for (Index = 0; Index < VariableMtrrCount; Index++) { + if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) { + // + // If mask is not valid, then do not display range + // + continue; + } + ContainVariableMtrr = TRUE; + DEBUG ((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n", + Index, + Mtrrs->Variables.Mtrr[Index].Base, + Mtrrs->Variables.Mtrr[Index].Mask + )); + } + if (!ContainVariableMtrr) { + DEBUG ((DEBUG_CACHE, "Variable MTRR : None.\n")); + } + DEBUG((DEBUG_CACHE, "\n")); + + // + // Dump MTRR setting in ranges + // + DEBUG((DEBUG_CACHE, "Memory Ranges:\n")); + DEBUG((DEBUG_CACHE, "====================================\n")); + MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); + Ranges[0].BaseAddress = 0; + Ranges[0].Length = MtrrValidBitsMask + 1; + Ranges[0].Type = MtrrGetDefaultMemoryTypeWorker (Mtrrs); + RangeCount = 1; + + MtrrLibGetRawVariableRanges ( + &Mtrrs->Variables, VariableMtrrCount, + MtrrValidBitsMask, MtrrValidAddressMask, RawVariableRanges + ); + MtrrLibApplyVariableMtrrs ( + RawVariableRanges, VariableMtrrCount, + Ranges, ARRAY_SIZE (Ranges), &RangeCount + ); + + MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &RangeCount); + + for (Index = 0; Index < RangeCount; Index++) { + DEBUG ((DEBUG_CACHE, "%a:%016lx-%016lx\n", + mMtrrMemoryCacheTypeShortName[Ranges[Index].Type], + Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length - 1 + )); + } + ); +} + +/** + This function prints all MTRRs for debugging. +**/ +VOID +EFIAPI +MtrrDebugPrintAllMtrrs ( + VOID + ) +{ + MtrrDebugPrintAllMtrrsWorker (NULL); +} diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf b/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf new file mode 100644 index 000000000..4c9ea2def --- /dev/null +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf @@ -0,0 +1,40 @@ +## @file +# MTRR library provides APIs for MTRR operation. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MtrrLib + MODULE_UNI_FILE = MtrrLib.uni + FILE_GUID = 6826b408-f4f3-47ee-917f-af7047f9d937 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MtrrLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MtrrLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseMemoryLib + BaseLib + CpuLib + DebugLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs ## SOMETIMES_CONSUMES + diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni b/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni new file mode 100644 index 000000000..646ec2a37 --- /dev/null +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni @@ -0,0 +1,16 @@ +// /** @file +// MTRR library provides APIs for MTRR operation. +// +// MTRR library provides APIs for MTRR operation. +// +// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "MTRR library provides APIs for MTRR operation" + +#string STR_MODULE_DESCRIPTION #language en-US "MTRR library provides APIs for MTRR operation." + diff --git a/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c new file mode 100644 index 000000000..cebaa8139 --- /dev/null +++ b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c @@ -0,0 +1,84 @@ +/** @file +Null instance of Platform Sec Lib. + +Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +{ + return NULL; +} + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param PeiServices Pointer to the PEI Services Table. + @param StructureSize Pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + return EFI_SUCCESS; +} + +/** + This interface disables temporary memory in SEC Phase. +**/ +VOID +EFIAPI +SecPlatformDisableTemporaryMemory ( + VOID + ) +{ +} + +/** + This function provides dummy function so that SecCore can pass build + validation. All real platform library instances need to implement the real + entry point in assembly. +**/ +VOID +EFIAPI +_ModuleEntryPoint ( + VOID + ) +{ + return; +} diff --git a/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf new file mode 100644 index 000000000..37d80b7ff --- /dev/null +++ b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf @@ -0,0 +1,31 @@ +## @file +# Library functions for PlatformSecLib. +# +# Null instance of Platform Sec Lib. +# +# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformSecLibNull + MODULE_UNI_FILE = PlatformSecLibNull.uni + FILE_GUID = 6695974D-968C-420b-80B9-7870CD20118F + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformSecLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PlatformSecLibNull.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec diff --git a/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni new file mode 100644 index 000000000..42f461374 --- /dev/null +++ b/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni @@ -0,0 +1,14 @@ +// /** @file +// Library functions for PlatformSecLib. +// +// Null instance of Platform Sec Library. +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library functions for PlatformSecLib" + +#string STR_MODULE_DESCRIPTION #language en-US "Null instance of Platform Sec Library." diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c new file mode 100644 index 000000000..5c673fa8c --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c @@ -0,0 +1,1184 @@ +/** @file + CPU Features Initialize functions. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RegisterCpuFeatures.h" + +CHAR16 *mDependTypeStr[] = {L"None", L"Thread", L"Core", L"Package", L"Invalid" }; + +/** + Worker function to save PcdCpuFeaturesCapability. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +SetCapabilityPcd ( + IN UINT8 *SupportedFeatureMask, + IN UINTN BitMaskSize + ) +{ + EFI_STATUS Status; + + Status = PcdSetPtrS (PcdCpuFeaturesCapability, &BitMaskSize, SupportedFeatureMask); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to save PcdCpuFeaturesSetting. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] BitMaskSize CPU feature bits mask buffer size. +**/ +VOID +SetSettingPcd ( + IN UINT8 *SupportedFeatureMask, + IN UINTN BitMaskSize + ) +{ + EFI_STATUS Status; + + Status = PcdSetPtrS (PcdCpuFeaturesSetting, &BitMaskSize, SupportedFeatureMask); + ASSERT_EFI_ERROR (Status); +} + +/** + Collects CPU type and feature information. + + @param[in, out] CpuInfo The pointer to CPU feature information +**/ +VOID +FillProcessorInfo ( + IN OUT REGISTER_CPU_FEATURE_INFORMATION *CpuInfo + ) +{ + CPUID_VERSION_INFO_EAX Eax; + CPUID_VERSION_INFO_ECX Ecx; + CPUID_VERSION_INFO_EDX Edx; + UINT32 DisplayedFamily; + UINT32 DisplayedModel; + + AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, &Ecx.Uint32, &Edx.Uint32); + + DisplayedFamily = Eax.Bits.FamilyId; + if (Eax.Bits.FamilyId == 0x0F) { + DisplayedFamily |= (Eax.Bits.ExtendedFamilyId << 4); + } + + DisplayedModel = Eax.Bits.Model; + if (Eax.Bits.FamilyId == 0x06 || Eax.Bits.FamilyId == 0x0f) { + DisplayedModel |= (Eax.Bits.ExtendedModelId << 4); + } + + CpuInfo->DisplayFamily = DisplayedFamily; + CpuInfo->DisplayModel = DisplayedModel; + CpuInfo->SteppingId = Eax.Bits.SteppingId; + CpuInfo->ProcessorType = Eax.Bits.ProcessorType; + CpuInfo->CpuIdVersionInfoEcx.Uint32 = Ecx.Uint32; + CpuInfo->CpuIdVersionInfoEdx.Uint32 = Edx.Uint32; +} + +/** + Prepares for private data used for CPU features. + +**/ +VOID +CpuInitDataInitialize ( + VOID + ) +{ + EFI_STATUS Status; + UINTN ProcessorNumber; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + CPU_FEATURES_ENTRY *CpuFeature; + CPU_FEATURES_INIT_ORDER *InitOrder; + CPU_FEATURES_DATA *CpuFeaturesData; + LIST_ENTRY *Entry; + UINT32 Core; + UINT32 Package; + UINT32 Thread; + EFI_CPU_PHYSICAL_LOCATION *Location; + BOOLEAN *CoresVisited; + UINTN Index; + UINT32 PackageIndex; + UINT32 CoreIndex; + UINT32 First; + ACPI_CPU_DATA *AcpiCpuData; + CPU_STATUS_INFORMATION *CpuStatus; + UINT32 *ValidCoreCountPerPackage; + UINTN NumberOfCpus; + UINTN NumberOfEnabledProcessors; + + Core = 0; + Package = 0; + Thread = 0; + + CpuFeaturesData = GetCpuFeaturesData (); + + // + // Initialize CpuFeaturesData->MpService as early as possile, so later function can use it. + // + CpuFeaturesData->MpService = GetMpService (); + + GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors); + + CpuFeaturesData->InitOrder = AllocateZeroPool (sizeof (CPU_FEATURES_INIT_ORDER) * NumberOfCpus); + ASSERT (CpuFeaturesData->InitOrder != NULL); + + // + // Collect CPU Features information + // + Entry = GetFirstNode (&CpuFeaturesData->FeatureList); + while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) { + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + ASSERT (CpuFeature->InitializeFunc != NULL); + if (CpuFeature->GetConfigDataFunc != NULL) { + CpuFeature->ConfigData = CpuFeature->GetConfigDataFunc (NumberOfCpus); + } + Entry = Entry->ForwardLink; + } + + CpuFeaturesData->NumberOfCpus = (UINT32) NumberOfCpus; + + AcpiCpuData = GetAcpiCpuData (); + ASSERT (AcpiCpuData != NULL); + CpuFeaturesData->AcpiCpuData= AcpiCpuData; + + CpuStatus = &AcpiCpuData->CpuStatus; + Location = AllocateZeroPool (sizeof (EFI_CPU_PHYSICAL_LOCATION) * NumberOfCpus); + ASSERT (Location != NULL); + AcpiCpuData->ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)Location; + + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + InitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber]; + InitOrder->FeaturesSupportedMask = AllocateZeroPool (CpuFeaturesData->BitMaskSize); + ASSERT (InitOrder->FeaturesSupportedMask != NULL); + InitializeListHead (&InitOrder->OrderList); + Status = GetProcessorInformation (ProcessorNumber, &ProcessorInfoBuffer); + ASSERT_EFI_ERROR (Status); + CopyMem ( + &InitOrder->CpuInfo.ProcessorInfo, + &ProcessorInfoBuffer, + sizeof (EFI_PROCESSOR_INFORMATION) + ); + CopyMem ( + &Location[ProcessorNumber], + &ProcessorInfoBuffer.Location, + sizeof (EFI_CPU_PHYSICAL_LOCATION) + ); + + // + // Collect CPU package count info. + // + if (Package < ProcessorInfoBuffer.Location.Package) { + Package = ProcessorInfoBuffer.Location.Package; + } + // + // Collect CPU max core count info. + // + if (Core < ProcessorInfoBuffer.Location.Core) { + Core = ProcessorInfoBuffer.Location.Core; + } + // + // Collect CPU max thread count info. + // + if (Thread < ProcessorInfoBuffer.Location.Thread) { + Thread = ProcessorInfoBuffer.Location.Thread; + } + } + CpuStatus->PackageCount = Package + 1; + CpuStatus->MaxCoreCount = Core + 1; + CpuStatus->MaxThreadCount = Thread + 1; + DEBUG ((DEBUG_INFO, "Processor Info: Package: %d, MaxCore : %d, MaxThread: %d\n", + CpuStatus->PackageCount, + CpuStatus->MaxCoreCount, + CpuStatus->MaxThreadCount)); + + // + // Collect valid core count in each package because not all cores are valid. + // + ValidCoreCountPerPackage= AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount); + ASSERT (ValidCoreCountPerPackage != 0); + CpuStatus->ValidCoreCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ValidCoreCountPerPackage; + CoresVisited = AllocatePool (sizeof (BOOLEAN) * CpuStatus->MaxCoreCount); + ASSERT (CoresVisited != NULL); + + for (Index = 0; Index < CpuStatus->PackageCount; Index ++ ) { + ZeroMem (CoresVisited, sizeof (BOOLEAN) * CpuStatus->MaxCoreCount); + // + // Collect valid cores in Current package. + // + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == Index && !CoresVisited[Location->Core] ) { + // + // The ValidCores position for Location->Core is valid. + // The possible values in ValidCores[Index] are 0 or 1. + // FALSE means no valid threads in this Core. + // TRUE means have valid threads in this core, no matter the thead count is 1 or more. + // + CoresVisited[Location->Core] = TRUE; + ValidCoreCountPerPackage[Index]++; + } + } + } + FreePool (CoresVisited); + + for (Index = 0; Index <= Package; Index++) { + DEBUG ((DEBUG_INFO, "Package: %d, Valid Core : %d\n", Index, ValidCoreCountPerPackage[Index])); + } + + CpuFeaturesData->CpuFlags.CoreSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount); + ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL); + CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount); + ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL); + + // + // Initialize CpuFeaturesData->InitOrder[].CpuInfo.First + // + + // + // Set First.Package for each thread belonging to the first package. + // + First = MAX_UINT32; + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + First = MIN (Location->Package, First); + } + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == First) { + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1; + } + } + + // + // Set First.Die/Tile/Module for each thread assuming: + // single Die under each package, single Tile under each Die, single Module under each Tile + // + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Die = 1; + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Tile = 1; + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Module = 1; + } + + for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) { + // + // Set First.Core for each thread in the first core of each package. + // + First = MAX_UINT32; + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == PackageIndex) { + First = MIN (Location->Core, First); + } + } + + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == PackageIndex && Location->Core == First) { + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1; + } + } + } + + for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) { + for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) { + // + // Set First.Thread for the first thread of each core. + // + First = MAX_UINT32; + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == PackageIndex && Location->Core == CoreIndex) { + First = MIN (Location->Thread, First); + } + } + + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location; + if (Location->Package == PackageIndex && Location->Core == CoreIndex && Location->Thread == First) { + CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1; + } + } + } + } +} + +/** + Worker function to do OR operation on CPU feature supported bits mask buffer. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] OrFeatureBitMask The feature bit mask to do OR operation + @param[in] BitMaskSize The CPU feature bits mask buffer size. + +**/ +VOID +SupportedMaskOr ( + IN UINT8 *SupportedFeatureMask, + IN UINT8 *OrFeatureBitMask, + IN UINT32 BitMaskSize + ) +{ + UINTN Index; + UINT8 *Data1; + UINT8 *Data2; + + Data1 = SupportedFeatureMask; + Data2 = OrFeatureBitMask; + for (Index = 0; Index < BitMaskSize; Index++) { + *(Data1++) |= *(Data2++); + } +} + +/** + Worker function to do AND operation on CPU feature supported bits mask buffer. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] AndFeatureBitMask The feature bit mask to do AND operation + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +SupportedMaskAnd ( + IN UINT8 *SupportedFeatureMask, + IN CONST UINT8 *AndFeatureBitMask, + IN UINT32 BitMaskSize + ) +{ + UINTN Index; + UINT8 *Data1; + CONST UINT8 *Data2; + + Data1 = SupportedFeatureMask; + Data2 = AndFeatureBitMask; + for (Index = 0; Index < BitMaskSize; Index++) { + *(Data1++) &= *(Data2++); + } +} + +/** + Worker function to clean bit operation on CPU feature supported bits mask buffer. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] AndFeatureBitMask The feature bit mask to do XOR operation + @param[in] BitMaskSize CPU feature bits mask buffer size. +**/ +VOID +SupportedMaskCleanBit ( + IN UINT8 *SupportedFeatureMask, + IN UINT8 *AndFeatureBitMask, + IN UINT32 BitMaskSize + ) +{ + UINTN Index; + UINT8 *Data1; + UINT8 *Data2; + + Data1 = SupportedFeatureMask; + Data2 = AndFeatureBitMask; + for (Index = 0; Index < BitMaskSize; Index++) { + *(Data1++) &= ~(*(Data2++)); + } +} + +/** + Worker function to check if the compared CPU feature set in the CPU feature + supported bits mask buffer. + + @param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer + @param[in] ComparedFeatureBitMask The feature bit mask to be compared + @param[in] BitMaskSize CPU feature bits mask buffer size. + + @retval TRUE The ComparedFeatureBitMask is set in CPU feature supported bits + mask buffer. + @retval FALSE The ComparedFeatureBitMask is not set in CPU feature supported bits + mask buffer. +**/ +BOOLEAN +IsBitMaskMatch ( + IN UINT8 *SupportedFeatureMask, + IN UINT8 *ComparedFeatureBitMask, + IN UINT32 BitMaskSize + ) +{ + UINTN Index; + UINT8 *Data1; + UINT8 *Data2; + + Data1 = SupportedFeatureMask; + Data2 = ComparedFeatureBitMask; + for (Index = 0; Index < BitMaskSize; Index++) { + if (((*(Data1++)) & (*(Data2++))) != 0) { + return TRUE; + } + } + return FALSE; +} + +/** + Collects processor data for calling processor. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +CollectProcessorData ( + IN OUT VOID *Buffer + ) +{ + UINTN ProcessorNumber; + CPU_FEATURES_ENTRY *CpuFeature; + REGISTER_CPU_FEATURE_INFORMATION *CpuInfo; + LIST_ENTRY *Entry; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = (CPU_FEATURES_DATA *)Buffer; + ProcessorNumber = GetProcessorIndex (CpuFeaturesData); + CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo; + // + // collect processor information + // + FillProcessorInfo (CpuInfo); + Entry = GetFirstNode (&CpuFeaturesData->FeatureList); + while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) { + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + if (CpuFeature->SupportFunc == NULL) { + // + // If SupportFunc is NULL, then the feature is supported. + // + SupportedMaskOr ( + CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask, + CpuFeature->FeatureMask, + CpuFeaturesData->BitMaskSize + ); + } else if (CpuFeature->SupportFunc (ProcessorNumber, CpuInfo, CpuFeature->ConfigData)) { + SupportedMaskOr ( + CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask, + CpuFeature->FeatureMask, + CpuFeaturesData->BitMaskSize + ); + } + Entry = Entry->ForwardLink; + } +} + +/** + Dump the contents of a CPU register table. + + @param[in] ProcessorNumber The index of the CPU to show the register table contents + + @note This service could be called by BSP only. +**/ +VOID +DumpRegisterTableOnProcessor ( + IN UINTN ProcessorNumber + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + UINTN FeatureIndex; + CPU_REGISTER_TABLE *RegisterTable; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead; + UINT32 DebugPrintErrorLevel; + + DebugPrintErrorLevel = (ProcessorNumber == 0) ? DEBUG_INFO : DEBUG_VERBOSE; + CpuFeaturesData = GetCpuFeaturesData (); + // + // Debug information + // + RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber]; + DEBUG ((DebugPrintErrorLevel, "RegisterTable->TableLength = %d\n", RegisterTable->TableLength)); + + RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry; + + for (FeatureIndex = 0; FeatureIndex < RegisterTable->TableLength; FeatureIndex++) { + RegisterTableEntry = &RegisterTableEntryHead[FeatureIndex]; + switch (RegisterTableEntry->RegisterType) { + case Msr: + DEBUG (( + DebugPrintErrorLevel, + "Processor: %04d: Index %04d, MSR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n", + (UINT32) ProcessorNumber, + (UINT32) FeatureIndex, + RegisterTableEntry->Index, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitLength, + RegisterTableEntry->Value + )); + break; + case ControlRegister: + DEBUG (( + DebugPrintErrorLevel, + "Processor: %04d: Index %04d, CR : %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n", + (UINT32) ProcessorNumber, + (UINT32) FeatureIndex, + RegisterTableEntry->Index, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitLength, + RegisterTableEntry->Value + )); + break; + case MemoryMapped: + DEBUG (( + DebugPrintErrorLevel, + "Processor: %04d: Index %04d, MMIO : %016lx, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n", + (UINT32) ProcessorNumber, + (UINT32) FeatureIndex, + RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32), + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitLength, + RegisterTableEntry->Value + )); + break; + case CacheControl: + DEBUG (( + DebugPrintErrorLevel, + "Processor: %04d: Index %04d, CACHE: %08x, Bit Start: %02d, Bit Length: %02d, Value: %016lx\r\n", + (UINT32) ProcessorNumber, + (UINT32) FeatureIndex, + RegisterTableEntry->Index, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitLength, + RegisterTableEntry->Value + )); + break; + case Semaphore: + DEBUG (( + DebugPrintErrorLevel, + "Processor: %04d: Index %04d, SEMAP: %s\r\n", + (UINT32) ProcessorNumber, + (UINT32) FeatureIndex, + mDependTypeStr[MIN ((UINT32)RegisterTableEntry->Value, InvalidDepType)] + )); + break; + + default: + break; + } + } +} + +/** + Get the biggest dependence type. + PackageDepType > CoreDepType > ThreadDepType > NoneDepType. + + @param[in] BeforeDep Before dependence type. + @param[in] AfterDep After dependence type. + @param[in] NoneNeibBeforeDep Before dependence type for not neighborhood features. + @param[in] NoneNeibAfterDep After dependence type for not neighborhood features. + + @retval Return the biggest dependence type. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +BiggestDep ( + IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep, + IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep, + IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep, + IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep + ) +{ + CPU_FEATURE_DEPENDENCE_TYPE Bigger; + + Bigger = MAX (BeforeDep, AfterDep); + Bigger = MAX (Bigger, NoneNeibBeforeDep); + return MAX(Bigger, NoneNeibAfterDep); +} + +/** + Analysis register CPU features on each processor and save CPU setting in CPU register table. + + @param[in] NumberOfCpus Number of processor in system + +**/ +VOID +AnalysisProcessorFeatures ( + IN UINTN NumberOfCpus + ) +{ + EFI_STATUS Status; + UINTN ProcessorNumber; + CPU_FEATURES_ENTRY *CpuFeature; + CPU_FEATURES_ENTRY *CpuFeatureInOrder; + CPU_FEATURES_INIT_ORDER *CpuInitOrder; + REGISTER_CPU_FEATURE_INFORMATION *CpuInfo; + LIST_ENTRY *Entry; + CPU_FEATURES_DATA *CpuFeaturesData; + LIST_ENTRY *NextEntry; + CPU_FEATURES_ENTRY *NextCpuFeatureInOrder; + BOOLEAN Success; + CPU_FEATURE_DEPENDENCE_TYPE BeforeDep; + CPU_FEATURE_DEPENDENCE_TYPE AfterDep; + CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep; + CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuFeaturesData->CapabilityPcd = AllocatePool (CpuFeaturesData->BitMaskSize); + ASSERT (CpuFeaturesData->CapabilityPcd != NULL); + SetMem (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize, 0xFF); + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber]; + // + // Calculate the last capability on all processors + // + SupportedMaskAnd (CpuFeaturesData->CapabilityPcd, CpuInitOrder->FeaturesSupportedMask, CpuFeaturesData->BitMaskSize); + } + // + // Calculate the last setting + // + CpuFeaturesData->SettingPcd = AllocateCopyPool (CpuFeaturesData->BitMaskSize, CpuFeaturesData->CapabilityPcd); + ASSERT (CpuFeaturesData->SettingPcd != NULL); + SupportedMaskAnd (CpuFeaturesData->SettingPcd, PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize); + + // + // Dump the last CPU feature list + // + DEBUG_CODE ( + DEBUG ((DEBUG_INFO, "Last CPU features list...\n")); + Entry = GetFirstNode (&CpuFeaturesData->FeatureList); + while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) { + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) { + if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) { + DEBUG ((DEBUG_INFO, "[Enable ] ")); + } else { + DEBUG ((DEBUG_INFO, "[Disable ] ")); + } + } else { + DEBUG ((DEBUG_INFO, "[Unsupport] ")); + } + DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize); + Entry = Entry->ForwardLink; + } + DEBUG ((DEBUG_INFO, "PcdCpuFeaturesCapability:\n")); + DumpCpuFeatureMask (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize); + DEBUG ((DEBUG_INFO, "Origin PcdCpuFeaturesSetting:\n")); + DumpCpuFeatureMask (PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize); + DEBUG ((DEBUG_INFO, "Final PcdCpuFeaturesSetting:\n")); + DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize); + ); + + // + // Save PCDs and display CPU PCDs + // + SetCapabilityPcd (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize); + SetSettingPcd (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize); + + for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) { + CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber]; + Entry = GetFirstNode (&CpuFeaturesData->FeatureList); + while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) { + // + // Insert each feature into processor's order list + // + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) { + CpuFeatureInOrder = AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY), CpuFeature); + ASSERT (CpuFeatureInOrder != NULL); + InsertTailList (&CpuInitOrder->OrderList, &CpuFeatureInOrder->Link); + } + Entry = Entry->ForwardLink; + } + // + // Go through ordered feature list to initialize CPU features + // + CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo; + Entry = GetFirstNode (&CpuInitOrder->OrderList); + while (!IsNull (&CpuInitOrder->OrderList, Entry)) { + CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + + Success = FALSE; + if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) { + Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE); + if (EFI_ERROR (Status)) { + // + // Clean the CpuFeatureInOrder->FeatureMask in setting PCD. + // + SupportedMaskCleanBit (CpuFeaturesData->SettingPcd, CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize); + if (CpuFeatureInOrder->FeatureName != NULL) { + DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName)); + } else { + DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Mask = ")); + DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize); + } + } else { + Success = TRUE; + } + } else { + Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, FALSE); + if (EFI_ERROR (Status)) { + if (CpuFeatureInOrder->FeatureName != NULL) { + DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName)); + } else { + DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Mask = ")); + DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize); + } + } else { + Success = TRUE; + } + } + + if (Success) { + NextEntry = Entry->ForwardLink; + if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) { + NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry); + + // + // If feature has dependence with the next feature (ONLY care core/package dependency). + // and feature initialize succeed, add sync semaphere here. + // + BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NextCpuFeatureInOrder->FeatureMask); + AfterDep = DetectFeatureScope (NextCpuFeatureInOrder, FALSE, CpuFeatureInOrder->FeatureMask); + // + // Check whether next feature has After type dependence with not neighborhood CPU + // Features in former CPU features. + // + NoneNeibAfterDep = DetectNoneNeighborhoodFeatureScope(NextCpuFeatureInOrder, FALSE, &CpuInitOrder->OrderList); + } else { + BeforeDep = NoneDepType; + AfterDep = NoneDepType; + NoneNeibAfterDep = NoneDepType; + } + // + // Check whether current feature has Before type dependence with none neighborhood + // CPU features in after Cpu features. + // + NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope(CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList); + + // + // Get the biggest dependence and add semaphore for it. + // PackageDepType > CoreDepType > ThreadDepType > NoneDepType. + // + BeforeDep = BiggestDep(BeforeDep, AfterDep, NoneNeibBeforeDep, NoneNeibAfterDep); + if (BeforeDep > ThreadDepType) { + CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, BeforeDep); + } + } + + Entry = Entry->ForwardLink; + } + + // + // Dump PcdCpuFeaturesSetting again because this value maybe updated + // again during initialize the features. + // + DEBUG ((DEBUG_INFO, "Dump final value for PcdCpuFeaturesSetting:\n")); + DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize); + + // + // Dump the RegisterTable + // + DumpRegisterTableOnProcessor (ProcessorNumber); + } +} + +/** + Increment semaphore by 1. + + @param Sem IN: 32-bit unsigned integer + +**/ +VOID +LibReleaseSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + InterlockedIncrement (Sem); +} + +/** + Decrement the semaphore by 1 if it is not zero. + + Performs an atomic decrement operation for semaphore. + The compare exchange operation must be performed using + MP safe mechanisms. + + @param Sem IN: 32-bit unsigned integer + +**/ +VOID +LibWaitForSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + UINT32 Value; + + do { + Value = *Sem; + } while (Value == 0 || + InterlockedCompareExchange32 ( + Sem, + Value, + Value - 1 + ) != Value); +} + +/** + Read / write CR value. + + @param[in] CrIndex The CR index which need to read/write. + @param[in] Read Read or write. TRUE is read. + @param[in,out] CrValue CR value. + + @retval EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED. +**/ +UINTN +ReadWriteCr ( + IN UINT32 CrIndex, + IN BOOLEAN Read, + IN OUT UINTN *CrValue + ) +{ + switch (CrIndex) { + case 0: + if (Read) { + *CrValue = AsmReadCr0 (); + } else { + AsmWriteCr0 (*CrValue); + } + break; + case 2: + if (Read) { + *CrValue = AsmReadCr2 (); + } else { + AsmWriteCr2 (*CrValue); + } + break; + case 3: + if (Read) { + *CrValue = AsmReadCr3 (); + } else { + AsmWriteCr3 (*CrValue); + } + break; + case 4: + if (Read) { + *CrValue = AsmReadCr4 (); + } else { + AsmWriteCr4 (*CrValue); + } + break; + default: + return EFI_UNSUPPORTED;; + } + + return EFI_SUCCESS; +} + +/** + Initialize the CPU registers from a register table. + + @param[in] RegisterTable The register table for this AP. + @param[in] ApLocation AP location info for this ap. + @param[in] CpuStatus CPU status info for this CPU. + @param[in] CpuFlags Flags data structure used when program the register. + + @note This service could be called by BSP/APs. +**/ +VOID +ProgramProcessorRegister ( + IN CPU_REGISTER_TABLE *RegisterTable, + IN EFI_CPU_PHYSICAL_LOCATION *ApLocation, + IN CPU_STATUS_INFORMATION *CpuStatus, + IN PROGRAM_CPU_REGISTER_FLAGS *CpuFlags + ) +{ + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; + UINTN Index; + UINTN Value; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead; + volatile UINT32 *SemaphorePtr; + UINT32 FirstThread; + UINT32 PackageThreadsCount; + UINT32 CurrentThread; + UINTN ProcessorIndex; + UINTN ValidThreadCount; + UINT32 *ValidCoreCountPerPackage; + EFI_STATUS Status; + UINT64 CurrentValue; + + // + // Traverse Register Table of this logical processor + // + RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry; + + for (Index = 0; Index < RegisterTable->TableLength; Index++) { + + RegisterTableEntry = &RegisterTableEntryHead[Index]; + + // + // Check the type of specified register + // + switch (RegisterTableEntry->RegisterType) { + // + // The specified register is Control Register + // + case ControlRegister: + Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value); + if (EFI_ERROR (Status)) { + break; + } + if (RegisterTableEntry->TestThenWrite) { + CurrentValue = BitFieldRead64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + break; + } + } + Value = (UINTN) BitFieldWrite64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + RegisterTableEntry->Value + ); + ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value); + break; + + // + // The specified register is Model Specific Register + // + case Msr: + if (RegisterTableEntry->TestThenWrite) { + Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index); + if (RegisterTableEntry->ValidBitLength >= 64) { + if (Value == RegisterTableEntry->Value) { + break; + } + } else { + CurrentValue = BitFieldRead64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + break; + } + } + } + + if (RegisterTableEntry->ValidBitLength >= 64) { + // + // If length is not less than 64 bits, then directly write without reading + // + AsmWriteMsr64 ( + RegisterTableEntry->Index, + RegisterTableEntry->Value + ); + } else { + // + // Set the bit section according to bit start and length + // + AsmMsrBitFieldWrite64 ( + RegisterTableEntry->Index, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + RegisterTableEntry->Value + ); + } + break; + // + // MemoryMapped operations + // + case MemoryMapped: + AcquireSpinLock (&CpuFlags->MemoryMappedLock); + MmioBitFieldWrite32 ( + (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)), + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + (UINT32)RegisterTableEntry->Value + ); + ReleaseSpinLock (&CpuFlags->MemoryMappedLock); + break; + // + // Enable or disable cache + // + case CacheControl: + // + // If value of the entry is 0, then disable cache. Otherwise, enable cache. + // + if (RegisterTableEntry->Value == 0) { + AsmDisableCache (); + } else { + AsmEnableCache (); + } + break; + + case Semaphore: + // Semaphore works logic like below: + // + // V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]); + // P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]); + // + // All threads (T0...Tn) waits in P() line and continues running + // together. + // + // + // T0 T1 ... Tn + // + // V(0...n) V(0...n) ... V(0...n) + // n * P(0) n * P(1) ... n * P(n) + // + switch (RegisterTableEntry->Value) { + case CoreDepType: + SemaphorePtr = CpuFlags->CoreSemaphoreCount; + // + // Get Offset info for the first thread in the core which current thread belongs to. + // + FirstThread = (ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core) * CpuStatus->MaxThreadCount; + CurrentThread = FirstThread + ApLocation->Thread; + // + // First Notify all threads in current Core that this thread has ready. + // + for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) { + LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]); + } + // + // Second, check whether all valid threads in current core have ready. + // + for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) { + LibWaitForSemaphore (&SemaphorePtr[CurrentThread]); + } + break; + + case PackageDepType: + SemaphorePtr = CpuFlags->PackageSemaphoreCount; + ValidCoreCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ValidCoreCountPerPackage; + // + // Get Offset info for the first thread in the package which current thread belongs to. + // + FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount; + // + // Get the possible threads count for current package. + // + PackageThreadsCount = CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; + CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread; + // + // Get the valid thread count for current package. + // + ValidThreadCount = CpuStatus->MaxThreadCount * ValidCoreCountPerPackage[ApLocation->Package]; + + // + // Different packages may have different valid cores in them. If driver maintail clearly + // cores number in different packages, the logic will be much complicated. + // Here driver just simply records the max core number in all packages and use it as expect + // core number for all packages. + // In below two steps logic, first current thread will Release semaphore for each thread + // in current package. Maybe some threads are not valid in this package, but driver don't + // care. Second, driver will let current thread wait semaphore for all valid threads in + // current package. Because only the valid threads will do release semaphore for this + // thread, driver here only need to wait the valid thread count. + // + + // + // First Notify ALL THREADS in current package that this thread has ready. + // + for (ProcessorIndex = 0; ProcessorIndex < PackageThreadsCount ; ProcessorIndex ++) { + LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]); + } + // + // Second, check whether VALID THREADS (not all threads) in current package have ready. + // + for (ProcessorIndex = 0; ProcessorIndex < ValidThreadCount; ProcessorIndex ++) { + LibWaitForSemaphore (&SemaphorePtr[CurrentThread]); + } + break; + + default: + break; + } + break; + + default: + break; + } + } +} + +/** + Programs registers for the calling processor. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +SetProcessorRegister ( + IN OUT VOID *Buffer + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + CPU_REGISTER_TABLE *RegisterTable; + CPU_REGISTER_TABLE *RegisterTables; + UINT32 InitApicId; + UINTN ProcIndex; + UINTN Index; + ACPI_CPU_DATA *AcpiCpuData; + + CpuFeaturesData = (CPU_FEATURES_DATA *) Buffer; + AcpiCpuData = CpuFeaturesData->AcpiCpuData; + + RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable; + + InitApicId = GetInitialApicId (); + RegisterTable = NULL; + ProcIndex = (UINTN)-1; + for (Index = 0; Index < AcpiCpuData->NumberOfCpus; Index++) { + if (RegisterTables[Index].InitialApicId == InitApicId) { + RegisterTable = &RegisterTables[Index]; + ProcIndex = Index; + break; + } + } + ASSERT (RegisterTable != NULL); + + ProgramProcessorRegister ( + RegisterTable, + (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->ApLocation + ProcIndex, + &AcpiCpuData->CpuStatus, + &CpuFeaturesData->CpuFlags + ); +} + +/** + Performs CPU features detection. + + This service will invoke MP service to check CPU features' + capabilities on BSP/APs. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesDetect ( + VOID + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData(); + + CpuInitDataInitialize (); + + if (CpuFeaturesData->NumberOfCpus > 1) { + // + // Wakeup all APs for data collection. + // + StartupAllAPsWorker (CollectProcessorData, NULL); + } + + // + // Collect data on BSP + // + CollectProcessorData (CpuFeaturesData); + + AnalysisProcessorFeatures (CpuFeaturesData->NumberOfCpus); +} + diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c new file mode 100644 index 000000000..e2e06e88e --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c @@ -0,0 +1,276 @@ +/** @file + CPU Register Table Library functions. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +#include "RegisterCpuFeatures.h" + +CPU_FEATURES_DATA mCpuFeaturesData = {0}; + +/** + Worker function to get CPU_FEATURES_DATA pointer. + + @return Pointer to CPU_FEATURES_DATA. +**/ +CPU_FEATURES_DATA * +GetCpuFeaturesData ( + VOID + ) +{ + return &mCpuFeaturesData; +} + +/** + Worker function to get EFI_MP_SERVICES_PROTOCOL pointer. + + @return MP_SERVICES variable. +**/ +MP_SERVICES +GetMpService ( + VOID + ) +{ + EFI_STATUS Status; + MP_SERVICES MpService; + + // + // Get MP Services Protocol + // + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **)&MpService.Protocol + ); + ASSERT_EFI_ERROR (Status); + + return MpService; +} + +/** + Worker function to return processor index. + + @param CpuFeaturesData Cpu Feature Data structure. + + @return The processor index. +**/ +UINTN +GetProcessorIndex ( + IN CPU_FEATURES_DATA *CpuFeaturesData + ) +{ + EFI_STATUS Status; + UINTN ProcessorIndex; + EFI_MP_SERVICES_PROTOCOL *MpServices; + + MpServices = CpuFeaturesData->MpService.Protocol; + Status = MpServices->WhoAmI(MpServices, &ProcessorIndex); + ASSERT_EFI_ERROR (Status); + return ProcessorIndex; +} + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @return Status of MpServices->GetProcessorInfo(). +**/ +EFI_STATUS +GetProcessorInformation ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + MpServices = CpuFeaturesData->MpService.Protocol; + + Status = MpServices->GetProcessorInfo ( + MpServices, + ProcessorNumber, + ProcessorInfoBuffer + ); + return Status; +} + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] MpEvent A pointer to the event to be used later + to check whether procedure has done. +**/ +VOID +StartupAllAPsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN EFI_EVENT MpEvent + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + MpServices = CpuFeaturesData->MpService.Protocol; + + // + // Wakeup all APs + // + Status = MpServices->StartupAllAPs ( + MpServices, + Procedure, + FALSE, + MpEvent, + 0, + CpuFeaturesData, + NULL + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. +**/ +VOID +SwitchNewBsp ( + IN UINTN ProcessorNumber + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + MpServices = CpuFeaturesData->MpService.Protocol; + + // + // Wakeup all APs + // + Status = MpServices->SwitchBSP ( + MpServices, + ProcessorNumber, + TRUE + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to retrieve the number of logical processor in the platform. + + @param[out] NumberOfCpus Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. +**/ +VOID +GetNumberOfProcessor ( + OUT UINTN *NumberOfCpus, + OUT UINTN *NumberOfEnabledProcessors + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + MpServices = CpuFeaturesData->MpService.Protocol; + + // + // Get the number of CPUs + // + Status = MpServices->GetNumberOfProcessors ( + MpServices, + NumberOfCpus, + NumberOfEnabledProcessors + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Performs CPU features Initialization. + + This service will invoke MP service to perform CPU features + initialization on BSP/APs per user configuration. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesInitialize ( + VOID + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + UINTN OldBspNumber; + EFI_EVENT MpEvent; + EFI_STATUS Status; + + CpuFeaturesData = GetCpuFeaturesData (); + + OldBspNumber = GetProcessorIndex (CpuFeaturesData); + CpuFeaturesData->BspNumber = OldBspNumber; + + // + // + // Initialize MpEvent to suppress incorrect compiler/analyzer warnings. + // + MpEvent = NULL; + + if (CpuFeaturesData->NumberOfCpus > 1) { + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_CALLBACK, + EfiEventEmptyFunction, + NULL, + &MpEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Wakeup all APs for programming. + // + StartupAllAPsWorker (SetProcessorRegister, MpEvent); + } + + // + // Programming BSP + // + SetProcessorRegister (CpuFeaturesData); + + if (CpuFeaturesData->NumberOfCpus > 1) { + // + // Wait all processors to finish the task. + // + do { + Status = gBS->CheckEvent (MpEvent); + } while (Status == EFI_NOT_READY); + ASSERT_EFI_ERROR (Status); + } + + // + // Switch to new BSP if required + // + if (CpuFeaturesData->BspNumber != OldBspNumber) { + SwitchNewBsp (CpuFeaturesData->BspNumber); + } +} + diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf new file mode 100644 index 000000000..aba87842c --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf @@ -0,0 +1,57 @@ +## @file +# Register CPU Features Library DXE instance. +# +# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeRegisterCpuFeaturesLib + MODULE_UNI_FILE = RegisterCpuFeaturesLib.uni + FILE_GUID = ADE8F745-AA2E-49f6-8ED4-746B34867E52 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RegisterCpuFeaturesLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + DxeRegisterCpuFeaturesLib.c + RegisterCpuFeaturesLib.c + RegisterCpuFeatures.h + CpuFeaturesInitialize.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + LocalApicLib + BaseMemoryLib + MemoryAllocationLib + SynchronizationLib + UefiBootServicesTableLib + IoLib + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiMpServiceProtocolGuid ## CONSUMES + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSupport ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesCapability ## PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSetting ## PRODUCES ## CONSUMES + +[Depex] + gEfiMpServiceProtocolGuid AND gEdkiiCpuFeaturesSetDoneGuid diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c new file mode 100644 index 000000000..64768f7a7 --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c @@ -0,0 +1,324 @@ +/** @file + CPU Register Table Library functions. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include "RegisterCpuFeatures.h" + +#define REGISTER_CPU_FEATURES_GUID \ + { \ + 0xa694c467, 0x697a, 0x446b, { 0xb9, 0x29, 0x5b, 0x14, 0xa0, 0xcf, 0x39, 0xf } \ + } + +EFI_GUID mRegisterCpuFeaturesHobGuid = REGISTER_CPU_FEATURES_GUID; + +/** + Worker function to get CPU_FEATURES_DATA pointer. + + @return Pointer to CPU_FEATURES_DATA. +**/ +CPU_FEATURES_DATA * +GetCpuFeaturesData ( + VOID + ) +{ + CPU_FEATURES_DATA *CpuInitData; + EFI_HOB_GUID_TYPE *GuidHob; + VOID *DataInHob; + UINT64 Data64; + + CpuInitData = NULL; + GuidHob = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid); + if (GuidHob != NULL) { + DataInHob = GET_GUID_HOB_DATA (GuidHob); + CpuInitData = (CPU_FEATURES_DATA *) (*(UINTN *) DataInHob); + ASSERT (CpuInitData != NULL); + } else { + CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA)); + ASSERT (CpuInitData != NULL); + // + // Build location of CPU MP DATA buffer in HOB + // + Data64 = (UINT64) (UINTN) CpuInitData; + BuildGuidDataHob ( + &mRegisterCpuFeaturesHobGuid, + (VOID *) &Data64, + sizeof (UINT64) + ); + } + + return CpuInitData; +} + +/** + Worker function to get MP PPI service pointer. + + @return MP_SERVICES variable. +**/ +MP_SERVICES +GetMpService ( + VOID + ) +{ + EFI_STATUS Status; + MP_SERVICES MpService; + + // + // Get MP Services Protocol + // + Status = PeiServicesLocatePpi ( + &gEfiPeiMpServicesPpiGuid, + 0, + NULL, + (VOID **)&MpService.Ppi + ); + ASSERT_EFI_ERROR (Status); + return MpService; +} + +/** + Worker function to return processor index. + + @param CpuFeaturesData Cpu Feature Data structure. + + @return The processor index. +**/ +UINTN +GetProcessorIndex ( + IN CPU_FEATURES_DATA *CpuFeaturesData + ) +{ + EFI_STATUS Status; + EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; + UINTN ProcessorIndex; + + CpuMpPpi = CpuFeaturesData->MpService.Ppi; + + // + // For two reasons which use NULL for WhoAmI: + // 1. This function will be called by APs and AP should not use PeiServices Table + // 2. Check WhoAmI implementation, this parameter will not be used. + // + Status = CpuMpPpi->WhoAmI(NULL, CpuMpPpi, &ProcessorIndex); + ASSERT_EFI_ERROR (Status); + return ProcessorIndex; +} + +/** + Worker function to MP-related information on the requested processor at the + instant this call is made. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @return Status of MpServices->GetProcessorInfo(). +**/ +EFI_STATUS +GetProcessorInformation ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; + EFI_STATUS Status; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuMpPpi = CpuFeaturesData->MpService.Ppi; + + Status = CpuMpPpi->GetProcessorInfo ( + GetPeiServicesTablePointer(), + CpuMpPpi, + ProcessorNumber, + ProcessorInfoBuffer + ); + return Status; +} + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] MpEvent The Event used to sync the result. + +**/ +VOID +StartupAllAPsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN EFI_EVENT MpEvent + ) +{ + EFI_STATUS Status; + EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuMpPpi = CpuFeaturesData->MpService.Ppi; + + // + // Wakeup all APs for data collection. + // + Status = CpuMpPpi->StartupAllAPs ( + GetPeiServicesTablePointer (), + CpuMpPpi, + Procedure, + FALSE, + 0, + CpuFeaturesData + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to execute a caller provided function on all enabled CPUs. + + @param[in] Procedure A pointer to the function to be run on + enabled CPUs of the system. + +**/ +VOID +StartupAllCPUsWorker ( + IN EFI_AP_PROCEDURE Procedure + ) +{ + EFI_STATUS Status; + EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + + // + // Get MP Services2 Ppi + // + Status = PeiServicesLocatePpi ( + &gEdkiiPeiMpServices2PpiGuid, + 0, + NULL, + (VOID **)&CpuMp2Ppi + ); + ASSERT_EFI_ERROR (Status); + + // + // Wakeup all APs for data collection. + // + Status = CpuMp2Ppi->StartupAllCPUs ( + CpuMp2Ppi, + Procedure, + 0, + CpuFeaturesData + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. +**/ +VOID +SwitchNewBsp ( + IN UINTN ProcessorNumber + ) +{ + EFI_STATUS Status; + EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuMpPpi = CpuFeaturesData->MpService.Ppi; + + // + // Wakeup all APs for data collection. + // + Status = CpuMpPpi->SwitchBSP ( + GetPeiServicesTablePointer (), + CpuMpPpi, + ProcessorNumber, + TRUE + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Worker function to retrieve the number of logical processor in the platform. + + @param[out] NumberOfCpus Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. +**/ +VOID +GetNumberOfProcessor ( + OUT UINTN *NumberOfCpus, + OUT UINTN *NumberOfEnabledProcessors + ) +{ + EFI_STATUS Status; + EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuMpPpi = CpuFeaturesData->MpService.Ppi; + + // + // Get the number of CPUs + // + Status = CpuMpPpi->GetNumberOfProcessors ( + GetPeiServicesTablePointer (), + CpuMpPpi, + NumberOfCpus, + NumberOfEnabledProcessors + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Performs CPU features Initialization. + + This service will invoke MP service to perform CPU features + initialization on BSP/APs per user configuration. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesInitialize ( + VOID + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + UINTN OldBspNumber; + + CpuFeaturesData = GetCpuFeaturesData (); + + OldBspNumber = GetProcessorIndex (CpuFeaturesData); + CpuFeaturesData->BspNumber = OldBspNumber; + + // + // Start to program register for all CPUs. + // + StartupAllCPUsWorker (SetProcessorRegister); + + // + // Switch to new BSP if required + // + if (CpuFeaturesData->BspNumber != OldBspNumber) { + SwitchNewBsp (CpuFeaturesData->BspNumber); + } +} + diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf new file mode 100644 index 000000000..61f922bf6 --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf @@ -0,0 +1,58 @@ +## @file +# Register CPU Features Library PEI instance. +# +# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiRegisterCpuFeaturesLib + MODULE_UNI_FILE = RegisterCpuFeaturesLib.uni + FILE_GUID = D8855DB3-8348-41B5-BDA4-385351767D41 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = RegisterCpuFeaturesLib|PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + PeiRegisterCpuFeaturesLib.c + RegisterCpuFeaturesLib.c + RegisterCpuFeatures.h + CpuFeaturesInitialize.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + LocalApicLib + BaseMemoryLib + MemoryAllocationLib + SynchronizationLib + HobLib + PeiServicesLib + PeiServicesTablePointerLib + IoLib + +[Ppis] + gEfiPeiMpServicesPpiGuid ## CONSUMES + gEdkiiPeiMpServices2PpiGuid ## CONSUMES + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSupport ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesCapability ## PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSetting ## CONSUMES ## PRODUCES + +[Depex] + gEfiPeiMpServicesPpiGuid AND gEdkiiCpuFeaturesSetDoneGuid diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h new file mode 100644 index 000000000..53cb340b4 --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h @@ -0,0 +1,268 @@ +/** @file + CPU Register Table Library definitions. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _REGISTER_CPU_FEATURES_H_ +#define _REGISTER_CPU_FEATURES_H_ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CPU_FEATURE_ENTRY_SIGNATURE SIGNATURE_32 ('C', 'F', 'E', 'S') + +#define CPU_FEATURE_NAME_SIZE 128 + +typedef struct { + REGISTER_CPU_FEATURE_INFORMATION CpuInfo; + UINT8 *FeaturesSupportedMask; + LIST_ENTRY OrderList; +} CPU_FEATURES_INIT_ORDER; + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + UINT8 *FeatureMask; + CHAR8 *FeatureName; + CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc; + CPU_FEATURE_SUPPORT SupportFunc; + CPU_FEATURE_INITIALIZE InitializeFunc; + UINT8 *ThreadBeforeFeatureBitMask; + UINT8 *ThreadAfterFeatureBitMask; + UINT8 *CoreBeforeFeatureBitMask; + UINT8 *CoreAfterFeatureBitMask; + UINT8 *PackageBeforeFeatureBitMask; + UINT8 *PackageAfterFeatureBitMask; + VOID *ConfigData; + BOOLEAN BeforeAll; + BOOLEAN AfterAll; +} CPU_FEATURES_ENTRY; + +// +// Flags used when program the register. +// +typedef struct { + volatile UINTN MemoryMappedLock; // Spinlock used to program mmio + volatile UINT32 *CoreSemaphoreCount; // Semaphore containers used to program Core semaphore. + volatile UINT32 *PackageSemaphoreCount; // Semaphore containers used to program Package semaphore. +} PROGRAM_CPU_REGISTER_FLAGS; + +typedef union { + EFI_MP_SERVICES_PROTOCOL *Protocol; + EFI_PEI_MP_SERVICES_PPI *Ppi; +} MP_SERVICES; + +typedef struct { + UINTN FeaturesCount; + UINT32 BitMaskSize; + LIST_ENTRY FeatureList; + + CPU_FEATURES_INIT_ORDER *InitOrder; + UINT8 *CapabilityPcd; + UINT8 *SettingPcd; + + UINT32 NumberOfCpus; + ACPI_CPU_DATA *AcpiCpuData; + + CPU_REGISTER_TABLE *RegisterTable; + CPU_REGISTER_TABLE *PreSmmRegisterTable; + UINTN BspNumber; + + PROGRAM_CPU_REGISTER_FLAGS CpuFlags; + + MP_SERVICES MpService; +} CPU_FEATURES_DATA; + +#define CPU_FEATURE_ENTRY_FROM_LINK(a) \ + CR ( \ + (a), \ + CPU_FEATURES_ENTRY, \ + Link, \ + CPU_FEATURE_ENTRY_SIGNATURE \ + ) + +/** + Worker function to get CPU_FEATURES_DATA pointer. + + @return Pointer to CPU_FEATURES_DATA. +**/ +CPU_FEATURES_DATA * +GetCpuFeaturesData ( + VOID + ); + +/** + Worker function to return processor index. + + @param CpuFeaturesData Cpu Feature Data structure. + + @return The processor index. +**/ +UINTN +GetProcessorIndex ( + IN CPU_FEATURES_DATA *CpuFeaturesData + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @return Status of MpServices->GetProcessorInfo(). +**/ +EFI_STATUS +GetProcessorInformation ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] MpEvent A pointer to the event to be used later + to check whether procedure has done. +**/ +VOID +StartupAllAPsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN EFI_EVENT MpEvent + ); + +/** + Worker function to retrieve the number of logical processor in the platform. + + @param[out] NumberOfCpus Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. +**/ +VOID +GetNumberOfProcessor ( + OUT UINTN *NumberOfCpus, + OUT UINTN *NumberOfEnabledProcessors + ); + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. +**/ +VOID +SwitchNewBsp ( + IN UINTN ProcessorNumber + ); + +/** + Function that uses DEBUG() macros to display the contents of a a CPU feature bit mask. + + @param[in] FeatureMask A pointer to the CPU feature bit mask. + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +DumpCpuFeatureMask ( + IN UINT8 *FeatureMask, + IN UINT32 BitMaskSize + ); + +/** + Dump CPU feature name or CPU feature bit mask. + + @param[in] CpuFeature Pointer to CPU_FEATURES_ENTRY + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +DumpCpuFeature ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN UINT32 BitMaskSize + ); + +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] NextCpuFeatureMask Pointer to next CPU feature Mask. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN UINT8 *NextCpuFeatureMask + ); + +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] FeatureList Pointer to CPU feature list. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectNoneNeighborhoodFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN LIST_ENTRY *FeatureList + ); + +/** + Programs registers for the calling processor. + + @param[in,out] Buffer The pointer to private data buffer. + +**/ +VOID +EFIAPI +SetProcessorRegister ( + IN OUT VOID *Buffer + ); + +/** + Return ACPI_CPU_DATA data. + + @return Pointer to ACPI_CPU_DATA data. +**/ +ACPI_CPU_DATA * +GetAcpiCpuData ( + VOID + ); + +/** + Worker function to get MP service pointer. + + @return MP_SERVICES variable. +**/ +MP_SERVICES +GetMpService ( + VOID + ); + +#endif diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c new file mode 100644 index 000000000..4063d4576 --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c @@ -0,0 +1,1284 @@ +/** @file + CPU Register Table Library functions. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RegisterCpuFeatures.h" + +/** + Function that uses DEBUG() macros to display the contents of a a CPU feature bit mask. + + @param[in] FeatureMask A pointer to the CPU feature bit mask. + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +DumpCpuFeatureMask ( + IN UINT8 *FeatureMask, + IN UINT32 BitMaskSize + ) +{ + UINTN Index; + UINT8 *Data8; + + Data8 = (UINT8 *) FeatureMask; + for (Index = 0; Index < BitMaskSize; Index++) { + DEBUG ((DEBUG_INFO, " %02x ", *Data8++)); + } + DEBUG ((DEBUG_INFO, "\n")); +} + +/** + Dump CPU feature name or CPU feature bit mask. + + @param[in] CpuFeature Pointer to CPU_FEATURES_ENTRY + @param[in] BitMaskSize CPU feature bits mask buffer size. + +**/ +VOID +DumpCpuFeature ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN UINT32 BitMaskSize + ) +{ + + if (CpuFeature->FeatureName != NULL) { + DEBUG ((DEBUG_INFO, "FeatureName: %a\n", CpuFeature->FeatureName)); + } else { + DEBUG ((DEBUG_INFO, "FeatureMask = ")); + DumpCpuFeatureMask (CpuFeature->FeatureMask, BitMaskSize); + } +} + +/** + Determines if the feature bit mask is in dependent CPU feature bit mask buffer. + + @param[in] FeatureMask Pointer to CPU feature bit mask + @param[in] DependentBitMask Pointer to dependent CPU feature bit mask buffer + + @retval TRUE The feature bit mask is in dependent CPU feature bit mask buffer. + @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer. +**/ +BOOLEAN +IsBitMaskMatchCheck ( + IN UINT8 *FeatureMask, + IN UINT8 *DependentBitMask + ) +{ + UINTN Index; + UINT8 *Data1; + UINT8 *Data2; + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + + Data1 = FeatureMask; + Data2 = DependentBitMask; + for (Index = 0; Index < CpuFeaturesData->BitMaskSize; Index++) { + if (((*(Data1++)) & (*(Data2++))) != 0) { + return TRUE; + } + } + return FALSE; +} + +/** + Try to find the specify cpu featuren in former/after feature list. + + @param[in] FeatureList Pointer to dependent CPU feature list + @param[in] CurrentEntry Pointer to current CPU feature entry. + @param[in] SearchFormer Find in former feature or after features. + @param[in] FeatureMask Pointer to CPU feature bit mask + + @retval TRUE The feature bit mask is in dependent CPU feature bit mask buffer. + @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer. +**/ +BOOLEAN +FindSpecifyFeature ( + IN LIST_ENTRY *FeatureList, + IN LIST_ENTRY *CurrentEntry, + IN BOOLEAN SearchFormer, + IN UINT8 *FeatureMask + ) +{ + CPU_FEATURES_ENTRY *CpuFeature; + LIST_ENTRY *NextEntry; + + // + // Check whether exist the not neighborhood entry first. + // If not exist, return FALSE means not found status. + // + if (SearchFormer) { + NextEntry = CurrentEntry->BackLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = NextEntry->BackLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = CurrentEntry->BackLink->BackLink; + } else { + NextEntry = CurrentEntry->ForwardLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = NextEntry->ForwardLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = CurrentEntry->ForwardLink->ForwardLink; + } + + while (!IsNull (FeatureList, NextEntry)) { + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry); + + if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) { + return TRUE; + } + + if (SearchFormer) { + NextEntry = NextEntry->BackLink; + } else { + NextEntry = NextEntry->ForwardLink; + } + } + + return FALSE; +} + +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] NextCpuFeatureMask Pointer to next CPU feature Mask. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN UINT8 *NextCpuFeatureMask + ) +{ + // + // if need to check before type dependence but the feature after current feature is not + // exist, means this before type dependence not valid, just return NoneDepType. + // Just like Feature A has a dependence of feature B, but Feature B not installed, so + // Feature A maybe insert to the last entry of the list. In this case, for below code, + // Featrure A has depend of feature B, but it is the last entry of the list, so the + // NextCpuFeatureMask is NULL, so the dependence for feature A here is useless and code + // just return NoneDepType. + // + if (NextCpuFeatureMask == NULL) { + return NoneDepType; + } + + if (Before) { + if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; + } + + if ((CpuFeature->PackageAfterFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreAfterFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) && + IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; +} + +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] FeatureList Pointer to CPU feature list. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectNoneNeighborhoodFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN LIST_ENTRY *FeatureList + ) +{ + if (Before) { + if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; + } + + if ((CpuFeature->PackageAfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreAfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; +} + +/** + Base on dependence relationship to asjust feature dependence. + + ONLY when the feature before(or after) the find feature also has + dependence with the find feature. In this case, driver need to base + on dependce relationship to decide how to insert current feature and + adjust the feature dependence. + + @param[in, out] PreviousFeature CPU feature current before the find one. + @param[in, out] CurrentFeature Cpu feature need to adjust. + @param[in] FindFeature Cpu feature which current feature depends. + @param[in] Before Before or after dependence relationship. + + @retval TRUE means the current feature dependence has been adjusted. + + @retval FALSE means the previous feature dependence has been adjusted. + or previous feature has no dependence with the find one. + +**/ +BOOLEAN +AdjustFeaturesDependence ( + IN OUT CPU_FEATURES_ENTRY *PreviousFeature, + IN OUT CPU_FEATURES_ENTRY *CurrentFeature, + IN CPU_FEATURES_ENTRY *FindFeature, + IN BOOLEAN Before + ) +{ + CPU_FEATURE_DEPENDENCE_TYPE PreDependType; + CPU_FEATURE_DEPENDENCE_TYPE CurrentDependType; + + PreDependType = DetectFeatureScope(PreviousFeature, Before, FindFeature->FeatureMask); + CurrentDependType = DetectFeatureScope(CurrentFeature, Before, FindFeature->FeatureMask); + + // + // If previous feature has no dependence with the find featue. + // return FALSE. + // + if (PreDependType == NoneDepType) { + return FALSE; + } + + // + // If both feature have dependence, keep the one which needs use more + // processors and clear the dependence for the other one. + // + if (PreDependType >= CurrentDependType) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Base on dependence relationship to asjust feature order. + + @param[in] FeatureList Pointer to CPU feature list + @param[in, out] FindEntry The entry this feature depend on. + @param[in, out] CurrentEntry The entry for this feature. + @param[in] Before Before or after dependence relationship. + +**/ +VOID +AdjustEntry ( + IN LIST_ENTRY *FeatureList, + IN OUT LIST_ENTRY *FindEntry, + IN OUT LIST_ENTRY *CurrentEntry, + IN BOOLEAN Before + ) +{ + LIST_ENTRY *PreviousEntry; + CPU_FEATURES_ENTRY *PreviousFeature; + CPU_FEATURES_ENTRY *CurrentFeature; + CPU_FEATURES_ENTRY *FindFeature; + + // + // For CPU feature which has core or package type dependence, later code need to insert + // AcquireSpinLock/ReleaseSpinLock logic to sequency the execute order. + // So if driver finds both feature A and B need to execute before feature C, driver will + // base on dependence type of feature A and B to update the logic here. + // For example, feature A has package type dependence and feature B has core type dependence, + // because package type dependence need to wait for more processors which has strong dependence + // than core type dependence. So driver will adjust the feature order to B -> A -> C. and driver + // will remove the feature dependence in feature B. + // Driver just needs to make sure before feature C been executed, feature A has finished its task + // in all all thread. Feature A finished in all threads also means feature B have finshed in all + // threads. + // + if (Before) { + PreviousEntry = GetPreviousNode (FeatureList, FindEntry); + } else { + + PreviousEntry = GetNextNode (FeatureList, FindEntry); + } + + CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry); + RemoveEntryList (CurrentEntry); + + if (IsNull (FeatureList, PreviousEntry)) { + // + // If not exist the previous or next entry, just insert the current entry. + // + if (Before) { + InsertTailList (FindEntry, CurrentEntry); + } else { + InsertHeadList (FindEntry, CurrentEntry); + } + } else { + // + // If exist the previous or next entry, need to check it before insert curent entry. + // + PreviousFeature = CPU_FEATURE_ENTRY_FROM_LINK (PreviousEntry); + FindFeature = CPU_FEATURE_ENTRY_FROM_LINK (FindEntry); + + if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, FindFeature, Before)) { + // + // Return TRUE means current feature dependence has been cleared and the previous + // feature dependence has been kept and used. So insert current feature before (or after) + // the previous feature. + // + if (Before) { + InsertTailList (PreviousEntry, CurrentEntry); + } else { + InsertHeadList (PreviousEntry, CurrentEntry); + } + } else { + if (Before) { + InsertTailList (FindEntry, CurrentEntry); + } else { + InsertHeadList (FindEntry, CurrentEntry); + } + } + } +} + + +/** + Checks and adjusts current CPU features per dependency relationship. + + @param[in] FeatureList Pointer to CPU feature list + @param[in] CurrentEntry Pointer to current checked CPU feature + @param[in] FeatureMask The feature bit mask. + + @retval return Swapped info. +**/ +BOOLEAN +InsertToBeforeEntry ( + IN LIST_ENTRY *FeatureList, + IN LIST_ENTRY *CurrentEntry, + IN UINT8 *FeatureMask + ) +{ + LIST_ENTRY *CheckEntry; + CPU_FEATURES_ENTRY *CheckFeature; + BOOLEAN Swapped; + + Swapped = FALSE; + + // + // Check all features dispatched before this entry + // + CheckEntry = GetFirstNode (FeatureList); + while (CheckEntry != CurrentEntry) { + CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry); + if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) { + AdjustEntry (FeatureList, CheckEntry, CurrentEntry, TRUE); + Swapped = TRUE; + break; + } + CheckEntry = CheckEntry->ForwardLink; + } + + return Swapped; +} + +/** + Checks and adjusts current CPU features per dependency relationship. + + @param[in] FeatureList Pointer to CPU feature list + @param[in] CurrentEntry Pointer to current checked CPU feature + @param[in] FeatureMask The feature bit mask. + + @retval return Swapped info. +**/ +BOOLEAN +InsertToAfterEntry ( + IN LIST_ENTRY *FeatureList, + IN LIST_ENTRY *CurrentEntry, + IN UINT8 *FeatureMask + ) +{ + LIST_ENTRY *CheckEntry; + CPU_FEATURES_ENTRY *CheckFeature; + BOOLEAN Swapped; + + Swapped = FALSE; + + // + // Check all features dispatched after this entry + // + CheckEntry = GetNextNode (FeatureList, CurrentEntry); + while (!IsNull (FeatureList, CheckEntry)) { + CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry); + if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) { + AdjustEntry (FeatureList, CheckEntry, CurrentEntry, FALSE); + Swapped = TRUE; + break; + } + CheckEntry = CheckEntry->ForwardLink; + } + + return Swapped; +} + +/** + Checks and adjusts CPU features order per dependency relationship. + + @param[in] FeatureList Pointer to CPU feature list +**/ +VOID +CheckCpuFeaturesDependency ( + IN LIST_ENTRY *FeatureList + ) +{ + LIST_ENTRY *CurrentEntry; + CPU_FEATURES_ENTRY *CpuFeature; + LIST_ENTRY *CheckEntry; + CPU_FEATURES_ENTRY *CheckFeature; + BOOLEAN Swapped; + LIST_ENTRY *TempEntry; + LIST_ENTRY *NextEntry; + + CurrentEntry = GetFirstNode (FeatureList); + while (!IsNull (FeatureList, CurrentEntry)) { + Swapped = FALSE; + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry); + NextEntry = CurrentEntry->ForwardLink; + if (CpuFeature->BeforeAll) { + // + // Check all features dispatched before this entry + // + CheckEntry = GetFirstNode (FeatureList); + while (CheckEntry != CurrentEntry) { + CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry); + if (!CheckFeature->BeforeAll) { + // + // If this feature has no BeforeAll flag and is dispatched before CpuFeature, + // insert currentEntry before Checked feature + // + RemoveEntryList (CurrentEntry); + InsertTailList (CheckEntry, CurrentEntry); + Swapped = TRUE; + break; + } + CheckEntry = CheckEntry->ForwardLink; + } + if (Swapped) { + CurrentEntry = NextEntry; + continue; + } + } + + if (CpuFeature->AfterAll) { + // + // Check all features dispatched after this entry + // + CheckEntry = GetNextNode (FeatureList, CurrentEntry); + while (!IsNull (FeatureList, CheckEntry)) { + CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry); + if (!CheckFeature->AfterAll) { + // + // If this feature has no AfterAll flag and is dispatched after CpuFeature, + // insert currentEntry after Checked feature + // + TempEntry = GetNextNode (FeatureList, CurrentEntry); + RemoveEntryList (CurrentEntry); + InsertHeadList (CheckEntry, CurrentEntry); + CurrentEntry = TempEntry; + Swapped = TRUE; + break; + } + CheckEntry = CheckEntry->ForwardLink; + } + if (Swapped) { + CurrentEntry = NextEntry; + continue; + } + } + + if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) { + Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->ThreadBeforeFeatureBitMask); + if (Swapped) { + continue; + } + } + + if (CpuFeature->ThreadAfterFeatureBitMask != NULL) { + Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->ThreadAfterFeatureBitMask); + if (Swapped) { + continue; + } + } + + if (CpuFeature->CoreBeforeFeatureBitMask != NULL) { + Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask); + if (Swapped) { + continue; + } + } + + if (CpuFeature->CoreAfterFeatureBitMask != NULL) { + Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask); + if (Swapped) { + continue; + } + } + + if (CpuFeature->PackageBeforeFeatureBitMask != NULL) { + Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask); + if (Swapped) { + continue; + } + } + + if (CpuFeature->PackageAfterFeatureBitMask != NULL) { + Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask); + if (Swapped) { + continue; + } + } + + CurrentEntry = CurrentEntry->ForwardLink; + } +} + +/** + Worker function to register CPU Feature. + + @param[in] CpuFeaturesData Pointer to CPU feature data structure. + @param[in] CpuFeature Pointer to CPU feature entry + + @retval RETURN_SUCCESS The CPU feature was successfully registered. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to register + the CPU feature. + @retval RETURN_UNSUPPORTED Registration of the CPU feature is not + supported due to a circular dependency between + BEFORE and AFTER features. +**/ +RETURN_STATUS +RegisterCpuFeatureWorker ( + IN CPU_FEATURES_DATA *CpuFeaturesData, + IN CPU_FEATURES_ENTRY *CpuFeature + ) +{ + EFI_STATUS Status; + CPU_FEATURES_ENTRY *CpuFeatureEntry; + LIST_ENTRY *Entry; + BOOLEAN FeatureExist; + + FeatureExist = FALSE; + CpuFeatureEntry = NULL; + Entry = GetFirstNode (&CpuFeaturesData->FeatureList); + while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) { + CpuFeatureEntry = CPU_FEATURE_ENTRY_FROM_LINK (Entry); + if (CompareMem (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask, CpuFeaturesData->BitMaskSize) == 0) { + // + // If this feature already registered + // + FeatureExist = TRUE; + break; + } + Entry = Entry->ForwardLink; + } + + if (!FeatureExist) { + DEBUG ((DEBUG_INFO, "[NEW] ")); + DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize); + InsertTailList (&CpuFeaturesData->FeatureList, &CpuFeature->Link); + CpuFeaturesData->FeaturesCount++; + } else { + DEBUG ((DEBUG_INFO, "[OVERRIDE] ")); + DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize); + ASSERT (CpuFeatureEntry != NULL); + // + // Overwrite original parameters of CPU feature + // + if (CpuFeature->GetConfigDataFunc != NULL) { + CpuFeatureEntry->GetConfigDataFunc = CpuFeature->GetConfigDataFunc; + } + if (CpuFeature->SupportFunc != NULL) { + CpuFeatureEntry->SupportFunc = CpuFeature->SupportFunc; + } + if (CpuFeature->InitializeFunc != NULL) { + CpuFeatureEntry->InitializeFunc = CpuFeature->InitializeFunc; + } + if (CpuFeature->FeatureName != NULL) { + if (CpuFeatureEntry->FeatureName == NULL) { + CpuFeatureEntry->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE); + ASSERT (CpuFeatureEntry->FeatureName != NULL); + } + Status = AsciiStrCpyS (CpuFeatureEntry->FeatureName, CPU_FEATURE_NAME_SIZE, CpuFeature->FeatureName); + ASSERT_EFI_ERROR (Status); + FreePool (CpuFeature->FeatureName); + } + if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) { + if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask); + } + CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask; + } + if (CpuFeature->ThreadAfterFeatureBitMask != NULL) { + if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask); + } + CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask; + } + if (CpuFeature->CoreBeforeFeatureBitMask != NULL) { + if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask); + } + CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask; + } + if (CpuFeature->CoreAfterFeatureBitMask != NULL) { + if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask); + } + CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask; + } + if (CpuFeature->PackageBeforeFeatureBitMask != NULL) { + if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask); + } + CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask; + } + if (CpuFeature->PackageAfterFeatureBitMask != NULL) { + if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) { + FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask); + } + CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask; + } + + CpuFeatureEntry->BeforeAll = CpuFeature->BeforeAll; + CpuFeatureEntry->AfterAll = CpuFeature->AfterAll; + + FreePool (CpuFeature->FeatureMask); + FreePool (CpuFeature); + } + // + // Verify CPU features dependency can change CPU feature order + // + CheckCpuFeaturesDependency (&CpuFeaturesData->FeatureList); + return RETURN_SUCCESS; +} + +/** + Sets CPU feature bit mask in CPU feature bit mask buffer. + + @param[in] FeaturesBitMask Pointer to CPU feature bit mask buffer + @param[in] Feature The bit number of the CPU feature + @param[in] BitMaskSize CPU feature bit mask buffer size +**/ +VOID +SetCpuFeaturesBitMask ( + IN UINT8 **FeaturesBitMask, + IN UINT32 Feature, + IN UINTN BitMaskSize + ) +{ + UINT8 *CpuFeaturesBitMask; + + ASSERT (FeaturesBitMask != NULL); + CpuFeaturesBitMask = *FeaturesBitMask; + if (CpuFeaturesBitMask == NULL) { + CpuFeaturesBitMask = AllocateZeroPool (BitMaskSize); + ASSERT (CpuFeaturesBitMask != NULL); + *FeaturesBitMask = CpuFeaturesBitMask; + } + + CpuFeaturesBitMask += (Feature / 8); + *CpuFeaturesBitMask |= (UINT8) (1 << (Feature % 8)); +} + +/** + Registers a CPU Feature. + + @param[in] FeatureName A Null-terminated Ascii string indicates CPU feature + name. + @param[in] GetConfigDataFunc CPU feature get configuration data function. This + is an optional parameter that may be NULL. If NULL, + then the most recently registered function for the + CPU feature is used. If no functions are registered + for a CPU feature, then the CPU configuration data + for the registered feature is NULL. + @param[in] SupportFunc CPU feature support function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature is assumed to be + supported by all CPUs. + @param[in] InitializeFunc CPU feature initialize function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature initialization is + skipped. + @param[in] ... Variable argument list of UINT32 CPU feature value. + Values with no modifiers are the features provided + by the registered functions. + Values with CPU_FEATURE_BEFORE modifier are features + that must be initialized after the features provided + by the registered functions are used. + Values with CPU_FEATURE_AFTER modifier are features + that must be initialized before the features provided + by the registered functions are used. + The last argument in this variable argument list must + always be CPU_FEATURE_END. + + @retval RETURN_SUCCESS The CPU feature was successfully registered. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to register + the CPU feature. + @retval RETURN_UNSUPPORTED Registration of the CPU feature is not + supported due to a circular dependency between + BEFORE and AFTER features. + @retval RETURN_NOT_READY CPU feature PCD PcdCpuFeaturesUserConfiguration + not updated by Platform driver yet. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +RegisterCpuFeature ( + IN CHAR8 *FeatureName, OPTIONAL + IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc, OPTIONAL + IN CPU_FEATURE_SUPPORT SupportFunc, OPTIONAL + IN CPU_FEATURE_INITIALIZE InitializeFunc, OPTIONAL + ... + ) +{ + EFI_STATUS Status; + VA_LIST Marker; + UINT32 Feature; + CPU_FEATURES_ENTRY *CpuFeature; + UINT8 *FeatureMask; + UINT8 *ThreadBeforeFeatureBitMask; + UINT8 *ThreadAfterFeatureBitMask; + UINT8 *CoreBeforeFeatureBitMask; + UINT8 *CoreAfterFeatureBitMask; + UINT8 *PackageBeforeFeatureBitMask; + UINT8 *PackageAfterFeatureBitMask; + BOOLEAN BeforeAll; + BOOLEAN AfterAll; + CPU_FEATURES_DATA *CpuFeaturesData; + + FeatureMask = NULL; + ThreadBeforeFeatureBitMask = NULL; + ThreadAfterFeatureBitMask = NULL; + CoreBeforeFeatureBitMask = NULL; + CoreAfterFeatureBitMask = NULL; + PackageBeforeFeatureBitMask = NULL; + PackageAfterFeatureBitMask = NULL; + BeforeAll = FALSE; + AfterAll = FALSE; + + CpuFeaturesData = GetCpuFeaturesData (); + if (CpuFeaturesData->FeaturesCount == 0) { + InitializeListHead (&CpuFeaturesData->FeatureList); + InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock); + // + // Code assumes below three PCDs have PCD same buffer size. + // + ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesCapability)); + ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesSupport)); + CpuFeaturesData->BitMaskSize = (UINT32) PcdGetSize (PcdCpuFeaturesSetting); + } + + VA_START (Marker, InitializeFunc); + Feature = VA_ARG (Marker, UINT32); + while (Feature != CPU_FEATURE_END) { + // + // It's invalid to require a feature is before AND after all other features. + // + ASSERT ((Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)) + != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)); + + // + // It's invalid to require feature A is before AND after before feature B, + // either in thread level, core level or package level. + // + ASSERT ((Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)) + != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)); + ASSERT ((Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)) + != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)); + ASSERT ((Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)) + != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)); + if (Feature < CPU_FEATURE_THREAD_BEFORE) { + BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE; + AfterAll = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE; + Feature &= ~(CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL); + ASSERT (FeatureMask == NULL); + SetCpuFeaturesBitMask (&FeatureMask, Feature, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_THREAD_BEFORE) != 0) { + SetCpuFeaturesBitMask (&ThreadBeforeFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_BEFORE, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_THREAD_AFTER) != 0) { + SetCpuFeaturesBitMask (&ThreadAfterFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_AFTER, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) { + SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) { + SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) { + SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, CpuFeaturesData->BitMaskSize); + } else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) { + SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, CpuFeaturesData->BitMaskSize); + } + Feature = VA_ARG (Marker, UINT32); + } + VA_END (Marker); + + CpuFeature = AllocateZeroPool (sizeof (CPU_FEATURES_ENTRY)); + ASSERT (CpuFeature != NULL); + CpuFeature->Signature = CPU_FEATURE_ENTRY_SIGNATURE; + CpuFeature->FeatureMask = FeatureMask; + CpuFeature->ThreadBeforeFeatureBitMask = ThreadBeforeFeatureBitMask; + CpuFeature->ThreadAfterFeatureBitMask = ThreadAfterFeatureBitMask; + CpuFeature->CoreBeforeFeatureBitMask = CoreBeforeFeatureBitMask; + CpuFeature->CoreAfterFeatureBitMask = CoreAfterFeatureBitMask; + CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask; + CpuFeature->PackageAfterFeatureBitMask = PackageAfterFeatureBitMask; + CpuFeature->BeforeAll = BeforeAll; + CpuFeature->AfterAll = AfterAll; + CpuFeature->GetConfigDataFunc = GetConfigDataFunc; + CpuFeature->SupportFunc = SupportFunc; + CpuFeature->InitializeFunc = InitializeFunc; + if (FeatureName != NULL) { + CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE); + ASSERT (CpuFeature->FeatureName != NULL); + Status = AsciiStrCpyS (CpuFeature->FeatureName, CPU_FEATURE_NAME_SIZE, FeatureName); + ASSERT_EFI_ERROR (Status); + } + + Status = RegisterCpuFeatureWorker (CpuFeaturesData, CpuFeature); + ASSERT_EFI_ERROR (Status); + + return RETURN_SUCCESS; +} + +/** + Return ACPI_CPU_DATA data. + + @return Pointer to ACPI_CPU_DATA data. +**/ +ACPI_CPU_DATA * +GetAcpiCpuData ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NumberOfCpus; + UINTN NumberOfEnabledProcessors; + ACPI_CPU_DATA *AcpiCpuData; + UINTN TableSize; + CPU_REGISTER_TABLE *RegisterTable; + UINTN Index; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + + AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress); + if (AcpiCpuData != NULL) { + return AcpiCpuData; + } + + AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA))); + ASSERT (AcpiCpuData != NULL); + + // + // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure + // + Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData); + ASSERT_EFI_ERROR (Status); + + GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors); + AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus; + + // + // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs + // + TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE); + RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize)); + ASSERT (RegisterTable != NULL); + + for (Index = 0; Index < NumberOfCpus; Index++) { + Status = GetProcessorInformation (Index, &ProcessorInfoBuffer); + ASSERT_EFI_ERROR (Status); + + RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId; + RegisterTable[Index].TableLength = 0; + RegisterTable[Index].AllocatedSize = 0; + RegisterTable[Index].RegisterTableEntry = 0; + + RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId; + RegisterTable[NumberOfCpus + Index].TableLength = 0; + RegisterTable[NumberOfCpus + Index].AllocatedSize = 0; + RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0; + } + AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable; + AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus); + + return AcpiCpuData; +} + +/** + Enlarges CPU register table for each processor. + + @param[in, out] RegisterTable Pointer processor's CPU register table +**/ +STATIC +VOID +EnlargeRegisterTable ( + IN OUT CPU_REGISTER_TABLE *RegisterTable + ) +{ + EFI_PHYSICAL_ADDRESS Address; + UINTN UsedPages; + + UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE; + Address = (UINTN)AllocatePages (UsedPages + 1); + ASSERT (Address != 0); + + // + // If there are records existing in the register table, then copy its contents + // to new region and free the old one. + // + if (RegisterTable->AllocatedSize > 0) { + CopyMem ( + (VOID *) (UINTN) Address, + (VOID *) (UINTN) RegisterTable->RegisterTableEntry, + RegisterTable->AllocatedSize + ); + + FreePages ((VOID *)(UINTN)RegisterTable->RegisterTableEntry, UsedPages); + } + + // + // Adjust the allocated size and register table base address. + // + RegisterTable->AllocatedSize += EFI_PAGE_SIZE; + RegisterTable->RegisterTableEntry = Address; +} + +/** + Add an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] PreSmmFlag If TRUE, entry will be added into PreSmm register table + If FALSE, entry will be added into register table + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValidBitStart Start of the bit section + @param[in] ValidBitLength Length of the bit section + @param[in] Value Value to write + @param[in] TestThenWrite Whether need to test current Value before writing. + +**/ +VOID +CpuRegisterTableWriteWorker ( + IN BOOLEAN PreSmmFlag, + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT8 ValidBitStart, + IN UINT8 ValidBitLength, + IN UINT64 Value, + IN BOOLEAN TestThenWrite + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + ACPI_CPU_DATA *AcpiCpuData; + CPU_REGISTER_TABLE *RegisterTable; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; + + CpuFeaturesData = GetCpuFeaturesData (); + if (CpuFeaturesData->RegisterTable == NULL) { + AcpiCpuData = GetAcpiCpuData (); + ASSERT ((AcpiCpuData != NULL) && (AcpiCpuData->RegisterTable != 0)); + CpuFeaturesData->RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->RegisterTable; + CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->PreSmmInitRegisterTable; + } + + if (PreSmmFlag) { + RegisterTable = &CpuFeaturesData->PreSmmRegisterTable[ProcessorNumber]; + } else { + RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber]; + } + + if (RegisterTable->TableLength == RegisterTable->AllocatedSize / sizeof (CPU_REGISTER_TABLE_ENTRY)) { + EnlargeRegisterTable (RegisterTable); + } + + // + // Append entry in the register table. + // + RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry; + RegisterTableEntry[RegisterTable->TableLength].RegisterType = RegisterType; + RegisterTableEntry[RegisterTable->TableLength].Index = (UINT32) Index; + RegisterTableEntry[RegisterTable->TableLength].HighIndex = (UINT32) RShiftU64 (Index, 32); + RegisterTableEntry[RegisterTable->TableLength].ValidBitStart = ValidBitStart; + RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength; + RegisterTableEntry[RegisterTable->TableLength].Value = Value; + RegisterTableEntry[RegisterTable->TableLength].TestThenWrite = TestThenWrite; + + RegisterTable->TableLength++; +} + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ) +{ + UINT8 Start; + UINT8 End; + UINT8 Length; + + Start = (UINT8)LowBitSet64 (ValueMask); + End = (UINT8)HighBitSet64 (ValueMask); + Length = End - Start + 1; + CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE); +} + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableTestThenWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ) +{ + UINT8 Start; + UINT8 End; + UINT8 Length; + + Start = (UINT8)LowBitSet64 (ValueMask); + End = (UINT8)HighBitSet64 (ValueMask); + Length = End - Start + 1; + CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE); +} + +/** + Adds an entry in specified Pre-SMM register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +PreSmmCpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ) +{ + UINT8 Start; + UINT8 End; + UINT8 Length; + + Start = (UINT8)LowBitSet64 (ValueMask); + End = (UINT8)HighBitSet64 (ValueMask); + Length = End - Start + 1; + CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE); +} + +/** + Worker function to determine if a CPU feature is set in input CPU feature bit mask buffer. + + @param[in] CpuBitMask CPU feature bit mask buffer + @param[in] CpuBitMaskSize The size of CPU feature bit mask buffer + @param[in] Feature The bit number of the CPU feature + + @retval TRUE The CPU feature is set in CpuBitMask. + @retval FALSE The CPU feature is not set in CpuBitMask. + +**/ +BOOLEAN +IsCpuFeatureSetInCpuPcd ( + IN UINT8 *CpuBitMask, + IN UINTN CpuBitMaskSize, + IN UINT32 Feature + ) +{ + if ((Feature >> 3) >= CpuBitMaskSize) { + return FALSE; + } + return ((*(CpuBitMask + (Feature >> 3)) & (1 << (Feature & 0x07))) != 0); +} + +/** + Determines if a CPU feature is enabled in PcdCpuFeaturesSupport bit mask. + If a CPU feature is disabled in PcdCpuFeaturesSupport then all the code/data + associated with that feature should be optimized away if compiler + optimizations are enabled. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSupport + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSupport. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSupport. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureSupported ( + IN UINT32 Feature + ) +{ + return IsCpuFeatureSetInCpuPcd ( + (UINT8 *)PcdGetPtr (PcdCpuFeaturesSupport), + PcdGetSize (PcdCpuFeaturesSupport), + Feature + ); +} + +/** + Determines if a CPU feature is set in PcdCpuFeaturesSetting bit mask. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSetting + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSetting. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSetting. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureInSetting ( + IN UINT32 Feature + ) +{ + return IsCpuFeatureSetInCpuPcd ( + (UINT8 *)PcdGetPtr (PcdCpuFeaturesSetting), + PcdGetSize (PcdCpuFeaturesSetting), + Feature + ); +} + +/** + Switches to assigned BSP after CPU features initialization. + + @param[in] ProcessorNumber The index of the CPU executing this function. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +SwitchBspAfterFeaturesInitialize ( + IN UINTN ProcessorNumber + ) +{ + CPU_FEATURES_DATA *CpuFeaturesData; + + CpuFeaturesData = GetCpuFeaturesData (); + CpuFeaturesData->BspNumber = ProcessorNumber; +} + diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.uni b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.uni new file mode 100644 index 000000000..fee904711 --- /dev/null +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.uni @@ -0,0 +1,16 @@ +// /** @file +// Register CPU Features Library instance. +// +// Register CPU Features Library instance. +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Register CPU Features Library instance" + +#string STR_MODULE_DESCRIPTION #language en-US "Register CPU Features Library instance." + diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf new file mode 100644 index 000000000..cd8bc628c --- /dev/null +++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf @@ -0,0 +1,54 @@ +## @file +# Instance of Timer Library only using CPU resources. +# +# Timer Library that only uses CPU resources to provide calibrated delays +# on IA-32, x64, and IPF. +# Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can use this TimerLib +# in their initialization without any issues. They only have to be careful in +# the implementation of runtime services and SMI handlers. +# Because CPU Local APIC and ITC could be programmed by OS, it cannot be +# used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM +# drivers and runtime drivers. +# +# This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in +# that it uses the local APIC library so that it supports x2APIC mode. +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecPeiDxeTimerLibUefiCpu + MODULE_UNI_FILE = SecPeiDxeTimerLibUefiCpu.uni + FILE_GUID = 4FFF2014-2086-4ee6-9B58-886D1967861C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib + + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + X86TimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + +[LibraryClasses] + PcdLib + DebugLib + LocalApicLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES + diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni new file mode 100644 index 000000000..e40ee106b --- /dev/null +++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni @@ -0,0 +1,26 @@ +// /** @file +// Instance of Timer Library only using CPU resources. +// +// Timer Library that only uses CPU resources to provide calibrated delays +// on IA-32, x64, and IPF. +// Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can use this TimerLib +// in their initialization without any issues. They only have to be careful in +// the implementation of runtime services and SMI handlers. +// Because CPU Local APIC and ITC could be programmed by OS, it cannot be +// used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM +// drivers and runtime drivers. +// +// This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in +// that it uses the local APIC library so that it supports x2APIC mode. +// +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Instance of Timer Library only using CPU resources" + +#string STR_MODULE_DESCRIPTION #language en-US "Timer Library that only uses CPU resources to provide calibrated delays on IA-32, x64, and IPF. Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can use this TimerLib in their initialization without any issues. They only have to be careful in the implementation of runtime services and SMI handlers. Because CPU Local APIC and ITC could be programmed by OS, it cannot be used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM drivers and runtime drivers. This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in that it uses the local APIC library so that it supports x2APIC mode." + diff --git a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c similarity index 75% rename from CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c rename to UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c index 99f8121ee..5d7fa80dd 100644 --- a/CloverEFI/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c +++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c @@ -2,15 +2,9 @@ Timer Library functions built upon local APIC on IA32/x64. This library uses the local APIC library so that it supports x2APIC mode. - - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -45,6 +39,9 @@ InternalX86GetTimerFrequency ( Stalls the CPU for at least the given number of ticks. It's invoked by MicroSecondDelay() and NanoSecondDelay(). + This function will ASSERT if the APIC timer intial count returned from + GetApicTimerInitCount() is zero. + @param Delay A period of time to delay in ticks. **/ @@ -55,22 +52,50 @@ InternalX86Delay ( ) { INT32 Ticks; - UINT32 PowerOfTwoCounter; + UINT32 Times; + UINT32 InitCount; + UINT32 StartTick; // - // The target timer count is calculated here + // In case Delay is too larger, separate it into several small delay slot. + // Devided Delay by half value of Init Count is to avoid Delay close to + // the Init Count, timeout maybe missing if the time consuming between 2 + // GetApicTimerCurrentCount() invoking is larger than the time gap between + // Delay and the Init Count. // - Ticks = GetApicTimerCurrentCount () - Delay; + InitCount = GetApicTimerInitCount (); + ASSERT (InitCount != 0); + Times = Delay / (InitCount / 2); + Delay = Delay % (InitCount / 2); // - // Wait until time out - // Delay > 2^31 could not be handled by this function - // Timer wrap-arounds are handled correctly by this function + // Get Start Tick and do delay // - PowerOfTwoCounter = GetPowerOfTwo32 (GetApicTimerInitCount ()); - while (((UINT32)(GetApicTimerCurrentCount () - Ticks) & PowerOfTwoCounter) == 0) { - CpuPause (); - } + StartTick = GetApicTimerCurrentCount (); + do { + // + // Wait until time out by Delay value + // + do { + CpuPause (); + // + // Get Ticks from Start to Current. + // + Ticks = StartTick - GetApicTimerCurrentCount (); + // + // Ticks < 0 means Timer wrap-arounds happens. + // + if (Ticks < 0) { + Ticks += InitCount; + } + } while ((UINT32)Ticks < Delay); + + // + // Update StartTick and Delay for next delay slot + // + StartTick -= (StartTick > Delay) ? Delay : (Delay - InitCount); + Delay = InitCount / 2; + } while (Times-- > 0); } /** @@ -181,10 +206,6 @@ GetPerformanceCounterProperties ( { if (StartValue != NULL) { *StartValue = (UINT64)GetApicTimerInitCount (); - // - // make sure StartValue is all 1s from High Bit - // - ASSERT ((*StartValue & (*StartValue + 1)) == 0); } if (EndValue != NULL) { diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm new file mode 100644 index 000000000..c98906c01 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm @@ -0,0 +1,276 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiEntry.nasm +; +; Abstract: +; +; Code template of the SMI handler for a particular processor +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +; +; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR +; +%define DSC_OFFSET 0xfb00 +%define DSC_GDTPTR 0x48 +%define DSC_GDTSIZ 0x50 +%define DSC_CS 0x14 +%define DSC_DS 0x16 +%define DSC_SS 0x18 +%define DSC_OTHERSEG 0x1a + +%define PROTECT_MODE_CS 0x8 +%define PROTECT_MODE_DS 0x20 +%define TSS_SEGMENT 0x40 + +extern ASM_PFX(SmiRendezvous) +extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) +extern ASM_PFX(CpuSmmDebugEntry) +extern ASM_PFX(CpuSmmDebugExit) + +global ASM_PFX(gcStmSmiHandlerTemplate) +global ASM_PFX(gcStmSmiHandlerSize) +global ASM_PFX(gcStmSmiHandlerOffset) +global ASM_PFX(gStmSmiCr3) +global ASM_PFX(gStmSmiStack) +global ASM_PFX(gStmSmbase) +global ASM_PFX(gStmXdSupported) +extern ASM_PFX(gStmSmiHandlerIdtr) + +ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4 +ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4 +ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4 +ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1 + + SECTION .text + +BITS 16 +ASM_PFX(gcStmSmiHandlerTemplate): +_StmSmiEntryPoint: + mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000 + mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ] + dec ax + mov [cs:bx], ax + mov eax, [cs:DSC_OFFSET + DSC_GDTPTR] + mov [cs:bx + 2], eax + mov ebp, eax ; ebp = GDT base +o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx] + mov ax, PROTECT_MODE_CS + mov [cs:bx-0x2],ax +o32 mov edi, strict dword 0 +StmSmbasePatch: + lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000] + mov [cs:bx-0x6],eax + mov ebx, cr0 + and ebx, 0x9ffafff3 + or ebx, 0x23 + mov cr0, ebx + jmp dword 0x0:0x0 +_StmGdtDesc: + DW 0 + DD 0 + +BITS 32 +@32bit: + mov ax, PROTECT_MODE_DS +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax + mov esp, strict dword 0 +StmSmiStackPatch: + mov eax, ASM_PFX(gStmSmiHandlerIdtr) + lidt [eax] + jmp ProtFlatMode + +ProtFlatMode: + mov eax, strict dword 0 +StmSmiCr3Patch: + mov cr3, eax +; +; Need to test for CR4 specific bit support +; + mov eax, 1 + cpuid ; use CPUID to determine if specific CR4 bits are supported + xor eax, eax ; Clear EAX + test edx, BIT2 ; Check for DE capabilities + jz .0 + or eax, BIT3 +.0: + test edx, BIT6 ; Check for PAE capabilities + jz .1 + or eax, BIT5 +.1: + test edx, BIT7 ; Check for MCE capabilities + jz .2 + or eax, BIT6 +.2: + test edx, BIT24 ; Check for FXSR capabilities + jz .3 + or eax, BIT9 +.3: + test edx, BIT25 ; Check for SSE capabilities + jz .4 + or eax, BIT10 +.4: ; as cr4.PGE is not set here, refresh cr3 + mov cr4, eax ; in PreModifyMtrrs() to flush TLB. + + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 + jz .6 +; Load TSS + mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag + mov eax, TSS_SEGMENT + ltr ax +.6: + +; enable NXE if supported + mov al, strict byte 1 +StmXdSupportedPatch: + cmp al, 0 + jz @SkipXd +; +; Check XD disable bit +; + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + push edx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .5 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.5: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr + jmp @XdDone +@SkipXd: + sub esp, 4 +@XdDone: + + mov ebx, cr0 + or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, ebx + lea ebx, [edi + DSC_OFFSET] + mov ax, [ebx + DSC_DS] + mov ds, eax + mov ax, [ebx + DSC_OTHERSEG] + mov es, eax + mov fs, eax + mov gs, eax + mov ax, [ebx + DSC_SS] + mov ss, eax + +CommonHandler: + mov ebx, [esp + 4] ; CPU Index + push ebx + mov eax, ASM_PFX(CpuSmmDebugEntry) + call eax + add esp, 4 + + push ebx + mov eax, ASM_PFX(SmiRendezvous) + call eax + add esp, 4 + + push ebx + mov eax, ASM_PFX(CpuSmmDebugExit) + call eax + add esp, 4 + + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz .7 + pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .7 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.7: + StuffRsb32 + rsm + + +_StmSmiHandler: +; +; Check XD disable bit +; + xor esi, esi + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz @StmXdDone + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .5 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.5: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone: + push esi + + ; below step is needed, because STM does not run above code. + ; we have to run below code to set IDT/CR0/CR4 + mov eax, ASM_PFX(gStmSmiHandlerIdtr) + lidt [eax] + + mov eax, cr0 + or eax, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, eax +; +; Need to test for CR4 specific bit support +; + mov eax, 1 + cpuid ; use CPUID to determine if specific CR4 bits are supported + mov eax, cr4 ; init EAX + test edx, BIT2 ; Check for DE capabilities + jz .0 + or eax, BIT3 +.0: + test edx, BIT6 ; Check for PAE capabilities + jz .1 + or eax, BIT5 +.1: + test edx, BIT7 ; Check for MCE capabilities + jz .2 + or eax, BIT6 +.2: + test edx, BIT24 ; Check for FXSR capabilities + jz .3 + or eax, BIT9 +.3: + test edx, BIT25 ; Check for SSE capabilities + jz .4 + or eax, BIT10 +.4: ; as cr4.PGE is not set here, refresh cr3 + mov cr4, eax ; in PreModifyMtrrs() to flush TLB. + ; STM init finish + jmp CommonHandler + +ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint +ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint + +global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress) +ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress): + ret diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiException.nasm b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiException.nasm new file mode 100644 index 000000000..b9c7e0bb2 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiException.nasm @@ -0,0 +1,173 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiException.nasm +; +; Abstract: +; +; Exception handlers used in SM mode +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +global ASM_PFX(gcStmPsd) + +extern ASM_PFX(SmmStmExceptionHandler) +extern ASM_PFX(SmmStmSetup) +extern ASM_PFX(SmmStmTeardown) +extern ASM_PFX(gStmXdSupported) +extern ASM_PFX(gStmSmiHandlerIdtr) + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +CODE_SEL equ 0x08 +DATA_SEL equ 0x20 +TSS_SEL equ 0x40 + + SECTION .data + +ASM_PFX(gcStmPsd): + DB 'TXTPSSIG' + DW PSD_SIZE + DW 1 ; Version + DD 0 ; LocalApicId + DB 0x05 ; Cr4Pse;Cr4Pae;Intel64Mode;ExecutionDisableOutsideSmrr + DB 0 ; BIOS to STM + DB 0 ; STM to BIOS + DB 0 + DW CODE_SEL + DW DATA_SEL + DW DATA_SEL + DW DATA_SEL + DW TSS_SEL + DW 0 + DQ 0 ; SmmCr3 + DD ASM_PFX(OnStmSetup) + DD 0 + DD ASM_PFX(OnStmTeardown) + DD 0 + DQ 0 ; SmmSmiHandlerRip - SMM guest entrypoint + DQ 0 ; SmmSmiHandlerRsp + DQ 0 + DD 0 + DD 0x80010100 ; RequiredStmSmmRevId + DD ASM_PFX(OnException) + DD 0 + DQ 0 ; ExceptionStack + DW DATA_SEL + DW 0x01F ; ExceptionFilter + DD 0 + DD 0 + DD 0 + DQ 0 ; BiosHwResourceRequirementsPtr + DQ 0 ; AcpiRsdp + DB 0 ; PhysicalAddressBits +PSD_SIZE equ $ - ASM_PFX(gcStmPsd) + + SECTION .text +;------------------------------------------------------------------------------ +; SMM Exception handlers +;------------------------------------------------------------------------------ +global ASM_PFX(OnException) +ASM_PFX(OnException): + mov ecx, esp + push ecx + call ASM_PFX(SmmStmExceptionHandler) + add esp, 4 + + mov ebx, eax + mov eax, 4 + vmcall + jmp $ + +global ASM_PFX(OnStmSetup) +ASM_PFX(OnStmSetup): +; +; Check XD disable bit +; + xor esi, esi + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz @StmXdDone1 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .51 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.51: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone1: + push esi + + call ASM_PFX(SmmStmSetup) + + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz .71 + pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .71 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.71: + StuffRsb32 + rsm + +global ASM_PFX(OnStmTeardown) +ASM_PFX(OnStmTeardown): +; +; Check XD disable bit +; + xor esi, esi + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz @StmXdDone2 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .52 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.52: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone2: + push esi + + call ASM_PFX(SmmStmTeardown) + + mov eax, ASM_PFX(gStmXdSupported) + mov al, [eax] + cmp al, 0 + jz .72 + pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .72 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.72: + StuffRsb32 + rsm diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmmStmSupport.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmmStmSupport.c new file mode 100644 index 000000000..399ddd742 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmmStmSupport.c @@ -0,0 +1,77 @@ +/** @file + SMM STM support functions + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include "SmmStm.h" + +/// +/// Page Table Entry +/// +#define IA32_PG_P BIT0 +#define IA32_PG_RW BIT1 +#define IA32_PG_PS BIT7 + +/** + + Create 4G page table for STM. + 4M Non-PAE page table in IA32 version. + + @param PageTableBase The page table base in MSEG + +**/ +VOID +StmGen4GPageTable ( + IN UINTN PageTableBase + ) +{ + UINTN Index; + UINT32 *Pte; + UINT32 Address; + + Pte = (UINT32*)(UINTN)PageTableBase; + + Address = 0; + for (Index = 0; Index < SIZE_4KB / sizeof (*Pte); Index++) { + *Pte = Address | IA32_PG_PS | IA32_PG_RW | IA32_PG_P; + Pte++; + Address += SIZE_4MB; + } +} + +/** + This is SMM exception handle. + Consumed by STM when exception happen. + + @param Context STM protection exception stack frame + + @return the EBX value for STM reference. + EBX = 0: resume SMM guest using register state found on exception stack. + EBX = 1 to 0x0F: EBX contains a BIOS error code which the STM must record in the + TXT.ERRORCODE register and subsequently reset the system via + TXT.CMD.SYS_RESET. The value of the TXT.ERRORCODE register is calculated as + follows: TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC + EBX = 0x10 to 0xFFFFFFFF - reserved, do not use. + +**/ +UINT32 +EFIAPI +SmmStmExceptionHandler ( + IN OUT STM_PROTECTION_EXCEPTION_STACK_FRAME Context + ) +{ + // TBD - SmmStmExceptionHandler, record information + DEBUG ((DEBUG_ERROR, "SmmStmExceptionHandler ...\n")); + // + // Skip this instruction and continue; + // + Context.Ia32StackFrame->Rip += Context.Ia32StackFrame->VmcsExitInstructionLength; + + return 0; +} diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c new file mode 100644 index 000000000..a00786a8e --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c @@ -0,0 +1,626 @@ +/** @file +The CPU specific programming for PiSmmCpuDxeSmm module. + +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Machine Specific Registers (MSRs) +// +#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE +#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2 +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3 +#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0 +#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1 +#define EFI_MSR_SMRR_MASK 0xFFFFF000 +#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11 +#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0 + +// +// MSRs required for configuration of SMM Code Access Check +// +#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D +#define SMM_CODE_ACCESS_CHK_BIT BIT58 + +/** + Internal worker function that is called to complete CPU initialization at the + end of SmmCpuFeaturesInitializeProcessor(). + +**/ +VOID +FinishSmmCpuFeaturesInitializeProcessor ( + VOID + ); + +// +// Set default value to assume SMRR is not supported +// +BOOLEAN mSmrrSupported = FALSE; + +// +// Set default value to assume MSR_SMM_FEATURE_CONTROL is not supported +// +BOOLEAN mSmmFeatureControlSupported = FALSE; + +// +// Set default value to assume IA-32 Architectural MSRs are used +// +UINT32 mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE; +UINT32 mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK; + +// +// Set default value to assume MTRRs need to be configured on each SMI +// +BOOLEAN mNeedConfigureMtrrs = TRUE; + +// +// Array for state of SMRR enable on all CPUs +// +BOOLEAN *mSmrrEnabled; + +/** + The constructor function + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT32 RegEax; + UINT32 RegEdx; + UINTN FamilyId; + UINTN ModelId; + + // + // Retrieve CPU Family and Model + // + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx); + FamilyId = (RegEax >> 8) & 0xf; + ModelId = (RegEax >> 4) & 0xf; + if (FamilyId == 0x06 || FamilyId == 0x0f) { + ModelId = ModelId | ((RegEax >> 12) & 0xf0); + } + + // + // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability + // + if ((RegEdx & BIT12) != 0) { + // + // Check MTRR_CAP MSR bit 11 for SMRR support + // + if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0) { + mSmrrSupported = TRUE; + } + } + + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family + // + // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then + // SMRR Physical Base and SMM Physical Mask MSRs are not available. + // + if (FamilyId == 0x06) { + if (ModelId == 0x1C || ModelId == 0x26 || ModelId == 0x27 || ModelId == 0x35 || ModelId == 0x36) { + mSmrrSupported = FALSE; + } + } + + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family + // + // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2 + // Processor Family MSRs + // + if (FamilyId == 0x06) { + if (ModelId == 0x17 || ModelId == 0x0f) { + mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE; + mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK; + } + } + + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 34.4.2 SMRAM Caching + // An IA-32 processor does not automatically write back and invalidate its + // caches before entering SMM or before exiting SMM. Because of this behavior, + // care must be taken in the placement of the SMRAM in system memory and in + // the caching of the SMRAM to prevent cache incoherence when switching back + // and forth between SMM and protected mode operation. + // + // An IA-32 processor is a processor that does not support the Intel 64 + // Architecture. Support for the Intel 64 Architecture can be detected from + // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29] + // + // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to TRUE, + // so caches are flushed on SMI entry and SMI exit, the interrupted code + // MTRRs are saved/restored, and MTRRs for SMM are loaded. + // + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax >= CPUID_EXTENDED_CPU_SIG) { + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT29) != 0) { + mNeedConfigureMtrrs = FALSE; + } + } + + // + // Allocate array for state of SMRR enable on all CPUs + // + mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + ASSERT (mSmrrEnabled != NULL); + + return EFI_SUCCESS; +} + +/** + Called during the very first SMI into System Management Mode to initialize + CPU features, including SMBASE, for the currently executing CPU. Since this + is the first SMI, the SMRAM Save State Map is at the default address of + SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The currently executing + CPU is specified by CpuIndex and CpuIndex can be used to access information + about the currently executing CPU in the ProcessorInfo array and the + HotPlugCpuData data structure. + + @param[in] CpuIndex The index of the CPU to initialize. The value + must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU that + was elected as monarch during System Management + Mode initialization. + FALSE if the CpuIndex is not the index of the CPU + that was elected as monarch during System + Management Mode initialization. + @param[in] ProcessorInfo Pointer to an array of EFI_PROCESSOR_INFORMATION + structures. ProcessorInfo[CpuIndex] contains the + information for the currently executing CPU. + @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA structure that + contains the ApidId and SmBase arrays. +**/ +VOID +EFIAPI +SmmCpuFeaturesInitializeProcessor ( + IN UINTN CpuIndex, + IN BOOLEAN IsMonarch, + IN EFI_PROCESSOR_INFORMATION *ProcessorInfo, + IN CPU_HOT_PLUG_DATA *CpuHotPlugData + ) +{ + SMRAM_SAVE_STATE_MAP *CpuState; + UINT64 FeatureControl; + UINT32 RegEax; + UINT32 RegEdx; + UINTN FamilyId; + UINTN ModelId; + + // + // Configure SMBASE. + // + CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET); + CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex]; + + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family + // + // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used, then + // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is set before + // accessing SMRR base/mask MSRs. If Lock(BIT0) of MSR_FEATURE_CONTROL MSR(0x3A) + // is set, then the MSR is locked and can not be modified. + // + if (mSmrrSupported && mSmrrPhysBaseMsr == SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE) { + FeatureControl = AsmReadMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL); + if ((FeatureControl & BIT3) == 0) { + if ((FeatureControl & BIT0) == 0) { + AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL, FeatureControl | BIT3); + } else { + mSmrrSupported = FALSE; + } + } + } + + // + // If SMRR is supported, then program SMRR base/mask MSRs. + // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first normal SMI. + // The code that initializes SMM environment is running in normal mode + // from SMRAM region. If SMRR is enabled here, then the SMRAM region + // is protected and the normal mode code execution will fail. + // + if (mSmrrSupported) { + // + // SMRR size cannot be less than 4-KBytes + // SMRR size must be of length 2^n + // SMRR base alignment cannot be less than SMRR length + // + if ((CpuHotPlugData->SmrrSize < SIZE_4KB) || + (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData->SmrrSize)) || + ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) != CpuHotPlugData->SmrrBase)) { + // + // Print message and halt if CPU is Monarch + // + if (IsMonarch) { + DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet alignment/size requirement!\n")); + CpuDeadLoop (); + } + } else { + AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase | MTRR_CACHE_WRITE_BACK); + AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1) & EFI_MSR_SMRR_MASK)); + mSmrrEnabled[CpuIndex] = FALSE; + } + } + + // + // Retrieve CPU Family and Model + // + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx); + FamilyId = (RegEax >> 8) & 0xf; + ModelId = (RegEax >> 4) & 0xf; + if (FamilyId == 0x06 || FamilyId == 0x0f) { + ModelId = ModelId | ((RegEax >> 12) & 0xf0); + } + + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM) + // Processor Family. + // + // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation + // Intel(R) Core(TM) Processor Family MSRs. + // + if (FamilyId == 0x06) { + if (ModelId == 0x3C || ModelId == 0x45 || ModelId == 0x46 || + ModelId == 0x3D || ModelId == 0x47 || ModelId == 0x4E || ModelId == 0x4F || + ModelId == 0x3F || ModelId == 0x56 || ModelId == 0x57 || ModelId == 0x5C) { + // + // 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 (SMM_FEATURES_LIB_IA32_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) != 0) { + mSmmFeatureControlSupported = TRUE; + } + } + } + + // + // Call internal worker function that completes the CPU initialization + // + FinishSmmCpuFeaturesInitializeProcessor (); +} + +/** + This function updates the SMRAM save state on the currently executing CPU + to resume execution at a specific address after an RSM instruction. This + function must evaluate the SMRAM save state to determine the execution mode + the RSM instruction resumes and update the resume execution address with + either NewInstructionPointer32 or NewInstructionPoint. The auto HALT restart + flag in the SMRAM save state must always be cleared. This function returns + the value of the instruction pointer from the SMRAM save state that was + replaced. If this function returns 0, then the SMRAM save state was not + modified. + + This function is called during the very first SMI on each CPU after + SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode + to signal that the SMBASE of each CPU has been updated before the default + SMBASE address is used for the first SMI to the next CPU. + + @param[in] CpuIndex The index of the CPU to hook. The value + must be between 0 and the NumberOfCpus + field in the System Management System Table + (SMST). + @param[in] CpuState Pointer to SMRAM Save State Map for the + currently executing CPU. + @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to + 32-bit execution mode from 64-bit SMM. + @param[in] NewInstructionPointer Instruction pointer to use if resuming to + same execution mode as SMM. + + @retval 0 This function did modify the SMRAM save state. + @retval > 0 The original instruction pointer value from the SMRAM save state + before it was replaced. +**/ +UINT64 +EFIAPI +SmmCpuFeaturesHookReturnFromSmm ( + IN UINTN CpuIndex, + IN SMRAM_SAVE_STATE_MAP *CpuState, + IN UINT64 NewInstructionPointer32, + IN UINT64 NewInstructionPointer + ) +{ + return 0; +} + +/** + Hook point in normal execution mode that allows the one CPU that was elected + as monarch during System Management Mode initialization to perform additional + initialization actions immediately after all of the CPUs have processed their + first SMI and called SmmCpuFeaturesInitializeProcessor() relocating SMBASE + into a buffer in SMRAM and called SmmCpuFeaturesHookReturnFromSmm(). +**/ +VOID +EFIAPI +SmmCpuFeaturesSmmRelocationComplete ( + VOID + ) +{ +} + +/** + Determines if MTRR registers must be configured to set SMRAM cache-ability + when executing in System Management Mode. + + @retval TRUE MTRR registers must be configured to set SMRAM cache-ability. + @retval FALSE MTRR registers do not need to be configured to set SMRAM + cache-ability. +**/ +BOOLEAN +EFIAPI +SmmCpuFeaturesNeedConfigureMtrrs ( + VOID + ) +{ + return mNeedConfigureMtrrs; +} + +/** + Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs() + returns TRUE. +**/ +VOID +EFIAPI +SmmCpuFeaturesDisableSmrr ( + VOID + ) +{ + if (mSmrrSupported && mNeedConfigureMtrrs) { + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64(mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID); + } +} + +/** + Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs() + returns TRUE. +**/ +VOID +EFIAPI +SmmCpuFeaturesReenableSmrr ( + VOID + ) +{ + if (mSmrrSupported && mNeedConfigureMtrrs) { + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID); + } +} + +/** + Processor specific hook point each time a CPU enters System Management Mode. + + @param[in] CpuIndex The index of the CPU that has entered SMM. The value + must be between 0 and the NumberOfCpus field in the + System Management System Table (SMST). +**/ +VOID +EFIAPI +SmmCpuFeaturesRendezvousEntry ( + IN UINTN CpuIndex + ) +{ + // + // If SMRR is supported and this is the first normal SMI, then enable SMRR + // + if (mSmrrSupported && !mSmrrEnabled[CpuIndex]) { + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID); + mSmrrEnabled[CpuIndex] = TRUE; + } +} + +/** + Processor specific hook point each time a CPU exits System Management Mode. + + @param[in] CpuIndex The index of the CPU that is exiting SMM. The value must + be between 0 and the NumberOfCpus field in the System + Management System Table (SMST). +**/ +VOID +EFIAPI +SmmCpuFeaturesRendezvousExit ( + IN UINTN CpuIndex + ) +{ +} + +/** + Check to see if an SMM register is supported by a specified CPU. + + @param[in] CpuIndex The index of the CPU to check for SMM register support. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to check for support. + + @retval TRUE The SMM register specified by RegName is supported by the CPU + specified by CpuIndex. + @retval FALSE The SMM register specified by RegName is not supported by the + CPU specified by CpuIndex. +**/ +BOOLEAN +EFIAPI +SmmCpuFeaturesIsSmmRegisterSupported ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName + ) +{ + if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) { + return TRUE; + } + return FALSE; +} + +/** + Returns the current value of the SMM register for the specified CPU. + If the SMM register is not supported, then 0 is returned. + + @param[in] CpuIndex The index of the CPU to read the SMM register. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to read. + + @return The value of the SMM register specified by RegName from the CPU + specified by CpuIndex. +**/ +UINT64 +EFIAPI +SmmCpuFeaturesGetSmmRegister ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName + ) +{ + if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) { + return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL); + } + return 0; +} + +/** + Sets the value of an SMM register on a specified CPU. + If the SMM register is not supported, then no action is performed. + + @param[in] CpuIndex The index of the CPU to write the SMM register. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] RegName Identifies the SMM register to write. + registers are read-only. + @param[in] Value The value to write to the SMM register. +**/ +VOID +EFIAPI +SmmCpuFeaturesSetSmmRegister ( + IN UINTN CpuIndex, + IN SMM_REG_NAME RegName, + IN UINT64 Value + ) +{ + if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) { + AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL, Value); + } +} + +/** + Read an SMM Save State register on the target processor. If this function + returns EFI_UNSUPPORTED, then the caller is responsible for reading the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to read the SMM Save State. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to read. + @param[in] Width The number of bytes to read from the CPU save state. + @param[out] 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_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support reading Register. + +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesReadSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + OUT VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Writes an SMM Save State register on the target processor. If this function + returns EFI_UNSUPPORTED, then the caller is responsible for writing the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to write the SMM Save State. The + value must be between 0 and the NumberOfCpus field in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to write. + @param[in] Width The number of bytes to write to the CPU save state. + @param[in] Buffer Upon entry, this holds the new CPU register value. + + @retval EFI_SUCCESS The register was written to Save State. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support writing Register. +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesWriteSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + IN CONST VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function is hook point called after the gEfiSmmReadyToLockProtocolGuid + notification is completely processed. +**/ +VOID +EFIAPI +SmmCpuFeaturesCompleteSmmReadyToLock ( + VOID + ) +{ +} + +/** + This API provides a method for a CPU to allocate a specific region for storing page tables. + + This API can be called more once to allocate memory for page tables. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + This function can also return NULL if there is no preference on where the page tables are allocated in SMRAM. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer for page tables. + @retval NULL Fail to allocate a specific region for storing page tables, + Or there is no preference on where the page tables are allocated in SMRAM. + +**/ +VOID * +EFIAPI +SmmCpuFeaturesAllocatePageTableMemory ( + IN UINTN Pages + ) +{ + return NULL; +} + diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf new file mode 100644 index 000000000..dd828baf6 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf @@ -0,0 +1,34 @@ +## @file +# The CPU specific programming for PiSmmCpuDxeSmm module. +# +# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmCpuFeaturesLib + MODULE_UNI_FILE = SmmCpuFeaturesLib.uni + FILE_GUID = FC3DC10D-D271-422a-AFF3-CBCF70344431 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmCpuFeaturesLib + CONSTRUCTOR = SmmCpuFeaturesLibConstructor + +[Sources] + SmmCpuFeaturesLib.c + SmmCpuFeaturesLibNoStm.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + MemoryAllocationLib + DebugLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni new file mode 100644 index 000000000..6ee54e925 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni @@ -0,0 +1,12 @@ +// /** @file +// The CPU specific programming for PiSmmCpuDxeSmm module. +// +// Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "The CPU specific programming for PiSmmCpuDxeSmm module." + +#string STR_MODULE_DESCRIPTION #language en-US "The CPU specific programming for PiSmmCpuDxeSmm module." diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibNoStm.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibNoStm.c new file mode 100644 index 000000000..3e63c5e27 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibNoStm.c @@ -0,0 +1,83 @@ +/** @file +The CPU specific programming for PiSmmCpuDxeSmm module when STM support +is not included. + +Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + Internal worker function that is called to complete CPU initialization at the + end of SmmCpuFeaturesInitializeProcessor(). + +**/ +VOID +FinishSmmCpuFeaturesInitializeProcessor ( + VOID + ) +{ +} + +/** + Return the size, in bytes, of a custom SMI Handler in bytes. If 0 is + returned, then a custom SMI handler is not provided by this library, + and the default SMI handler must be used. + + @retval 0 Use the default SMI handler. + @retval > 0 Use the SMI handler installed by SmmCpuFeaturesInstallSmiHandler() + The caller is required to allocate enough SMRAM for each CPU to + support the size of the custom SMI handler. +**/ +UINTN +EFIAPI +SmmCpuFeaturesGetSmiHandlerSize ( + VOID + ) +{ + return 0; +} + +/** + Install a custom SMI handler for the CPU specified by CpuIndex. This function + is only called if SmmCpuFeaturesGetSmiHandlerSize() returns a size is greater + than zero and is called by the CPU that was elected as monarch during System + Management Mode initialization. + + @param[in] CpuIndex The index of the CPU to install the custom SMI handler. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. + @param[in] SmiStack The stack to use when an SMI is processed by the + the CPU specified by CpuIndex. + @param[in] StackSize The size, in bytes, if the stack used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtBase The base address of the GDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtBase The base address of the IDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] Cr3 The base address of the page tables to use when an SMI + is processed by the CPU specified by CpuIndex. +**/ +VOID +EFIAPI +SmmCpuFeaturesInstallSmiHandler ( + IN UINTN CpuIndex, + IN UINT32 SmBase, + IN VOID *SmiStack, + IN UINTN StackSize, + IN UINTN GdtBase, + IN UINTN GdtSize, + IN UINTN IdtBase, + IN UINTN IdtSize, + IN UINT32 Cr3 + ) +{ +} diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf new file mode 100644 index 000000000..50b9cc871 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf @@ -0,0 +1,72 @@ +## @file +# The CPU specific programming for PiSmmCpuDxeSmm module when STM support +# is included. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmCpuFeaturesLibStm + MODULE_UNI_FILE = SmmCpuFeaturesLib.uni + FILE_GUID = 374DE830-81C5-4CC8-B2AB-28F0AB73710B + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmCpuFeaturesLib + CONSTRUCTOR = SmmCpuFeaturesLibStmConstructor + +[Sources] + SmmCpuFeaturesLib.c + SmmStm.c + SmmStm.h + +[Sources.Ia32] + Ia32/SmmStmSupport.c + + + Ia32/SmiEntry.nasm + Ia32/SmiException.nasm + +[Sources.X64] + X64/SmmStmSupport.c + + + X64/SmiEntry.nasm + X64/SmiException.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + PcdLib + HobLib + MemoryAllocationLib + DebugLib + UefiBootServicesTableLib + SmmServicesTableLib + TpmMeasurementLib + +[Protocols] + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiSmmEndOfDxeProtocolGuid ## CONSUMES + gEfiSmMonitorInitProtocolGuid ## PRODUCES + +[Guids] + gMsegSmramGuid ## SOMETIMES_CONSUMES ## HOB + gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMsegSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStmExceptionStackSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES + +[Depex] + gEfiMpServiceProtocolGuid diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.c new file mode 100644 index 000000000..f7f8afacf --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.c @@ -0,0 +1,1297 @@ +/** @file + SMM STM support functions + + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "SmmStm.h" + +#define TXT_EVTYPE_BASE 0x400 +#define TXT_EVTYPE_STM_HASH (TXT_EVTYPE_BASE + 14) + +#define RDWR_ACCS 3 +#define FULL_ACCS 7 + +/** + The constructor function + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_HANDLE mStmSmmCpuHandle = NULL; + +BOOLEAN mLockLoadMonitor = FALSE; + +// +// Template of STM_RSC_END structure for copying. +// +GLOBAL_REMOVE_IF_UNREFERENCED STM_RSC_END mRscEndNode = { + {END_OF_RESOURCES, sizeof (STM_RSC_END)}, +}; + +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 *mStmResourcesPtr = NULL; +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mStmResourceTotalSize = 0x0; +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mStmResourceSizeUsed = 0x0; +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mStmResourceSizeAvailable = 0x0; + +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mStmState = 0; + +// +// System Configuration Table pointing to STM Configuration Table +// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_SM_MONITOR_INIT_PROTOCOL mSmMonitorInitProtocol = { + LoadMonitor, + AddPiResource, + DeletePiResource, + GetPiResource, + GetMonitorState, +}; + + + + +#define CPUID1_EDX_XD_SUPPORT 0x100000 + +// +// External global variables associated with SMI Handler Template +// +extern CONST TXT_PROCESSOR_SMM_DESCRIPTOR gcStmPsd; +extern UINT32 gStmSmbase; +extern volatile UINT32 gStmSmiStack; +extern UINT32 gStmSmiCr3; +extern volatile UINT8 gcStmSmiHandlerTemplate[]; +extern CONST UINT16 gcStmSmiHandlerSize; +extern UINT16 gcStmSmiHandlerOffset; +extern BOOLEAN gStmXdSupported; + +// +// Variables used by SMI Handler +// +IA32_DESCRIPTOR gStmSmiHandlerIdtr; + +// +// MP Services Protocol +// +EFI_MP_SERVICES_PROTOCOL *mSmmCpuFeaturesLibMpService = NULL; + +// +// MSEG Base and Length in SMRAM +// +UINTN mMsegBase = 0; +UINTN mMsegSize = 0; + +BOOLEAN mStmConfigurationTableInitialized = FALSE; + +/** + The constructor function + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +SmmCpuFeaturesLibStmConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CPUID_VERSION_INFO_ECX RegEcx; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_SMRAM_DESCRIPTOR *SmramDescriptor; + + // + // Initialize address fixup + // + SmmCpuFeaturesLibStmSmiEntryFixupAddress (); + + // + // Call the common constructor function + // + Status = SmmCpuFeaturesLibConstructor (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + + // + // Lookup the MP Services Protocol + // + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **)&mSmmCpuFeaturesLibMpService + ); + ASSERT_EFI_ERROR (Status); + + // + // If CPU supports VMX, then determine SMRAM range for MSEG. + // + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx.Uint32, NULL); + if (RegEcx.Bits.VMX == 1) { + GuidHob = GetFirstGuidHob (&gMsegSmramGuid); + if (GuidHob != NULL) { + // + // Retrieve MSEG location from MSEG SRAM HOB + // + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); + if (SmramDescriptor->PhysicalSize > 0) { + mMsegBase = (UINTN)SmramDescriptor->CpuStart; + mMsegSize = (UINTN)SmramDescriptor->PhysicalSize; + } + } else if (PcdGet32 (PcdCpuMsegSize) > 0) { + // + // Allocate MSEG from SMRAM memory + // + mMsegBase = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuMsegSize))); + if (mMsegBase > 0) { + mMsegSize = ALIGN_VALUE (PcdGet32 (PcdCpuMsegSize), EFI_PAGE_SIZE); + } else { + DEBUG ((DEBUG_ERROR, "Not enough SMRAM resource to allocate MSEG size %08x\n", PcdGet32 (PcdCpuMsegSize))); + } + } + if (mMsegBase > 0) { + DEBUG ((DEBUG_INFO, "MsegBase: 0x%08x, MsegSize: 0x%08x\n", mMsegBase, mMsegSize)); + } + } + + return EFI_SUCCESS; +} + +/** + Internal worker function that is called to complete CPU initialization at the + end of SmmCpuFeaturesInitializeProcessor(). + +**/ +VOID +FinishSmmCpuFeaturesInitializeProcessor ( + VOID + ) +{ + MSR_IA32_SMM_MONITOR_CTL_REGISTER SmmMonitorCtl; + + // + // Set MSEG Base Address in SMM Monitor Control MSR. + // + if (mMsegBase > 0) { + SmmMonitorCtl.Uint64 = 0; + SmmMonitorCtl.Bits.MsegBase = (UINT32)mMsegBase >> 12; + SmmMonitorCtl.Bits.Valid = 1; + AsmWriteMsr64 (MSR_IA32_SMM_MONITOR_CTL, SmmMonitorCtl.Uint64); + } +} + +/** + Return the size, in bytes, of a custom SMI Handler in bytes. If 0 is + returned, then a custom SMI handler is not provided by this library, + and the default SMI handler must be used. + + @retval 0 Use the default SMI handler. + @retval > 0 Use the SMI handler installed by SmmCpuFeaturesInstallSmiHandler() + The caller is required to allocate enough SMRAM for each CPU to + support the size of the custom SMI handler. +**/ +UINTN +EFIAPI +SmmCpuFeaturesGetSmiHandlerSize ( + VOID + ) +{ + return gcStmSmiHandlerSize; +} + +/** + Install a custom SMI handler for the CPU specified by CpuIndex. This function + is only called if SmmCpuFeaturesGetSmiHandlerSize() returns a size is greater + than zero and is called by the CPU that was elected as monarch during System + Management Mode initialization. + + @param[in] CpuIndex The index of the CPU to install the custom SMI handler. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. + @param[in] SmiStack The stack to use when an SMI is processed by the + the CPU specified by CpuIndex. + @param[in] StackSize The size, in bytes, if the stack used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtBase The base address of the GDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtBase The base address of the IDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] Cr3 The base address of the page tables to use when an SMI + is processed by the CPU specified by CpuIndex. +**/ +VOID +EFIAPI +SmmCpuFeaturesInstallSmiHandler ( + IN UINTN CpuIndex, + IN UINT32 SmBase, + IN VOID *SmiStack, + IN UINTN StackSize, + IN UINTN GdtBase, + IN UINTN GdtSize, + IN UINTN IdtBase, + IN UINTN IdtSize, + IN UINT32 Cr3 + ) +{ + EFI_STATUS Status; + TXT_PROCESSOR_SMM_DESCRIPTOR *Psd; + VOID *Hob; + UINT32 RegEax; + UINT32 RegEdx; + EFI_PROCESSOR_INFORMATION ProcessorInfo; + + CopyMem ((VOID *)((UINTN)SmBase + TXT_SMM_PSD_OFFSET), &gcStmPsd, sizeof (gcStmPsd)); + Psd = (TXT_PROCESSOR_SMM_DESCRIPTOR *)(VOID *)((UINTN)SmBase + TXT_SMM_PSD_OFFSET); + Psd->SmmGdtPtr = GdtBase; + Psd->SmmGdtSize = (UINT32)GdtSize; + + // + // Initialize values in template before copy + // + gStmSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN)); + gStmSmiCr3 = Cr3; + gStmSmbase = SmBase; + gStmSmiHandlerIdtr.Base = IdtBase; + gStmSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1); + + if (gStmXdSupported) { + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax <= CPUID_EXTENDED_FUNCTION) { + // + // Extended CPUID functions are not supported on this processor. + // + gStmXdSupported = FALSE; + } + + 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. + // + gStmXdSupported = FALSE; + } + } + + // + // Set the value at the top of the CPU stack to the CPU Index + // + *(UINTN*)(UINTN)gStmSmiStack = CpuIndex; + + // + // Copy template to CPU specific SMI handler location + // + CopyMem ( + (VOID*)((UINTN)SmBase + SMM_HANDLER_OFFSET), + (VOID*)gcStmSmiHandlerTemplate, + gcStmSmiHandlerSize + ); + + Psd->SmmSmiHandlerRip = SmBase + SMM_HANDLER_OFFSET + gcStmSmiHandlerOffset; + Psd->SmmSmiHandlerRsp = (UINTN)SmiStack + StackSize - sizeof(UINTN); + Psd->SmmCr3 = Cr3; + + DEBUG((DEBUG_INFO, "CpuSmmStmExceptionStackSize - %x\n", PcdGet32(PcdCpuSmmStmExceptionStackSize))); + DEBUG((DEBUG_INFO, "Pages - %x\n", EFI_SIZE_TO_PAGES(PcdGet32(PcdCpuSmmStmExceptionStackSize)))); + Psd->StmProtectionExceptionHandler.SpeRsp = (UINT64)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStmExceptionStackSize))); + Psd->StmProtectionExceptionHandler.SpeRsp += EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStmExceptionStackSize))); + + Psd->BiosHwResourceRequirementsPtr = (UINT64)(UINTN)GetStmResource (); + + // + // Get the APIC ID for the CPU specified by CpuIndex + // + Status = mSmmCpuFeaturesLibMpService->GetProcessorInfo ( + mSmmCpuFeaturesLibMpService, + CpuIndex, + &ProcessorInfo + ); + ASSERT_EFI_ERROR (Status); + + Psd->LocalApicId = (UINT32)ProcessorInfo.ProcessorId; + Psd->AcpiRsdp = 0; + + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + Psd->PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + Psd->PhysicalAddressBits = (UINT8) RegEax; + } else { + Psd->PhysicalAddressBits = 36; + } + } + + if (!mStmConfigurationTableInitialized) { + StmSmmConfigurationTableInit (); + mStmConfigurationTableInitialized = TRUE; + } +} + +/** + SMM End Of Dxe event notification handler. + + STM support need patch AcpiRsdp in TXT_PROCESSOR_SMM_DESCRIPTOR. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. +**/ +EFI_STATUS +EFIAPI +SmmEndOfDxeEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + VOID *Rsdp; + UINTN Index; + TXT_PROCESSOR_SMM_DESCRIPTOR *Psd; + + DEBUG ((DEBUG_INFO, "SmmEndOfDxeEventNotify\n")); + + // + // found ACPI table RSD_PTR from system table + // + Rsdp = NULL; + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid)) { + // + // A match was found. + // + Rsdp = gST->ConfigurationTable[Index].VendorTable; + break; + } + } + if (Rsdp == NULL) { + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid)) { + // + // A match was found. + // + Rsdp = gST->ConfigurationTable[Index].VendorTable; + break; + } + } + } + + for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + Psd = (TXT_PROCESSOR_SMM_DESCRIPTOR *)((UINTN)gSmst->CpuSaveState[Index] - SMRAM_SAVE_STATE_MAP_OFFSET + TXT_SMM_PSD_OFFSET); + DEBUG ((DEBUG_INFO, "Index=%d Psd=%p Rsdp=%p\n", Index, Psd, Rsdp)); + Psd->AcpiRsdp = (UINT64)(UINTN)Rsdp; + } + + mLockLoadMonitor = TRUE; + + return EFI_SUCCESS; +} + +/** + This function initializes the STM configuration table. +**/ +VOID +StmSmmConfigurationTableInit ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Registration; + + Status = gSmst->SmmInstallProtocolInterface ( + &mStmSmmCpuHandle, + &gEfiSmMonitorInitProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmMonitorInitProtocol + ); + ASSERT_EFI_ERROR (Status); + + // + // + // Register SMM End of DXE Event + // + Status = gSmst->SmmRegisterProtocolNotify ( + &gEfiSmmEndOfDxeProtocolGuid, + SmmEndOfDxeEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); +} + +/** + + Get STM state. + + @return STM state + +**/ +EFI_SM_MONITOR_STATE +EFIAPI +GetMonitorState ( + VOID + ) +{ + return mStmState; +} + +/** + + Handle single Resource to see if it can be merged into Record. + + @param Resource A pointer to resource node to be added + @param Record A pointer to record node to be merged + + @retval TRUE resource handled + @retval FALSE resource is not handled + +**/ +BOOLEAN +HandleSingleResource ( + IN STM_RSC *Resource, + IN STM_RSC *Record + ) +{ + UINT64 ResourceLo; + UINT64 ResourceHi; + UINT64 RecordLo; + UINT64 RecordHi; + + ResourceLo = 0; + ResourceHi = 0; + RecordLo = 0; + RecordHi = 0; + + // + // Calling code is responsible for making sure that + // Resource->Header.RscType == (*Record)->Header.RscType + // thus we use just one of them as switch variable. + // + switch (Resource->Header.RscType) { + case MEM_RANGE: + case MMIO_RANGE: + ResourceLo = Resource->Mem.Base; + ResourceHi = Resource->Mem.Base + Resource->Mem.Length; + RecordLo = Record->Mem.Base; + RecordHi = Record->Mem.Base + Record->Mem.Length; + if (Resource->Mem.RWXAttributes != Record->Mem.RWXAttributes) { + if ((ResourceLo == RecordLo) && (ResourceHi == RecordHi)) { + Record->Mem.RWXAttributes = Resource->Mem.RWXAttributes | Record->Mem.RWXAttributes; + return TRUE; + } else { + return FALSE; + } + } + break; + case IO_RANGE: + case TRAPPED_IO_RANGE: + ResourceLo = (UINT64) Resource->Io.Base; + ResourceHi = (UINT64) Resource->Io.Base + (UINT64) Resource->Io.Length; + RecordLo = (UINT64) Record->Io.Base; + RecordHi = (UINT64) Record->Io.Base + (UINT64) Record->Io.Length; + break; + case PCI_CFG_RANGE: + if ((Resource->PciCfg.OriginatingBusNumber != Record->PciCfg.OriginatingBusNumber) || + (Resource->PciCfg.LastNodeIndex != Record->PciCfg.LastNodeIndex)) { + return FALSE; + } + if (CompareMem (Resource->PciCfg.PciDevicePath, Record->PciCfg.PciDevicePath, sizeof(STM_PCI_DEVICE_PATH_NODE) * (Resource->PciCfg.LastNodeIndex + 1)) != 0) { + return FALSE; + } + ResourceLo = (UINT64) Resource->PciCfg.Base; + ResourceHi = (UINT64) Resource->PciCfg.Base + (UINT64) Resource->PciCfg.Length; + RecordLo = (UINT64) Record->PciCfg.Base; + RecordHi = (UINT64) Record->PciCfg.Base + (UINT64) Record->PciCfg.Length; + if (Resource->PciCfg.RWAttributes != Record->PciCfg.RWAttributes) { + if ((ResourceLo == RecordLo) && (ResourceHi == RecordHi)) { + Record->PciCfg.RWAttributes = Resource->PciCfg.RWAttributes | Record->PciCfg.RWAttributes; + return TRUE; + } else { + return FALSE; + } + } + break; + case MACHINE_SPECIFIC_REG: + // + // Special case - merge MSR masks in place. + // + if (Resource->Msr.MsrIndex != Record->Msr.MsrIndex) { + return FALSE; + } + Record->Msr.ReadMask |= Resource->Msr.ReadMask; + Record->Msr.WriteMask |= Resource->Msr.WriteMask; + return TRUE; + default: + return FALSE; + } + // + // If resources are disjoint + // + if ((ResourceHi < RecordLo) || (ResourceLo > RecordHi)) { + return FALSE; + } + + // + // If resource is consumed by record. + // + if ((ResourceLo >= RecordLo) && (ResourceHi <= RecordHi)) { + return TRUE; + } + // + // Resources are overlapping. + // Resource and record are merged. + // + ResourceLo = (ResourceLo < RecordLo) ? ResourceLo : RecordLo; + ResourceHi = (ResourceHi > RecordHi) ? ResourceHi : RecordHi; + + switch (Resource->Header.RscType) { + case MEM_RANGE: + case MMIO_RANGE: + Record->Mem.Base = ResourceLo; + Record->Mem.Length = ResourceHi - ResourceLo; + break; + case IO_RANGE: + case TRAPPED_IO_RANGE: + Record->Io.Base = (UINT16) ResourceLo; + Record->Io.Length = (UINT16) (ResourceHi - ResourceLo); + break; + case PCI_CFG_RANGE: + Record->PciCfg.Base = (UINT16) ResourceLo; + Record->PciCfg.Length = (UINT16) (ResourceHi - ResourceLo); + break; + default: + return FALSE; + } + + return TRUE; +} + +/** + + Add resource node. + + @param Resource A pointer to resource node to be added + +**/ +VOID +AddSingleResource ( + IN STM_RSC *Resource + ) +{ + STM_RSC *Record; + + Record = (STM_RSC *)mStmResourcesPtr; + + while (TRUE) { + if (Record->Header.RscType == END_OF_RESOURCES) { + break; + } + // + // Go to next record if resource and record types don't match. + // + if (Resource->Header.RscType != Record->Header.RscType) { + Record = (STM_RSC *)((UINTN)Record + Record->Header.Length); + continue; + } + // + // Record is handled inside of procedure - don't adjust. + // + if (HandleSingleResource (Resource, Record)) { + return ; + } + Record = (STM_RSC *)((UINTN)Record + Record->Header.Length); + } + + // + // Add resource to the end of area. + // + CopyMem ( + mStmResourcesPtr + mStmResourceSizeUsed - sizeof(mRscEndNode), + Resource, + Resource->Header.Length + ); + CopyMem ( + mStmResourcesPtr + mStmResourceSizeUsed - sizeof(mRscEndNode) + Resource->Header.Length, + &mRscEndNode, + sizeof(mRscEndNode) + ); + mStmResourceSizeUsed += Resource->Header.Length; + mStmResourceSizeAvailable = mStmResourceTotalSize - mStmResourceSizeUsed; + + return ; +} + +/** + + Add resource list. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + +**/ +VOID +AddResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ) +{ + UINT32 Count; + UINTN Index; + STM_RSC *Resource; + + if (NumEntries == 0) { + Count = 0xFFFFFFFF; + } else { + Count = NumEntries; + } + + Resource = ResourceList; + + for (Index = 0; Index < Count; Index++) { + if (Resource->Header.RscType == END_OF_RESOURCES) { + return ; + } + AddSingleResource (Resource); + Resource = (STM_RSC *)((UINTN)Resource + Resource->Header.Length); + } + return ; +} + +/** + + Validate resource list. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval TRUE resource valid + @retval FALSE resource invalid + +**/ +BOOLEAN +ValidateResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ) +{ + UINT32 Count; + UINTN Index; + STM_RSC *Resource; + UINTN SubIndex; + + // + // If NumEntries == 0 make it very big. Scan will be terminated by + // END_OF_RESOURCES. + // + if (NumEntries == 0) { + Count = 0xFFFFFFFF; + } else { + Count = NumEntries; + } + + // + // Start from beginning of resource list. + // + Resource = ResourceList; + + for (Index = 0; Index < Count; Index++) { + DEBUG ((DEBUG_INFO, "ValidateResource (%d) - RscType(%x)\n", Index, Resource->Header.RscType)); + // + // Validate resource. + // + switch (Resource->Header.RscType) { + case END_OF_RESOURCES: + if (Resource->Header.Length != sizeof (STM_RSC_END)) { + return FALSE; + } + // + // If we are passed actual number of resources to add, + // END_OF_RESOURCES structure between them is considered an + // error. If NumEntries == 0 END_OF_RESOURCES is a termination. + // + if (NumEntries != 0) { + return FALSE; + } else { + // + // If NumEntries == 0 and list reached end - return success. + // + return TRUE; + } + break; + + case MEM_RANGE: + case MMIO_RANGE: + if (Resource->Header.Length != sizeof (STM_RSC_MEM_DESC)) { + return FALSE; + } + + if (Resource->Mem.RWXAttributes > FULL_ACCS) { + return FALSE; + } + break; + + case IO_RANGE: + case TRAPPED_IO_RANGE: + if (Resource->Header.Length != sizeof (STM_RSC_IO_DESC)) { + return FALSE; + } + + if ((Resource->Io.Base + Resource->Io.Length) > 0xFFFF) { + return FALSE; + } + break; + + case PCI_CFG_RANGE: + DEBUG ((DEBUG_INFO, "ValidateResource - PCI (0x%02x, 0x%08x, 0x%02x, 0x%02x)\n", Resource->PciCfg.OriginatingBusNumber, Resource->PciCfg.LastNodeIndex, Resource->PciCfg.PciDevicePath[0].PciDevice, Resource->PciCfg.PciDevicePath[0].PciFunction)); + if (Resource->Header.Length != sizeof (STM_RSC_PCI_CFG_DESC) + (sizeof(STM_PCI_DEVICE_PATH_NODE) * Resource->PciCfg.LastNodeIndex)) { + return FALSE; + } + for (SubIndex = 0; SubIndex <= Resource->PciCfg.LastNodeIndex; SubIndex++) { + if ((Resource->PciCfg.PciDevicePath[SubIndex].PciDevice > 0x1F) || (Resource->PciCfg.PciDevicePath[SubIndex].PciFunction > 7)) { + return FALSE; + } + } + if ((Resource->PciCfg.Base + Resource->PciCfg.Length) > 0x1000) { + return FALSE; + } + break; + + case MACHINE_SPECIFIC_REG: + if (Resource->Header.Length != sizeof (STM_RSC_MSR_DESC)) { + return FALSE; + } + break; + + default : + DEBUG ((DEBUG_ERROR, "ValidateResource - Unknown RscType(%x)\n", Resource->Header.RscType)); + return FALSE; + } + Resource = (STM_RSC *)((UINTN)Resource + Resource->Header.Length); + } + return TRUE; +} + +/** + + Get resource list. + EndResource is excluded. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval TRUE resource valid + @retval FALSE resource invalid + +**/ +UINTN +GetResourceSize ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ) +{ + UINT32 Count; + UINTN Index; + STM_RSC *Resource; + + Resource = ResourceList; + + // + // If NumEntries == 0 make it very big. Scan will be terminated by + // END_OF_RESOURCES. + // + if (NumEntries == 0) { + Count = 0xFFFFFFFF; + } else { + Count = NumEntries; + } + + // + // Start from beginning of resource list. + // + Resource = ResourceList; + + for (Index = 0; Index < Count; Index++) { + if (Resource->Header.RscType == END_OF_RESOURCES) { + break; + } + Resource = (STM_RSC *)((UINTN)Resource + Resource->Header.Length); + } + + return (UINTN)Resource - (UINTN)ResourceList; +} + +/** + + Add resources in list to database. Allocate new memory areas as needed. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are added + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + @retval EFI_OUT_OF_RESOURCES If nested procedure returned it and we cannot allocate more areas. + +**/ +EFI_STATUS +EFIAPI +AddPiResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN ResourceSize; + EFI_PHYSICAL_ADDRESS NewResource; + UINTN NewResourceSize; + + DEBUG ((DEBUG_INFO, "AddPiResource - Enter\n")); + + if (!ValidateResource (ResourceList, NumEntries)) { + return EFI_INVALID_PARAMETER; + } + + ResourceSize = GetResourceSize (ResourceList, NumEntries); + DEBUG ((DEBUG_INFO, "ResourceSize - 0x%08x\n", ResourceSize)); + if (ResourceSize == 0) { + return EFI_INVALID_PARAMETER; + } + + if (mStmResourcesPtr == NULL) { + // + // First time allocation + // + NewResourceSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (ResourceSize + sizeof(mRscEndNode))); + DEBUG ((DEBUG_INFO, "Allocate - 0x%08x\n", NewResourceSize)); + Status = gSmst->SmmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (NewResourceSize), + &NewResource + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Copy EndResource for initialization + // + mStmResourcesPtr = (UINT8 *)(UINTN)NewResource; + mStmResourceTotalSize = NewResourceSize; + CopyMem (mStmResourcesPtr, &mRscEndNode, sizeof(mRscEndNode)); + mStmResourceSizeUsed = sizeof(mRscEndNode); + mStmResourceSizeAvailable = mStmResourceTotalSize - sizeof(mRscEndNode); + + // + // Let SmmCore change resource ptr + // + NotifyStmResourceChange (mStmResourcesPtr); + } else if (mStmResourceSizeAvailable < ResourceSize) { + // + // Need enlarge + // + NewResourceSize = mStmResourceTotalSize + (ResourceSize - mStmResourceSizeAvailable); + NewResourceSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (NewResourceSize)); + DEBUG ((DEBUG_INFO, "ReAllocate - 0x%08x\n", NewResourceSize)); + Status = gSmst->SmmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (NewResourceSize), + &NewResource + ); + if (EFI_ERROR (Status)) { + return Status; + } + CopyMem ((VOID *)(UINTN)NewResource, mStmResourcesPtr, mStmResourceSizeUsed); + mStmResourceSizeAvailable = NewResourceSize - mStmResourceSizeUsed; + + gSmst->SmmFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)mStmResourcesPtr, + EFI_SIZE_TO_PAGES (mStmResourceTotalSize) + ); + + mStmResourceTotalSize = NewResourceSize; + mStmResourcesPtr = (UINT8 *)(UINTN)NewResource; + + // + // Let SmmCore change resource ptr + // + NotifyStmResourceChange (mStmResourcesPtr); + } + + // + // Check duplication + // + AddResource (ResourceList, NumEntries); + + return EFI_SUCCESS; +} + +/** + + Delete resources in list to database. + + @param ResourceList A pointer to resource list to be deleted + NULL means delete all resources. + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are deleted + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + +**/ +EFI_STATUS +EFIAPI +DeletePiResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ) +{ + if (ResourceList != NULL) { + // TBD + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + // + // Delete all + // + CopyMem (mStmResourcesPtr, &mRscEndNode, sizeof(mRscEndNode)); + mStmResourceSizeUsed = sizeof(mRscEndNode); + mStmResourceSizeAvailable = mStmResourceTotalSize - sizeof(mRscEndNode); + return EFI_SUCCESS; +} + +/** + + Get BIOS resources. + + @param ResourceList A pointer to resource list to be filled + @param ResourceSize On input it means size of resource list input. + On output it means size of resource list filled, + or the size of resource list to be filled if size of too small. + + @retval EFI_SUCCESS If resources are returned. + @retval EFI_BUFFER_TOO_SMALL If resource list buffer is too small to hold the whole resources. + +**/ +EFI_STATUS +EFIAPI +GetPiResource ( + OUT STM_RSC *ResourceList, + IN OUT UINT32 *ResourceSize + ) +{ + if (*ResourceSize < mStmResourceSizeUsed) { + *ResourceSize = (UINT32)mStmResourceSizeUsed; + return EFI_BUFFER_TOO_SMALL; + } + + CopyMem (ResourceList, mStmResourcesPtr, mStmResourceSizeUsed); + *ResourceSize = (UINT32)mStmResourceSizeUsed; + return EFI_SUCCESS; +} + +/** + + Set valid bit for MSEG MSR. + + @param Buffer Ap function buffer. (not used) + +**/ +VOID +EFIAPI +EnableMsegMsr ( + IN VOID *Buffer + ) +{ + MSR_IA32_SMM_MONITOR_CTL_REGISTER SmmMonitorCtl; + + SmmMonitorCtl.Uint64 = AsmReadMsr64 (MSR_IA32_SMM_MONITOR_CTL); + SmmMonitorCtl.Bits.Valid = 1; + AsmWriteMsr64 (MSR_IA32_SMM_MONITOR_CTL, SmmMonitorCtl.Uint64); +} + +/** + + Get 4K page aligned VMCS size. + + @return 4K page aligned VMCS size + +**/ +UINT32 +GetVmcsSize ( + VOID + ) +{ + MSR_IA32_VMX_BASIC_REGISTER VmxBasic; + + // + // Read VMCS size and and align to 4KB + // + VmxBasic.Uint64 = AsmReadMsr64 (MSR_IA32_VMX_BASIC); + return ALIGN_VALUE (VmxBasic.Bits.VmcsSize, SIZE_4KB); +} + +/** + + Check STM image size. + + @param StmImage STM image + @param StmImageSize STM image size + + @retval TRUE check pass + @retval FALSE check fail +**/ +BOOLEAN +StmCheckStmImage ( + IN EFI_PHYSICAL_ADDRESS StmImage, + IN UINTN StmImageSize + ) +{ + UINTN MinMsegSize; + STM_HEADER *StmHeader; + IA32_VMX_MISC_REGISTER VmxMiscMsr; + + // + // Check to see if STM image is compatible with CPU + // + StmHeader = (STM_HEADER *)(UINTN)StmImage; + VmxMiscMsr.Uint64 = AsmReadMsr64 (MSR_IA32_VMX_MISC); + if (StmHeader->HwStmHdr.MsegHeaderRevision != VmxMiscMsr.Bits.MsegRevisionIdentifier) { + DEBUG ((DEBUG_ERROR, "STM Image not compatible with CPU\n")); + DEBUG ((DEBUG_ERROR, " StmHeader->HwStmHdr.MsegHeaderRevision = %08x\n", StmHeader->HwStmHdr.MsegHeaderRevision)); + DEBUG ((DEBUG_ERROR, " VmxMiscMsr.Bits.MsegRevisionIdentifier = %08x\n", VmxMiscMsr.Bits.MsegRevisionIdentifier)); + return FALSE; + } + + // + // Get Minimal required Mseg size + // + MinMsegSize = (EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (StmHeader->SwStmHdr.StaticImageSize)) + + StmHeader->SwStmHdr.AdditionalDynamicMemorySize + + (StmHeader->SwStmHdr.PerProcDynamicMemorySize + GetVmcsSize () * 2) * gSmst->NumberOfCpus); + if (MinMsegSize < StmImageSize) { + MinMsegSize = StmImageSize; + } + + if (StmHeader->HwStmHdr.Cr3Offset >= StmHeader->SwStmHdr.StaticImageSize) { + // + // We will create page table, just in case that SINIT does not create it. + // + if (MinMsegSize < StmHeader->HwStmHdr.Cr3Offset + EFI_PAGES_TO_SIZE(6)) { + MinMsegSize = StmHeader->HwStmHdr.Cr3Offset + EFI_PAGES_TO_SIZE(6); + } + } + + // + // Check if it exceeds MSEG size + // + if (MinMsegSize > mMsegSize) { + DEBUG ((DEBUG_ERROR, "MSEG too small. Min MSEG Size = %08x Current MSEG Size = %08x\n", MinMsegSize, mMsegSize)); + DEBUG ((DEBUG_ERROR, " StmHeader->SwStmHdr.StaticImageSize = %08x\n", StmHeader->SwStmHdr.StaticImageSize)); + DEBUG ((DEBUG_ERROR, " StmHeader->SwStmHdr.AdditionalDynamicMemorySize = %08x\n", StmHeader->SwStmHdr.AdditionalDynamicMemorySize)); + DEBUG ((DEBUG_ERROR, " StmHeader->SwStmHdr.PerProcDynamicMemorySize = %08x\n", StmHeader->SwStmHdr.PerProcDynamicMemorySize)); + DEBUG ((DEBUG_ERROR, " VMCS Size = %08x\n", GetVmcsSize ())); + DEBUG ((DEBUG_ERROR, " Max CPUs = %08x\n", gSmst->NumberOfCpus)); + DEBUG ((DEBUG_ERROR, " StmHeader->HwStmHdr.Cr3Offset = %08x\n", StmHeader->HwStmHdr.Cr3Offset)); + return FALSE; + } + + return TRUE; +} + +/** + + Load STM image to MSEG. + + @param StmImage STM image + @param StmImageSize STM image size + +**/ +VOID +StmLoadStmImage ( + IN EFI_PHYSICAL_ADDRESS StmImage, + IN UINTN StmImageSize + ) +{ + MSR_IA32_SMM_MONITOR_CTL_REGISTER SmmMonitorCtl; + UINT32 MsegBase; + STM_HEADER *StmHeader; + + // + // Get MSEG base address from MSR_IA32_SMM_MONITOR_CTL + // + SmmMonitorCtl.Uint64 = AsmReadMsr64 (MSR_IA32_SMM_MONITOR_CTL); + MsegBase = SmmMonitorCtl.Bits.MsegBase << 12; + + // + // Zero all of MSEG base address + // + ZeroMem ((VOID *)(UINTN)MsegBase, mMsegSize); + + // + // Copy STM Image into MSEG + // + CopyMem ((VOID *)(UINTN)MsegBase, (VOID *)(UINTN)StmImage, StmImageSize); + + // + // STM Header is at the beginning of the STM Image + // + StmHeader = (STM_HEADER *)(UINTN)StmImage; + + StmGen4GPageTable ((UINTN)MsegBase + StmHeader->HwStmHdr.Cr3Offset); +} + +/** + + Load STM image to MSEG. + + @param StmImage STM image + @param StmImageSize STM image size + + @retval EFI_SUCCESS Load STM to MSEG successfully + @retval EFI_ALREADY_STARTED STM image is already loaded to MSEG + @retval EFI_BUFFER_TOO_SMALL MSEG is smaller than minimal requirement of STM image + @retval EFI_UNSUPPORTED MSEG is not enabled + +**/ +EFI_STATUS +EFIAPI +LoadMonitor ( + IN EFI_PHYSICAL_ADDRESS StmImage, + IN UINTN StmImageSize + ) +{ + MSR_IA32_SMM_MONITOR_CTL_REGISTER SmmMonitorCtl; + + if (mLockLoadMonitor) { + return EFI_ACCESS_DENIED; + } + + SmmMonitorCtl.Uint64 = AsmReadMsr64 (MSR_IA32_SMM_MONITOR_CTL); + if (SmmMonitorCtl.Bits.MsegBase == 0) { + return EFI_UNSUPPORTED; + } + + if (!StmCheckStmImage (StmImage, StmImageSize)) { + return EFI_BUFFER_TOO_SMALL; + } + + // Record STM_HASH to PCR 0, just in case it is NOT TXT launch, we still need provide the evidence. + TpmMeasureAndLogData( + 0, // PcrIndex + TXT_EVTYPE_STM_HASH, // EventType + NULL, // EventLog + 0, // LogLen + (VOID *)(UINTN)StmImage, // HashData + StmImageSize // HashDataLen + ); + + StmLoadStmImage (StmImage, StmImageSize); + + mStmState |= EFI_SM_MONITOR_STATE_ENABLED; + + return EFI_SUCCESS; +} + +/** + This function return BIOS STM resource. + Produced by SmmStm. + Consumed by SmmMpService when Init. + + @return BIOS STM resource + +**/ +VOID * +GetStmResource( + VOID + ) +{ + return mStmResourcesPtr; +} + +/** + This function notify STM resource change. + + @param StmResource BIOS STM resource + +**/ +VOID +NotifyStmResourceChange ( + VOID *StmResource + ) +{ + UINTN Index; + TXT_PROCESSOR_SMM_DESCRIPTOR *Psd; + + for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + Psd = (TXT_PROCESSOR_SMM_DESCRIPTOR *)((UINTN)gSmst->CpuSaveState[Index] - SMRAM_SAVE_STATE_MAP_OFFSET + TXT_SMM_PSD_OFFSET); + Psd->BiosHwResourceRequirementsPtr = (UINT64)(UINTN)StmResource; + } + return ; +} + + +/** + This is STM setup BIOS callback. +**/ +VOID +EFIAPI +SmmStmSetup ( + VOID + ) +{ + mStmState |= EFI_SM_MONITOR_STATE_ACTIVATED; +} + +/** + This is STM teardown BIOS callback. +**/ +VOID +EFIAPI +SmmStmTeardown ( + VOID + ) +{ + mStmState &= ~EFI_SM_MONITOR_STATE_ACTIVATED; +} + diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.h b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.h new file mode 100644 index 000000000..da551cc4a --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmStm.h @@ -0,0 +1,179 @@ +/** @file + SMM STM support + + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_STM_H_ +#define _SMM_STM_H_ + +#include + +/** + + Create 4G page table for STM. + 2M PAE page table in X64 version. + + @param PageTableBase The page table base in MSEG + +**/ +VOID +StmGen4GPageTable ( + IN UINTN PageTableBase + ); + +/** + This is SMM exception handle. + Consumed by STM when exception happen. + + @param Context STM protection exception stack frame + + @return the EBX value for STM reference. + EBX = 0: resume SMM guest using register state found on exception stack. + EBX = 1 to 0x0F: EBX contains a BIOS error code which the STM must record in the + TXT.ERRORCODE register and subsequently reset the system via + TXT.CMD.SYS_RESET. The value of the TXT.ERRORCODE register is calculated as + follows: TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC + EBX = 0x10 to 0xFFFFFFFF - reserved, do not use. + +**/ +UINT32 +EFIAPI +SmmStmExceptionHandler ( + IN OUT STM_PROTECTION_EXCEPTION_STACK_FRAME Context + ); + + +/** + + Get STM state. + + @return STM state + +**/ +EFI_SM_MONITOR_STATE +EFIAPI +GetMonitorState ( + VOID + ); + +/** + + Load STM image to MSEG. + + @param StmImage STM image + @param StmImageSize STM image size + + @retval EFI_SUCCESS Load STM to MSEG successfully + @retval EFI_BUFFER_TOO_SMALL MSEG is smaller than minimal requirement of STM image + +**/ +EFI_STATUS +EFIAPI +LoadMonitor ( + IN EFI_PHYSICAL_ADDRESS StmImage, + IN UINTN StmImageSize + ); + +/** + + Add resources in list to database. Allocate new memory areas as needed. + + @param ResourceList A pointer to resource list to be added + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are added + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + @retval EFI_OUT_OF_RESOURCES If nested procedure returned it and we cannot allocate more areas. + +**/ +EFI_STATUS +EFIAPI +AddPiResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ); + +/** + + Delete resources in list to database. + + @param ResourceList A pointer to resource list to be deleted + NULL means delete all resources. + @param NumEntries Optional number of entries. + If 0, list must be terminated by END_OF_RESOURCES. + + @retval EFI_SUCCESS If resources are deleted + @retval EFI_INVALID_PARAMETER If nested procedure detected resource failer + +**/ +EFI_STATUS +EFIAPI +DeletePiResource ( + IN STM_RSC *ResourceList, + IN UINT32 NumEntries OPTIONAL + ); + +/** + + Get BIOS resources. + + @param ResourceList A pointer to resource list to be filled + @param ResourceSize On input it means size of resource list input. + On output it means size of resource list filled, + or the size of resource list to be filled if size of too small. + + @retval EFI_SUCCESS If resources are returned. + @retval EFI_BUFFER_TOO_SMALL If resource list buffer is too small to hold the whole resources. + +**/ +EFI_STATUS +EFIAPI +GetPiResource ( + OUT STM_RSC *ResourceList, + IN OUT UINT32 *ResourceSize + ); + +/** + This function initialize STM configuration table. +**/ +VOID +StmSmmConfigurationTableInit ( + VOID + ); + +/** + This function notify STM resource change. + + @param StmResource BIOS STM resource + +**/ +VOID +NotifyStmResourceChange ( + IN VOID *StmResource + ); + +/** + This function return BIOS STM resource. + + @return BIOS STM resource + +**/ +VOID * +GetStmResource ( + VOID + ); + +/** + This function fixes up the address of the global variable or function + referred in SmiEntry assembly files to be the absolute address. +**/ +VOID +EFIAPI +SmmCpuFeaturesLibStmSmiEntryFixupAddress ( + ); + +#endif diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiEntry.nasm b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiEntry.nasm new file mode 100644 index 000000000..f09d8df1e --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiEntry.nasm @@ -0,0 +1,276 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiEntry.nasm +; +; Abstract: +; +; Code template of the SMI handler for a particular processor +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +; +; Variables referenced by C code +; + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +; +; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR +; +%define DSC_OFFSET 0xfb00 +%define DSC_GDTPTR 0x48 +%define DSC_GDTSIZ 0x50 +%define DSC_CS 0x14 +%define DSC_DS 0x16 +%define DSC_SS 0x18 +%define DSC_OTHERSEG 0x1a +; +; Constants relating to CPU State Save Area +; +%define SSM_DR6 0xffd0 +%define SSM_DR7 0xffc8 + +%define PROTECT_MODE_CS 0x8 +%define PROTECT_MODE_DS 0x20 +%define LONG_MODE_CS 0x38 +%define TSS_SEGMENT 0x40 +%define GDT_SIZE 0x50 + +extern ASM_PFX(SmiRendezvous) +extern ASM_PFX(gStmSmiHandlerIdtr) +extern ASM_PFX(CpuSmmDebugEntry) +extern ASM_PFX(CpuSmmDebugExit) + +global ASM_PFX(gStmSmbase) +global ASM_PFX(gStmXdSupported) +global ASM_PFX(gStmSmiStack) +global ASM_PFX(gStmSmiCr3) +global ASM_PFX(gcStmSmiHandlerTemplate) +global ASM_PFX(gcStmSmiHandlerSize) +global ASM_PFX(gcStmSmiHandlerOffset) + +ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4 +ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4 +ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4 +ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1 + + DEFAULT REL + SECTION .text + +BITS 16 +ASM_PFX(gcStmSmiHandlerTemplate): +_StmSmiEntryPoint: + mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000 + mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ] + dec ax + mov [cs:bx], ax + mov eax, [cs:DSC_OFFSET + DSC_GDTPTR] + mov [cs:bx + 2], eax +o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx] + mov ax, PROTECT_MODE_CS + mov [cs:bx-0x2],ax +o32 mov edi, strict dword 0 +StmSmbasePatch: + lea eax, [edi + (@ProtectedMode - _StmSmiEntryPoint) + 0x8000] + mov [cs:bx-0x6],eax + mov ebx, cr0 + and ebx, 0x9ffafff3 + or ebx, 0x23 + mov cr0, ebx + jmp dword 0x0:0x0 +_StmGdtDesc: + DW 0 + DD 0 + +BITS 32 +@ProtectedMode: + mov ax, PROTECT_MODE_DS +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax + mov esp, strict dword 0 +StmSmiStackPatch: + jmp ProtFlatMode + +BITS 64 +ProtFlatMode: + mov eax, strict dword 0 +StmSmiCr3Patch: + mov cr3, rax + mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3 + mov cr4, rax ; in PreModifyMtrrs() to flush TLB. +; Load TSS + sub esp, 8 ; reserve room in stack + sgdt [rsp] + mov eax, [rsp + 2] ; eax = GDT base + add esp, 8 + mov dl, 0x89 + mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag + mov eax, TSS_SEGMENT + ltr ax + +; enable NXE if supported + mov al, strict byte 1 +StmXdSupportedPatch: + cmp al, 0 + jz @SkipXd +; +; Check XD disable bit +; + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + sub esp, 4 + push rdx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .0 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.0: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr + jmp @XdDone +@SkipXd: + sub esp, 8 +@XdDone: + +; Switch into @LongMode + push LONG_MODE_CS ; push cs hardcore here + call Base ; push return address for retf later +Base: + add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg + + mov ecx, MSR_EFER + rdmsr + or ah, 1 ; enable LME + wrmsr + mov rbx, cr0 + or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, rbx + retf +@LongMode: ; long mode (64-bit code) starts here + mov rax, strict qword 0 ; mov rax, ASM_PFX(gStmSmiHandlerIdtr) +StmSmiEntrySmiHandlerIdtrAbsAddr: + lidt [rax] + lea ebx, [rdi + DSC_OFFSET] + mov ax, [rbx + DSC_DS] + mov ds, eax + mov ax, [rbx + DSC_OTHERSEG] + mov es, eax + mov fs, eax + mov gs, eax + mov ax, [rbx + DSC_SS] + mov ss, eax + mov rax, strict qword 0 ; mov rax, CommonHandler +StmSmiEntryCommonHandlerAbsAddr: + jmp rax +CommonHandler: + mov rbx, [rsp + 0x08] ; rbx <- CpuIndex + + ; + ; Save FP registers + ; + sub rsp, 0x200 + fxsave64 [rsp] + + add rsp, -0x20 + + mov rcx, rbx + call ASM_PFX(CpuSmmDebugEntry) + + mov rcx, rbx + call ASM_PFX(SmiRendezvous) + + mov rcx, rbx + call ASM_PFX(CpuSmmDebugExit) + + add rsp, 0x20 + + ; + ; Restore FP registers + ; + fxrstor64 [rsp] + + add rsp, 0x200 + + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz .1 + pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .1 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.1: + StuffRsb64 + rsm + +_StmSmiHandler: +; +; Check XD disable bit +; + xor r8, r8 + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz @StmXdDone + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov r8, rdx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .0 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.0: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone: + push r8 + + ; below step is needed, because STM does not run above code. + ; we have to run below code to set IDT/CR0/CR4 + mov rax, strict qword 0 ; mov rax, ASM_PFX(gStmSmiHandlerIdtr) +StmSmiHandlerIdtrAbsAddr: + lidt [rax] + + mov rax, cr0 + or eax, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, rax + mov rax, cr4 + mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3 + mov cr4, rax ; in PreModifyMtrrs() to flush TLB. + ; STM init finish + jmp CommonHandler + +ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint +ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint + +global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress) +ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress): + lea rax, [ASM_PFX(gStmSmiHandlerIdtr)] + lea rcx, [StmSmiEntrySmiHandlerIdtrAbsAddr] + mov qword [rcx - 8], rax + lea rcx, [StmSmiHandlerIdtrAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [CommonHandler] + lea rcx, [StmSmiEntryCommonHandlerAbsAddr] + mov qword [rcx - 8], rax + ret diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiException.nasm b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiException.nasm new file mode 100644 index 000000000..a04415687 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiException.nasm @@ -0,0 +1,176 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiException.nasm +; +; Abstract: +; +; Exception handlers used in SM mode +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +global ASM_PFX(gcStmPsd) + +extern ASM_PFX(SmmStmExceptionHandler) +extern ASM_PFX(SmmStmSetup) +extern ASM_PFX(SmmStmTeardown) +extern ASM_PFX(gStmXdSupported) +extern ASM_PFX(gStmSmiHandlerIdtr) + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +CODE_SEL equ 0x38 +DATA_SEL equ 0x20 +TR_SEL equ 0x40 + + SECTION .data + +; +; This structure serves as a template for all processors. +; +ASM_PFX(gcStmPsd): + DB 'TXTPSSIG' + DW PSD_SIZE + DW 1 ; Version + DD 0 ; LocalApicId + DB 0x0F ; Cr4Pse;Cr4Pae;Intel64Mode;ExecutionDisableOutsideSmrr + DB 0 ; BIOS to STM + DB 0 ; STM to BIOS + DB 0 + DW CODE_SEL + DW DATA_SEL + DW DATA_SEL + DW DATA_SEL + DW TR_SEL + DW 0 + DQ 0 ; SmmCr3 + DQ ASM_PFX(OnStmSetup) + DQ ASM_PFX(OnStmTeardown) + DQ 0 ; SmmSmiHandlerRip - SMM guest entrypoint + DQ 0 ; SmmSmiHandlerRsp + DQ 0 + DD 0 + DD 0x80010100 ; RequiredStmSmmRevId + DQ ASM_PFX(OnException) + DQ 0 ; ExceptionStack + DW DATA_SEL + DW 0x01F ; ExceptionFilter + DD 0 + DQ 0 + DQ 0 ; BiosHwResourceRequirementsPtr + DQ 0 ; AcpiRsdp + DB 0 ; PhysicalAddressBits +PSD_SIZE equ $ - ASM_PFX(gcStmPsd) + + DEFAULT REL + SECTION .text +;------------------------------------------------------------------------------ +; SMM Exception handlers +;------------------------------------------------------------------------------ +global ASM_PFX(OnException) +ASM_PFX(OnException): + mov rcx, rsp + add rsp, -0x28 + call ASM_PFX(SmmStmExceptionHandler) + add rsp, 0x28 + mov ebx, eax + mov eax, 4 + vmcall + jmp $ + +global ASM_PFX(OnStmSetup) +ASM_PFX(OnStmSetup): +; +; Check XD disable bit +; + xor r8, r8 + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz @StmXdDone1 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov r8, rdx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .01 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.01: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone1: + push r8 + + add rsp, -0x20 + call ASM_PFX(SmmStmSetup) + add rsp, 0x20 + + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz .11 + pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .11 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.11: + StuffRsb64 + rsm + +global ASM_PFX(OnStmTeardown) +ASM_PFX(OnStmTeardown): +; +; Check XD disable bit +; + xor r8, r8 + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz @StmXdDone2 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + mov r8, rdx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .02 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.02: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr +@StmXdDone2: + push r8 + + add rsp, -0x20 + call ASM_PFX(SmmStmTeardown) + add rsp, 0x20 + + lea rax, [ASM_PFX(gStmXdSupported)] + mov al, [rax] + cmp al, 0 + jz .12 + pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .12 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.12: + StuffRsb64 + rsm diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmmStmSupport.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmmStmSupport.c new file mode 100644 index 000000000..aacc1455a --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmmStmSupport.c @@ -0,0 +1,89 @@ +/** @file + SMM STM support functions + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include "SmmStm.h" + +/// +/// Page Table Entry +/// +#define IA32_PG_P BIT0 +#define IA32_PG_RW BIT1 +#define IA32_PG_PS BIT7 + +/** + + Create 4G page table for STM. + 2M PAE page table in X64 version. + + @param PageTableBase The page table base in MSEG + +**/ +VOID +StmGen4GPageTable ( + IN UINTN PageTableBase + ) +{ + UINTN Index; + UINTN SubIndex; + UINT64 *Pde; + UINT64 *Pte; + UINT64 *Pml4; + + Pml4 = (UINT64*)(UINTN)PageTableBase; + PageTableBase += SIZE_4KB; + *Pml4 = PageTableBase | IA32_PG_RW | IA32_PG_P; + + Pde = (UINT64*)(UINTN)PageTableBase; + PageTableBase += SIZE_4KB; + Pte = (UINT64 *)(UINTN)PageTableBase; + + for (Index = 0; Index < 4; Index++) { + *Pde = PageTableBase | IA32_PG_RW | IA32_PG_P; + Pde++; + PageTableBase += SIZE_4KB; + + for (SubIndex = 0; SubIndex < SIZE_4KB / sizeof (*Pte); SubIndex++) { + *Pte = (((Index << 9) + SubIndex) << 21) | IA32_PG_PS | IA32_PG_RW | IA32_PG_P; + Pte++; + } + } +} + +/** + This is SMM exception handle. + Consumed by STM when exception happen. + + @param Context STM protection exception stack frame + + @return the EBX value for STM reference. + EBX = 0: resume SMM guest using register state found on exception stack. + EBX = 1 to 0x0F: EBX contains a BIOS error code which the STM must record in the + TXT.ERRORCODE register and subsequently reset the system via + TXT.CMD.SYS_RESET. The value of the TXT.ERRORCODE register is calculated as + follows: TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC + EBX = 0x10 to 0xFFFFFFFF - reserved, do not use. + +**/ +UINT32 +EFIAPI +SmmStmExceptionHandler ( + IN OUT STM_PROTECTION_EXCEPTION_STACK_FRAME Context + ) +{ + // TBD - SmmStmExceptionHandler, record information + DEBUG ((DEBUG_ERROR, "SmmStmExceptionHandler ...\n")); + // + // Skip this instruction and continue; + // + Context.X64StackFrame->Rip += Context.X64StackFrame->VmcsExitInstructionLength; + + return 0; +} diff --git a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c new file mode 100644 index 000000000..6c2010dc0 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c @@ -0,0 +1,102 @@ +/** @file +SMM CPU Platform Hook NULL library instance. + +Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include + +/** + Checks if platform produces a valid SMI. + + This function checks if platform produces a valid SMI. This function is + called at SMM entry to detect if this is a spurious SMI. This function + must be implemented in an MP safe way because it is called by multiple CPU + threads. + + @retval TRUE There is a valid SMI + @retval FALSE There is no valid SMI + +**/ +BOOLEAN +EFIAPI +PlatformValidSmi ( + VOID + ) +{ + return TRUE; +} + +/** + Clears platform top level SMI status bit. + + This function clears platform top level SMI status bit. + + @retval TRUE The platform top level SMI status is cleared. + @retval FALSE The platform top level SMI status cannot be cleared. + +**/ +BOOLEAN +EFIAPI +ClearTopLevelSmiStatus ( + VOID + ) +{ + return TRUE; +} + +/** + Performs platform specific way of SMM BSP election. + + This function performs platform specific way of SMM BSP election. + + @param IsBsp Output parameter. TRUE: the CPU this function executes + on is elected to be the SMM BSP. FALSE: the CPU this + function executes on is to be SMM AP. + + @retval EFI_SUCCESS The function executes successfully. + @retval EFI_NOT_READY The function does not determine whether this CPU should be + BSP or AP. This may occur if hardware init sequence to + enable the determination is yet to be done, or the function + chooses not to do BSP election and will let SMM CPU driver to + use its default BSP election process. + @retval EFI_DEVICE_ERROR The function cannot determine whether this CPU should be + BSP or AP due to hardware error. + +**/ +EFI_STATUS +EFIAPI +PlatformSmmBspElection ( + OUT BOOLEAN *IsBsp + ) +{ + return EFI_NOT_READY; +} + +/** + Get platform page table attribute. + + This function gets page table attribute of platform. + + @param Address Input parameter. Obtain the page table entries attribute on this address. + @param PageSize Output parameter. The size of the page. + @param NumOfPages Output parameter. Number of page. + @param PageAttribute Output parameter. Paging Attributes (WB, UC, etc). + + @retval EFI_SUCCESS The platform page table attribute from the address is determined. + @retval EFI_UNSUPPORTED The platform does not support getting page table attribute for the address. + +**/ +EFI_STATUS +EFIAPI +GetPlatformPageTableAttribute ( + IN UINT64 Address, + IN OUT SMM_PAGE_SIZE_TYPE *PageSize, + IN OUT UINTN *NumOfPages, + IN OUT UINTN *PageAttribute + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf new file mode 100644 index 000000000..fab6b30b7 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf @@ -0,0 +1,34 @@ +## @file +# SMM CPU Platform Hook NULL library instance. +# +# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmCpuPlatformHookLibNull + MODULE_UNI_FILE = SmmCpuPlatformHookLibNull.uni + FILE_GUID = D6494E1B-E06F-4ab5-B64D-48B25AA9EB33 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmCpuPlatformHookLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SmmCpuPlatformHookLibNull.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec diff --git a/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni new file mode 100644 index 000000000..b00beee96 --- /dev/null +++ b/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni @@ -0,0 +1,12 @@ +// /** @file +// SMM CPU Platform Hook NULL library instance. +// +// Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "SMM CPU Platform Hook NULL library instance" + +#string STR_MODULE_DESCRIPTION #language en-US "SMM CPU Platform Hook NULL library instance." diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c new file mode 100644 index 000000000..68e5003ad --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c @@ -0,0 +1,419 @@ +/** @file +PiSmmCommunication PEI Driver. + +Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PiSmmCommunicationPrivate.h" + +/** + the whole picture is below: + + +----------------------------------+ + | ACPI_VARIABLE_HOB | + | SmramDescriptor | <- DRAM + | CpuStart |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | SMM_S3_RESUME_STATE | + | Signature | <- SMRAM + | Smst |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | EFI_SMM_SYSTEM_TABLE2 | + | NumberOfTableEntries | <- SMRAM + | SmmConfigurationTable |--- + +----------------------------------+ | + | + +----------------------------------+<-- + | EFI_SMM_COMMUNICATION_CONTEXT | + | SwSmiNumber | <- SMRAM + | BufferPtrAddress |---------------- + +----------------------------------+ | + | + +----------------------------------+ | + | EFI_SMM_COMMUNICATION_ACPI_TABLE | | + | SwSmiNumber | <- AcpiTable | + | BufferPtrAddress |--- | + +----------------------------------+ | | + | | + +----------------------------------+<--------------- + | Communication Buffer Pointer | <- AcpiNvs + +----------------------------------+--- + | + +----------------------------------+<-- + | EFI_SMM_COMMUNICATE_HEADER | + | HeaderGuid | <- DRAM + | MessageLength | + +----------------------------------+ + +**/ + +#if defined (MDE_CPU_IA32) +typedef struct { + EFI_TABLE_HEADER Hdr; + UINT64 SmmFirmwareVendor; + UINT64 SmmFirmwareRevision; + UINT64 SmmInstallConfigurationTable; + UINT64 SmmIoMemRead; + UINT64 SmmIoMemWrite; + UINT64 SmmIoIoRead; + UINT64 SmmIoIoWrite; + UINT64 SmmAllocatePool; + UINT64 SmmFreePool; + UINT64 SmmAllocatePages; + UINT64 SmmFreePages; + UINT64 SmmStartupThisAp; + UINT64 CurrentlyExecutingCpu; + UINT64 NumberOfCpus; + UINT64 CpuSaveStateSize; + UINT64 CpuSaveState; + UINT64 NumberOfTableEntries; + UINT64 SmmConfigurationTable; +} EFI_SMM_SYSTEM_TABLE2_64; + +typedef struct { + EFI_GUID VendorGuid; + UINT64 VendorTable; +} EFI_CONFIGURATION_TABLE64; +#endif + +#if defined (MDE_CPU_X64) +typedef EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2_64; +typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64; +#endif + +/** + 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_SMM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. + @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_SMM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ); + +EFI_PEI_SMM_COMMUNICATION_PPI mSmmCommunicationPpi = { Communicate }; + +EFI_PEI_PPI_DESCRIPTOR mPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiSmmCommunicationPpiGuid, + &mSmmCommunicationPpi +}; + +/** + Get SMM communication context. + + @return SMM communication context. +**/ +EFI_SMM_COMMUNICATION_CONTEXT * +GetCommunicationContext ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + GuidHob = GetFirstGuidHob (&gEfiPeiSmmCommunicationPpiGuid); + ASSERT (GuidHob != NULL); + + SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)GET_GUID_HOB_DATA (GuidHob); + + return SmmCommunicationContext; +} + +/** + Set SMM communication context. + + @param SmmCommunicationContext SMM communication context. +**/ +VOID +SetCommunicationContext ( + IN EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN BufferSize; + + BufferSize = sizeof (*SmmCommunicationContext); + Hob.Raw = BuildGuidHob ( + &gEfiPeiSmmCommunicationPpiGuid, + BufferSize + ); + ASSERT (Hob.Raw); + + CopyMem ((VOID *)Hob.Raw, SmmCommunicationContext, sizeof(*SmmCommunicationContext)); +} + +/** + Get VendorTable by VendorGuid in Smst. + + @param Signature Signature of SMM_S3_RESUME_STATE + @param Smst SMM system table + @param VendorGuid vendor guid + + @return vendor table. +**/ +VOID * +InternalSmstGetVendorTableByGuid ( + IN UINT64 Signature, + IN EFI_SMM_SYSTEM_TABLE2 *Smst, + IN EFI_GUID *VendorGuid + ) +{ + EFI_CONFIGURATION_TABLE *SmmConfigurationTable; + UINTN NumberOfTableEntries; + UINTN Index; + EFI_SMM_SYSTEM_TABLE2_64 *Smst64; + EFI_CONFIGURATION_TABLE64 *SmmConfigurationTable64; + + if ((sizeof(UINTN) == sizeof(UINT32)) && (Signature == SMM_S3_RESUME_SMM_64)) { + // + // 32 PEI + 64 DXE + // + Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst; + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst64->SmmConfigurationTable)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst64->NumberOfTableEntries)); + SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable; + NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries; + for (Index = 0; Index < NumberOfTableEntries; Index++) { + if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) { + return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable; + } + } + return NULL; + } else { + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst->SmmConfigurationTable)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst->NumberOfTableEntries)); + SmmConfigurationTable = Smst->SmmConfigurationTable; + NumberOfTableEntries = Smst->NumberOfTableEntries; + for (Index = 0; Index < NumberOfTableEntries; Index++) { + if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) { + return (VOID *)SmmConfigurationTable[Index].VendorTable; + } + } + return NULL; + } +} + +/** + Init SMM communication context. +**/ +VOID +InitCommunicationContext ( + VOID + ) +{ + EFI_SMRAM_DESCRIPTOR *SmramDescriptor; + SMM_S3_RESUME_STATE *SmmS3ResumeState; + VOID *GuidHob; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); + ASSERT (GuidHob != NULL); + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); + SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; + + DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmS3ResumeState: %x\n", SmmS3ResumeState)); + DEBUG ((EFI_D_INFO, "InitCommunicationContext - Smst: %x\n", SmmS3ResumeState->Smst)); + + SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)InternalSmstGetVendorTableByGuid ( + SmmS3ResumeState->Signature, + (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst, + &gEfiPeiSmmCommunicationPpiGuid + ); + ASSERT (SmmCommunicationContext != NULL); + + SetCommunicationContext (SmmCommunicationContext); + + return ; +} + +/** + 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_SMM_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. + @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_SMM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ) +{ + EFI_STATUS Status; + PEI_SMM_CONTROL_PPI *SmmControl; + PEI_SMM_ACCESS_PPI *SmmAccess; + UINT8 SmiCommand; + UINTN Size; + EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Enter\n")); + + if (CommBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Get needed resource + // + Status = PeiServicesLocatePpi ( + &gPeiSmmControlPpiGuid, + 0, + NULL, + (VOID **)&SmmControl + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + Status = PeiServicesLocatePpi ( + &gPeiSmmAccessPpiGuid, + 0, + NULL, + (VOID **)&SmmAccess + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + // + // Check SMRAM locked, it should be done after SMRAM lock. + // + if (!SmmAccess->LockState) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState)); + return EFI_NOT_STARTED; + } + + SmmCommunicationContext = GetCommunicationContext (); + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei BufferPtrAddress - 0x%016lx, BufferPtr: 0x%016lx\n", SmmCommunicationContext->BufferPtrAddress, *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress)); + + // + // No need to check if BufferPtr is 0, because it is in PEI phase. + // + *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer; + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei CommBuffer - %x\n", (UINTN)CommBuffer)); + + // + // Send command + // + SmiCommand = (UINT8)SmmCommunicationContext->SwSmiNumber; + Size = sizeof(SmiCommand); + Status = SmmControl->Trigger ( + (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), + SmmControl, + (INT8 *)&SmiCommand, + &Size, + FALSE, + 0 + ); + ASSERT_EFI_ERROR (Status); + + // + // Setting BufferPtr to 0 means this transaction is done. + // + *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = 0; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Exit\n")); + + return EFI_SUCCESS; +} + +/** + Entry Point for PI SMM communication PEIM. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Pointer to PEI Services table. + + @retval EFI_SUCCESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + PEI_SMM_ACCESS_PPI *SmmAccess; + EFI_BOOT_MODE BootMode; + UINTN Index; + + BootMode = GetBootModeHob (); + if (BootMode != BOOT_ON_S3_RESUME) { + return EFI_UNSUPPORTED; + } + + Status = PeiServicesLocatePpi ( + &gPeiSmmAccessPpiGuid, + 0, + NULL, + (VOID **)&SmmAccess + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_STARTED; + } + + // + // Check SMRAM locked, it should be done before SMRAM lock. + // + if (SmmAccess->LockState) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState)); + return EFI_ACCESS_DENIED; + } + + // + // Open all SMRAM + // + for (Index = 0; !EFI_ERROR (Status); Index++) { + Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + } + + InitCommunicationContext (); + + PeiServicesInstallPpi (&mPpiList); + + return RETURN_SUCCESS; +} diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf new file mode 100644 index 000000000..4d274ce2b --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf @@ -0,0 +1,64 @@ +## @file +# PI SMM Communication PEIM which produces PEI SMM Communication PPI. +# +# This PEIM retrieves the SMM communication context and produces PEI SMM +# Communication PPIin the S3 boot mode. +# +# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCommunicationPei + MODULE_UNI_FILE = PiSmmCommunicationPei.uni + FILE_GUID = 1C8B7F78-1699-40e6-AF33-9B995D16B043 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PiSmmCommunicationPeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PiSmmCommunicationPei.c + PiSmmCommunicationPrivate.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesTablePointerLib + PeiServicesLib + BaseLib + BaseMemoryLib + HobLib + DebugLib + +[Guids] + gEfiAcpiVariableGuid ## CONSUMES ## HOB + +[Ppis] + ## PRODUCES + ## UNDEFINED # HOB # SMM Configuration Table + gEfiPeiSmmCommunicationPpiGuid + gPeiSmmAccessPpiGuid ## CONSUMES + gPeiSmmControlPpiGuid ## CONSUMES + +# [BootMode] +# S3_RESUME ## CONSUMES + +[Depex] + gPeiSmmAccessPpiGuid AND + gPeiSmmControlPpiGuid AND + gEfiPeiMasterBootModePpiGuid + +[UserExtensions.TianoCore."ExtraFiles"] + PiSmmCommunicationPeiExtra.uni diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni new file mode 100644 index 000000000..29c22808a --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni @@ -0,0 +1,15 @@ +// /** @file +// PI SMM Communication PEIM which produces PEI SMM Communication PPI. +// +// This PEIM retrieves the SMM communication context and produces PEI SMM +// Communication PPIin the S3 boot mode. +// +// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "PI SMM Communication PEIM that produces PEI SMM Communication PPI" + +#string STR_MODULE_DESCRIPTION #language en-US "This PEIM retrieves the SMM communication context and produces PEI SMM Communication PPI in the S3 boot mode." diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni new file mode 100644 index 000000000..c76457846 --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// PiSmmCommunicationPei Localized Strings and Content +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"SMM Communication PEI Module" diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h new file mode 100644 index 000000000..cf1c57eef --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h @@ -0,0 +1,24 @@ +/** @file +PiSmmCommunication private data structure + +Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_COMMUNICATION_PRIVATE_H_ +#define _SMM_COMMUNICATION_PRIVATE_H_ + +#pragma pack(push, 1) + +#define SMM_COMMUNICATION_SIGNATURE SIGNATURE_32 ('S','M','M','C') + +typedef struct { + UINT32 Signature; + UINT32 SwSmiNumber; + EFI_PHYSICAL_ADDRESS BufferPtrAddress; +} EFI_SMM_COMMUNICATION_CONTEXT; + +#pragma pack(pop) + +#endif diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c new file mode 100644 index 000000000..30f7d57bd --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c @@ -0,0 +1,207 @@ +/** @file +PiSmmCommunication SMM Driver. + +Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PiSmmCommunicationPrivate.h" + +EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = { + SMM_COMMUNICATION_SIGNATURE +}; + +/** + Set SMM communication context. +**/ +VOID +SetCommunicationContext ( + VOID + ) +{ + EFI_STATUS Status; + + Status = gSmst->SmmInstallConfigurationTable ( + gSmst, + &gEfiPeiSmmCommunicationPpiGuid, + &mSmmCommunicationContext, + sizeof(mSmmCommunicationContext) + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Dispatch function for a Software SMI handler. + + @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @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-SMM environment into an SMM environment. + @param CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS Command is handled successfully. + +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + UINTN CommSize; + EFI_STATUS Status; + EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader; + EFI_PHYSICAL_ADDRESS *BufferPtrAddress; + + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Enter\n")); + + BufferPtrAddress = (EFI_PHYSICAL_ADDRESS *)(UINTN)mSmmCommunicationContext.BufferPtrAddress; + CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)(UINTN)*BufferPtrAddress; + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader)); + if (CommunicateHeader == NULL) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n")); + Status = EFI_SUCCESS; + } else { + if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader)); + Status = EFI_SUCCESS; + goto Done; + } + + CommSize = (UINTN)CommunicateHeader->MessageLength; + if (!SmmIsBufferOutsideSmmValid ((UINTN)&CommunicateHeader->Data[0], CommSize)) { + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader->Data[0])); + Status = EFI_SUCCESS; + goto Done; + } + + // + // Call dispatch function + // + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0])); + Status = gSmst->SmiManage ( + &CommunicateHeader->HeaderGuid, + NULL, + &CommunicateHeader->Data[0], + &CommSize + ); + } + +Done: + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler %r\n", Status)); + DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Exit\n")); + + return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING; +} + +/** + Allocate EfiACPIMemoryNVS below 4G memory address. + + This function allocates EfiACPIMemoryNVS below 4G memory address. + + @param Size Size of memory to allocate. + + @return Allocated address for output. + +**/ +VOID* +AllocateAcpiNvsMemoryBelow4G ( + IN UINTN Size + ) +{ + UINTN Pages; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + VOID* Buffer; + + Pages = EFI_SIZE_TO_PAGES (Size); + Address = 0xffffffff; + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + Pages, + &Address + ); + ASSERT_EFI_ERROR (Status); + + Buffer = (VOID *) (UINTN) Address; + ZeroMem (Buffer, Size); + + return Buffer; +} + +/** + Entry Point for PI SMM communication SMM driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable A Pointer to the EFI System Table. + + @retval EFI_SUCCESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +PiSmmCommunicationSmmEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2; + EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext; + EFI_HANDLE DispatchHandle; + EFI_PHYSICAL_ADDRESS *BufferPtrAddress; + + // + // Register software SMI handler + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **)&SmmSwDispatch2 + ); + ASSERT_EFI_ERROR (Status); + + SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1; + Status = SmmSwDispatch2->Register ( + SmmSwDispatch2, + PiSmmCommunicationHandler, + &SmmSwDispatchContext, + &DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue)); + + BufferPtrAddress = AllocateAcpiNvsMemoryBelow4G (sizeof(EFI_PHYSICAL_ADDRESS)); + ASSERT (BufferPtrAddress != NULL); + DEBUG ((EFI_D_INFO, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress, *BufferPtrAddress)); + + // + // Save context + // + mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue; + mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress; + SetCommunicationContext (); + + return Status; +} diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf new file mode 100644 index 000000000..2d4b46001 --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf @@ -0,0 +1,55 @@ +## @file +# PI SMM Communication SMM driver that saves SMM communication context +# for use by SMM Communication PEIM in the S3 boot mode. +# +# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCommunicationSmm + MODULE_UNI_FILE = PiSmmCommunicationSmm.uni + FILE_GUID = E21F35A8-42FF-4050-82D6-93F7CDFA7073 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = PiSmmCommunicationSmmEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PiSmmCommunicationSmm.c + PiSmmCommunicationPrivate.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + SmmServicesTableLib + BaseLib + BaseMemoryLib + DebugLib + SmmMemLib + +[Ppis] + gEfiPeiSmmCommunicationPpiGuid ## UNDEFINED # SMM Configuration Table + +[Protocols] + gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmSwDispatch2ProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + PiSmmCommunicationSmmExtra.uni diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni new file mode 100644 index 000000000..cfb642e67 --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni @@ -0,0 +1,13 @@ +// /** @file +// PI SMM Communication SMM driver that saves SMM communication context +// for use by SMM Communication PEIM in the S3 boot mode. +// +// Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "PI SMM Communication SMM driver that saves SMM communication context" + +#string STR_MODULE_DESCRIPTION #language en-US "PI SMM Communication SMM driver that saves SMM communication context for use by SMM Communication PEIM in the S3 boot mode." diff --git a/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni new file mode 100644 index 000000000..7d9c2b679 --- /dev/null +++ b/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// PiSmmCommunicationSmm Localized Strings and Content +// +// Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"SMM Communication SMM Driver" diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c new file mode 100644 index 000000000..29e9ba92b --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c @@ -0,0 +1,1101 @@ +/** @file +Code for Processor S3 restoration + +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +#pragma pack(1) +typedef struct { + UINTN Lock; + VOID *StackStart; + UINTN StackSize; + VOID *ApFunction; + IA32_DESCRIPTOR GdtrProfile; + IA32_DESCRIPTOR IdtrProfile; + UINT32 BufferStart; + UINT32 Cr3; + UINTN InitializeFloatingPointUnitsAddress; +} MP_CPU_EXCHANGE_INFO; +#pragma pack() + +typedef struct { + UINT8 *RendezvousFunnelAddress; + UINTN PModeEntryOffset; + UINTN FlatJumpOffset; + UINTN Size; + UINTN LModeEntryOffset; + UINTN LongJumpOffset; +} MP_ASSEMBLY_ADDRESS_MAP; + +// +// Flags used when program the register. +// +typedef struct { + volatile UINTN MemoryMappedLock; // Spinlock used to program mmio + volatile UINT32 *CoreSemaphoreCount; // Semaphore container used to program + // core level semaphore. + volatile UINT32 *PackageSemaphoreCount; // Semaphore container used to program + // package level semaphore. +} PROGRAM_CPU_REGISTER_FLAGS; + +// +// Signal that SMM BASE relocation is complete. +// +volatile BOOLEAN mInitApsAfterSmmBaseReloc; + +/** + Get starting address and size of the rendezvous entry for APs. + Information for fixing a jump instruction in the code is also returned. + + @param AddressMap Output buffer for address map information. +**/ +VOID * +EFIAPI +AsmGetAddressMap ( + MP_ASSEMBLY_ADDRESS_MAP *AddressMap + ); + +#define LEGACY_REGION_SIZE (2 * 0x1000) +#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE) + +PROGRAM_CPU_REGISTER_FLAGS mCpuFlags; +ACPI_CPU_DATA mAcpiCpuData; +volatile UINT32 mNumberToFinish; +MP_CPU_EXCHANGE_INFO *mExchangeInfo; +BOOLEAN mRestoreSmmConfigurationInS3 = FALSE; + +// +// S3 boot flag +// +BOOLEAN mSmmS3Flag = FALSE; + +// +// Pointer to structure used during S3 Resume +// +SMM_S3_RESUME_STATE *mSmmS3ResumeState = NULL; + +BOOLEAN mAcpiS3Enable = TRUE; + +UINT8 *mApHltLoopCode = NULL; +UINT8 mApHltLoopCodeTemplate[] = { + 0x8B, 0x44, 0x24, 0x04, // mov eax, dword ptr [esp+4] + 0xF0, 0xFF, 0x08, // lock dec dword ptr [eax] + 0xFA, // cli + 0xF4, // hlt + 0xEB, 0xFC // jmp $-2 + }; + +/** + Sync up the MTRR values for all processors. + + @param MtrrTable Table holding fixed/variable MTRR values to be loaded. +**/ +VOID +EFIAPI +LoadMtrrData ( + EFI_PHYSICAL_ADDRESS MtrrTable + ) +/*++ + +Routine Description: + + Sync up the MTRR values for all processors. + +Arguments: + +Returns: + None + +--*/ +{ + MTRR_SETTINGS *MtrrSettings; + + MtrrSettings = (MTRR_SETTINGS *) (UINTN) MtrrTable; + MtrrSetAllMtrrs (MtrrSettings); +} + +/** + Increment semaphore by 1. + + @param Sem IN: 32-bit unsigned integer + +**/ +VOID +S3ReleaseSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + InterlockedIncrement (Sem); +} + +/** + Decrement the semaphore by 1 if it is not zero. + + Performs an atomic decrement operation for semaphore. + The compare exchange operation must be performed using + MP safe mechanisms. + + @param Sem IN: 32-bit unsigned integer + +**/ +VOID +S3WaitForSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + UINT32 Value; + + do { + Value = *Sem; + } while (Value == 0 || + InterlockedCompareExchange32 ( + Sem, + Value, + Value - 1 + ) != Value); +} + +/** + Read / write CR value. + + @param[in] CrIndex The CR index which need to read/write. + @param[in] Read Read or write. TRUE is read. + @param[in,out] CrValue CR value. + + @retval EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED. +**/ +UINTN +ReadWriteCr ( + IN UINT32 CrIndex, + IN BOOLEAN Read, + IN OUT UINTN *CrValue + ) +{ + switch (CrIndex) { + case 0: + if (Read) { + *CrValue = AsmReadCr0 (); + } else { + AsmWriteCr0 (*CrValue); + } + break; + case 2: + if (Read) { + *CrValue = AsmReadCr2 (); + } else { + AsmWriteCr2 (*CrValue); + } + break; + case 3: + if (Read) { + *CrValue = AsmReadCr3 (); + } else { + AsmWriteCr3 (*CrValue); + } + break; + case 4: + if (Read) { + *CrValue = AsmReadCr4 (); + } else { + AsmWriteCr4 (*CrValue); + } + break; + default: + return EFI_UNSUPPORTED;; + } + + return EFI_SUCCESS; +} + +/** + Initialize the CPU registers from a register table. + + @param[in] RegisterTable The register table for this AP. + @param[in] ApLocation AP location info for this ap. + @param[in] CpuStatus CPU status info for this CPU. + @param[in] CpuFlags Flags data structure used when program the register. + + @note This service could be called by BSP/APs. +**/ +VOID +ProgramProcessorRegister ( + IN CPU_REGISTER_TABLE *RegisterTable, + IN EFI_CPU_PHYSICAL_LOCATION *ApLocation, + IN CPU_STATUS_INFORMATION *CpuStatus, + IN PROGRAM_CPU_REGISTER_FLAGS *CpuFlags + ) +{ + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; + UINTN Index; + UINTN Value; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead; + volatile UINT32 *SemaphorePtr; + UINT32 FirstThread; + UINT32 PackageThreadsCount; + UINT32 CurrentThread; + UINTN ProcessorIndex; + UINTN ValidThreadCount; + UINT32 *ValidCoreCountPerPackage; + EFI_STATUS Status; + UINT64 CurrentValue; + + // + // Traverse Register Table of this logical processor + // + RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry; + + for (Index = 0; Index < RegisterTable->TableLength; Index++) { + + RegisterTableEntry = &RegisterTableEntryHead[Index]; + + // + // Check the type of specified register + // + switch (RegisterTableEntry->RegisterType) { + // + // The specified register is Control Register + // + case ControlRegister: + Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value); + if (EFI_ERROR (Status)) { + break; + } + if (RegisterTableEntry->TestThenWrite) { + CurrentValue = BitFieldRead64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + break; + } + } + Value = (UINTN) BitFieldWrite64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + RegisterTableEntry->Value + ); + ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value); + break; + // + // The specified register is Model Specific Register + // + case Msr: + if (RegisterTableEntry->TestThenWrite) { + Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index); + if (RegisterTableEntry->ValidBitLength >= 64) { + if (Value == RegisterTableEntry->Value) { + break; + } + } else { + CurrentValue = BitFieldRead64 ( + Value, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1 + ); + if (CurrentValue == RegisterTableEntry->Value) { + break; + } + } + } + + // + // If this function is called to restore register setting after INIT signal, + // there is no need to restore MSRs in register table. + // + if (RegisterTableEntry->ValidBitLength >= 64) { + // + // If length is not less than 64 bits, then directly write without reading + // + AsmWriteMsr64 ( + RegisterTableEntry->Index, + RegisterTableEntry->Value + ); + } else { + // + // Set the bit section according to bit start and length + // + AsmMsrBitFieldWrite64 ( + RegisterTableEntry->Index, + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + RegisterTableEntry->Value + ); + } + break; + // + // MemoryMapped operations + // + case MemoryMapped: + AcquireSpinLock (&CpuFlags->MemoryMappedLock); + MmioBitFieldWrite32 ( + (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)), + RegisterTableEntry->ValidBitStart, + RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1, + (UINT32)RegisterTableEntry->Value + ); + ReleaseSpinLock (&CpuFlags->MemoryMappedLock); + break; + // + // Enable or disable cache + // + case CacheControl: + // + // If value of the entry is 0, then disable cache. Otherwise, enable cache. + // + if (RegisterTableEntry->Value == 0) { + AsmDisableCache (); + } else { + AsmEnableCache (); + } + break; + + case Semaphore: + // Semaphore works logic like below: + // + // V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]); + // P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]); + // + // All threads (T0...Tn) waits in P() line and continues running + // together. + // + // + // T0 T1 ... Tn + // + // V(0...n) V(0...n) ... V(0...n) + // n * P(0) n * P(1) ... n * P(n) + // + ASSERT ( + (ApLocation != NULL) && + (CpuStatus->ValidCoreCountPerPackage != 0) && + (CpuFlags->CoreSemaphoreCount != NULL) && + (CpuFlags->PackageSemaphoreCount != NULL) + ); + switch (RegisterTableEntry->Value) { + case CoreDepType: + SemaphorePtr = CpuFlags->CoreSemaphoreCount; + // + // Get Offset info for the first thread in the core which current thread belongs to. + // + FirstThread = (ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core) * CpuStatus->MaxThreadCount; + CurrentThread = FirstThread + ApLocation->Thread; + // + // First Notify all threads in current Core that this thread has ready. + // + for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) { + S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]); + } + // + // Second, check whether all valid threads in current core have ready. + // + for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) { + S3WaitForSemaphore (&SemaphorePtr[CurrentThread]); + } + break; + + case PackageDepType: + SemaphorePtr = CpuFlags->PackageSemaphoreCount; + ValidCoreCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ValidCoreCountPerPackage; + // + // Get Offset info for the first thread in the package which current thread belongs to. + // + FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount; + // + // Get the possible threads count for current package. + // + PackageThreadsCount = CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; + CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread; + // + // Get the valid thread count for current package. + // + ValidThreadCount = CpuStatus->MaxThreadCount * ValidCoreCountPerPackage[ApLocation->Package]; + + // + // Different packages may have different valid cores in them. If driver maintail clearly + // cores number in different packages, the logic will be much complicated. + // Here driver just simply records the max core number in all packages and use it as expect + // core number for all packages. + // In below two steps logic, first current thread will Release semaphore for each thread + // in current package. Maybe some threads are not valid in this package, but driver don't + // care. Second, driver will let current thread wait semaphore for all valid threads in + // current package. Because only the valid threads will do release semaphore for this + // thread, driver here only need to wait the valid thread count. + // + + // + // First Notify all threads in current package that this thread has ready. + // + for (ProcessorIndex = 0; ProcessorIndex < PackageThreadsCount ; ProcessorIndex ++) { + S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]); + } + // + // Second, check whether all valid threads in current package have ready. + // + for (ProcessorIndex = 0; ProcessorIndex < ValidThreadCount; ProcessorIndex ++) { + S3WaitForSemaphore (&SemaphorePtr[CurrentThread]); + } + break; + + default: + break; + } + break; + + default: + break; + } + } +} + +/** + + Set Processor register for one AP. + + @param PreSmmRegisterTable Use pre Smm register table or register table. + +**/ +VOID +SetRegister ( + IN BOOLEAN PreSmmRegisterTable + ) +{ + CPU_REGISTER_TABLE *RegisterTable; + CPU_REGISTER_TABLE *RegisterTables; + UINT32 InitApicId; + UINTN ProcIndex; + UINTN Index; + + if (PreSmmRegisterTable) { + RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.PreSmmInitRegisterTable; + } else { + RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable; + } + + InitApicId = GetInitialApicId (); + RegisterTable = NULL; + ProcIndex = (UINTN)-1; + for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) { + if (RegisterTables[Index].InitialApicId == InitApicId) { + RegisterTable = &RegisterTables[Index]; + ProcIndex = Index; + break; + } + } + ASSERT (RegisterTable != NULL); + + if (mAcpiCpuData.ApLocation != 0) { + ProgramProcessorRegister ( + RegisterTable, + (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)mAcpiCpuData.ApLocation + ProcIndex, + &mAcpiCpuData.CpuStatus, + &mCpuFlags + ); + } else { + ProgramProcessorRegister ( + RegisterTable, + NULL, + &mAcpiCpuData.CpuStatus, + &mCpuFlags + ); + } +} + +/** + AP initialization before then after SMBASE relocation in the S3 boot path. +**/ +VOID +InitializeAp ( + VOID + ) +{ + UINTN TopOfStack; + UINT8 Stack[128]; + + LoadMtrrData (mAcpiCpuData.MtrrTable); + + SetRegister (TRUE); + + // + // Count down the number with lock mechanism. + // + InterlockedDecrement (&mNumberToFinish); + + // + // Wait for BSP to signal SMM Base relocation done. + // + while (!mInitApsAfterSmmBaseReloc) { + CpuPause (); + } + + ProgramVirtualWireMode (); + DisableLvtInterrupts (); + + SetRegister (FALSE); + + // + // Place AP into the safe code, count down the number with lock mechanism in the safe code. + // + TopOfStack = (UINTN) Stack + sizeof (Stack); + TopOfStack &= ~(UINTN) (CPU_STACK_ALIGNMENT - 1); + CopyMem ((VOID *) (UINTN) mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate)); + TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish); +} + +/** + Prepares startup vector for APs. + + This function prepares startup vector for APs. + + @param WorkingBuffer The address of the work buffer. +**/ +VOID +PrepareApStartupVector ( + EFI_PHYSICAL_ADDRESS WorkingBuffer + ) +{ + EFI_PHYSICAL_ADDRESS StartupVector; + MP_ASSEMBLY_ADDRESS_MAP AddressMap; + + // + // Get the address map of startup code for AP, + // including code size, and offset of long jump instructions to redirect. + // + ZeroMem (&AddressMap, sizeof (AddressMap)); + AsmGetAddressMap (&AddressMap); + + StartupVector = WorkingBuffer; + + // + // Copy AP startup code to startup vector, and then redirect the long jump + // instructions for mode switching. + // + CopyMem ((VOID *) (UINTN) StartupVector, AddressMap.RendezvousFunnelAddress, AddressMap.Size); + *(UINT32 *) (UINTN) (StartupVector + AddressMap.FlatJumpOffset + 3) = (UINT32) (StartupVector + AddressMap.PModeEntryOffset); + if (AddressMap.LongJumpOffset != 0) { + *(UINT32 *) (UINTN) (StartupVector + AddressMap.LongJumpOffset + 2) = (UINT32) (StartupVector + AddressMap.LModeEntryOffset); + } + + // + // Get the start address of exchange data between BSP and AP. + // + mExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (StartupVector + AddressMap.Size); + ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO)); + + CopyMem ((VOID *) (UINTN) &mExchangeInfo->GdtrProfile, (VOID *) (UINTN) mAcpiCpuData.GdtrProfile, sizeof (IA32_DESCRIPTOR)); + CopyMem ((VOID *) (UINTN) &mExchangeInfo->IdtrProfile, (VOID *) (UINTN) mAcpiCpuData.IdtrProfile, sizeof (IA32_DESCRIPTOR)); + + mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress; + mExchangeInfo->StackSize = mAcpiCpuData.StackSize; + mExchangeInfo->BufferStart = (UINT32) StartupVector; + mExchangeInfo->Cr3 = (UINT32) (AsmReadCr3 ()); + mExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits; +} + +/** + The function is invoked before SMBASE relocation in S3 path to restores CPU status. + + The function is invoked before SMBASE relocation in S3 path. It does first time microcode load + and restores MTRRs for both BSP and APs. + +**/ +VOID +InitializeCpuBeforeRebase ( + VOID + ) +{ + LoadMtrrData (mAcpiCpuData.MtrrTable); + + SetRegister (TRUE); + + ProgramVirtualWireMode (); + + PrepareApStartupVector (mAcpiCpuData.StartupVector); + + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus); + } else { + ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus); + } + mNumberToFinish = (UINT32)(mNumberOfCpus - 1); + mExchangeInfo->ApFunction = (VOID *) (UINTN) InitializeAp; + + // + // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots. + // + mInitApsAfterSmmBaseReloc = FALSE; + + // + // Send INIT IPI - SIPI to all APs + // + SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector); + + while (mNumberToFinish > 0) { + CpuPause (); + } +} + +/** + The function is invoked after SMBASE relocation in S3 path to restores CPU status. + + The function is invoked after SMBASE relocation in S3 path. It restores configuration according to + data saved by normal boot path for both BSP and APs. + +**/ +VOID +InitializeCpuAfterRebase ( + VOID + ) +{ + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus); + } else { + ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus); + } + mNumberToFinish = (UINT32)(mNumberOfCpus - 1); + + // + // Signal that SMM base relocation is complete and to continue initialization for all APs. + // + mInitApsAfterSmmBaseReloc = TRUE; + + // + // Must begin set register after all APs have continue their initialization. + // This is a requirement to support semaphore mechanism in register table. + // Because if semaphore's dependence type is package type, semaphore will wait + // for all Aps in one package finishing their tasks before set next register + // for all APs. If the Aps not begin its task during BSP doing its task, the + // BSP thread will hang because it is waiting for other Aps in the same + // package finishing their task. + // + SetRegister (FALSE); + + while (mNumberToFinish > 0) { + CpuPause (); + } +} + +/** + Restore SMM Configuration in S3 boot path. + +**/ +VOID +RestoreSmmConfigurationInS3 ( + VOID + ) +{ + if (!mAcpiS3Enable) { + return; + } + + // + // Restore SMM Configuration in S3 boot path. + // + if (mRestoreSmmConfigurationInS3) { + // + // Need make sure gSmst 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; + + // + // Configure SMM Code Access Check feature if available. + // + ConfigSmmCodeAccessCheck (); + + SmmCpuFeaturesCompleteSmmReadyToLock (); + + mRestoreSmmConfigurationInS3 = FALSE; + } +} + +/** + Perform SMM initialization for all processors in the S3 boot path. + + For a native platform, MP initialization in the S3 boot path is also performed in this function. +**/ +VOID +EFIAPI +SmmRestoreCpu ( + VOID + ) +{ + SMM_S3_RESUME_STATE *SmmS3ResumeState; + IA32_DESCRIPTOR Ia32Idtr; + IA32_DESCRIPTOR X64Idtr; + IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER]; + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "SmmRestoreCpu()\n")); + + mSmmS3Flag = TRUE; + + // + // See if there is enough context to resume PEI Phase + // + if (mSmmS3ResumeState == NULL) { + DEBUG ((EFI_D_ERROR, "No context to return to PEI Phase\n")); + CpuDeadLoop (); + } + + SmmS3ResumeState = mSmmS3ResumeState; + ASSERT (SmmS3ResumeState != NULL); + + if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) { + // + // Save the IA32 IDT Descriptor + // + AsmReadIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr); + + // + // Setup X64 IDT table + // + ZeroMem (IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32); + X64Idtr.Base = (UINTN) IdtEntryTable; + X64Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32 - 1); + AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr); + + // + // Setup the default exception handler + // + Status = InitializeCpuExceptionHandlers (NULL); + ASSERT_EFI_ERROR (Status); + + // + // Initialize Debug Agent to support source level debug + // + InitializeDebugAgent (DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64, (VOID *)&Ia32Idtr, NULL); + } + + // + // Skip initialization if mAcpiCpuData is not valid + // + if (mAcpiCpuData.NumberOfCpus > 0) { + // + // First time microcode load and restore MTRRs + // + InitializeCpuBeforeRebase (); + } + + // + // Restore SMBASE for BSP and all APs + // + SmmRelocateBases (); + + // + // Skip initialization if mAcpiCpuData is not valid + // + if (mAcpiCpuData.NumberOfCpus > 0) { + // + // Restore MSRs for BSP and all APs + // + InitializeCpuAfterRebase (); + } + + // + // Set a flag to restore SMM configuration in S3 path. + // + mRestoreSmmConfigurationInS3 = TRUE; + + DEBUG (( EFI_D_INFO, "SMM S3 Return CS = %x\n", SmmS3ResumeState->ReturnCs)); + DEBUG (( EFI_D_INFO, "SMM S3 Return Entry Point = %x\n", SmmS3ResumeState->ReturnEntryPoint)); + DEBUG (( EFI_D_INFO, "SMM S3 Return Context1 = %x\n", SmmS3ResumeState->ReturnContext1)); + DEBUG (( EFI_D_INFO, "SMM S3 Return Context2 = %x\n", SmmS3ResumeState->ReturnContext2)); + DEBUG (( EFI_D_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer)); + + // + // If SMM is in 32-bit mode, then use SwitchStack() to resume PEI Phase + // + if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) { + DEBUG ((EFI_D_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n")); + + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->ReturnEntryPoint, + (VOID *)(UINTN)SmmS3ResumeState->ReturnContext1, + (VOID *)(UINTN)SmmS3ResumeState->ReturnContext2, + (VOID *)(UINTN)SmmS3ResumeState->ReturnStackPointer + ); + } + + // + // If SMM is in 64-bit mode, then use AsmDisablePaging64() to resume PEI Phase + // + if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) { + DEBUG ((EFI_D_INFO, "Call AsmDisablePaging64() to return to S3 Resume in PEI Phase\n")); + // + // Disable interrupt of Debug timer, since new IDT table is for IA32 and will not work in long mode. + // + SaveAndSetDebugTimerInterrupt (FALSE); + // + // Restore IA32 IDT table + // + AsmWriteIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr); + AsmDisablePaging64 ( + SmmS3ResumeState->ReturnCs, + (UINT32)SmmS3ResumeState->ReturnEntryPoint, + (UINT32)SmmS3ResumeState->ReturnContext1, + (UINT32)SmmS3ResumeState->ReturnContext2, + (UINT32)SmmS3ResumeState->ReturnStackPointer + ); + } + + // + // Can not resume PEI Phase + // + DEBUG ((EFI_D_ERROR, "No context to return to PEI Phase\n")); + CpuDeadLoop (); +} + +/** + 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 *GuidHob; + EFI_SMRAM_DESCRIPTOR *SmramDescriptor; + SMM_S3_RESUME_STATE *SmmS3ResumeState; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + + if (!mAcpiS3Enable) { + return; + } + + GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); + if (GuidHob == NULL) { + DEBUG (( + DEBUG_ERROR, + "ERROR:%a(): HOB(gEfiAcpiVariableGuid=%g) needed by S3 resume doesn't exist!\n", + __FUNCTION__, + &gEfiAcpiVariableGuid + )); + CpuDeadLoop (); + } else { + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); + + DEBUG ((EFI_D_INFO, "SMM S3 SMRAM Structure = %x\n", SmramDescriptor)); + DEBUG ((EFI_D_INFO, "SMM S3 Structure = %x\n", SmramDescriptor->CpuStart)); + + SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; + ZeroMem (SmmS3ResumeState, sizeof (SMM_S3_RESUME_STATE)); + + mSmmS3ResumeState = SmmS3ResumeState; + SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gSmst; + + SmmS3ResumeState->SmmS3ResumeEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)SmmRestoreCpu; + + SmmS3ResumeState->SmmS3StackSize = SIZE_32KB; + SmmS3ResumeState->SmmS3StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)SmmS3ResumeState->SmmS3StackSize)); + if (SmmS3ResumeState->SmmS3StackBase == 0) { + SmmS3ResumeState->SmmS3StackSize = 0; + } + + SmmS3ResumeState->SmmS3Cr0 = mSmmCr0; + SmmS3ResumeState->SmmS3Cr3 = Cr3; + SmmS3ResumeState->SmmS3Cr4 = mSmmCr4; + + if (sizeof (UINTN) == sizeof (UINT64)) { + SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_64; + } + if (sizeof (UINTN) == sizeof (UINT32)) { + SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_32; + } + + // + // Patch SmmS3ResumeState->SmmS3Cr3 + // + InitSmmS3Cr3 (); + } + + // + // Allocate safe memory in ACPI NVS for AP to execute hlt loop in + // protected mode on S3 path + // + Address = BASE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (sizeof (mApHltLoopCodeTemplate)), + &Address + ); + ASSERT_EFI_ERROR (Status); + mApHltLoopCode = (UINT8 *) (UINTN) Address; +} + +/** + Copy register table from ACPI NVS memory into SMRAM. + + @param[in] DestinationRegisterTableList Points to destination register table. + @param[in] SourceRegisterTableList Points to source register table. + @param[in] NumberOfCpus Number of CPUs. + +**/ +VOID +CopyRegisterTable ( + IN CPU_REGISTER_TABLE *DestinationRegisterTableList, + IN CPU_REGISTER_TABLE *SourceRegisterTableList, + IN UINT32 NumberOfCpus + ) +{ + UINTN Index; + CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; + + CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); + for (Index = 0; Index < NumberOfCpus; Index++) { + if (DestinationRegisterTableList[Index].AllocatedSize != 0) { + RegisterTableEntry = AllocateCopyPool ( + DestinationRegisterTableList[Index].AllocatedSize, + (VOID *)(UINTN)SourceRegisterTableList[Index].RegisterTableEntry + ); + ASSERT (RegisterTableEntry != NULL); + DestinationRegisterTableList[Index].RegisterTableEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTableEntry; + } + } +} + +/** + Get ACPI CPU data. + +**/ +VOID +GetAcpiCpuData ( + VOID + ) +{ + ACPI_CPU_DATA *AcpiCpuData; + IA32_DESCRIPTOR *Gdtr; + IA32_DESCRIPTOR *Idtr; + VOID *GdtForAp; + VOID *IdtForAp; + VOID *MachineCheckHandlerForAp; + CPU_STATUS_INFORMATION *CpuStatus; + + if (!mAcpiS3Enable) { + return; + } + + // + // Prevent use of mAcpiCpuData by initialize NumberOfCpus to 0 + // + mAcpiCpuData.NumberOfCpus = 0; + + // + // If PcdCpuS3DataAddress was never set, then do not copy CPU S3 Data into SMRAM + // + AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress); + if (AcpiCpuData == 0) { + return; + } + + // + // For a native platform, copy the CPU S3 data into SMRAM for use on CPU S3 Resume. + // + CopyMem (&mAcpiCpuData, AcpiCpuData, sizeof (mAcpiCpuData)); + + mAcpiCpuData.MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (MTRR_SETTINGS)); + ASSERT (mAcpiCpuData.MtrrTable != 0); + + CopyMem ((VOID *)(UINTN)mAcpiCpuData.MtrrTable, (VOID *)(UINTN)AcpiCpuData->MtrrTable, sizeof (MTRR_SETTINGS)); + + mAcpiCpuData.GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR)); + ASSERT (mAcpiCpuData.GdtrProfile != 0); + + CopyMem ((VOID *)(UINTN)mAcpiCpuData.GdtrProfile, (VOID *)(UINTN)AcpiCpuData->GdtrProfile, sizeof (IA32_DESCRIPTOR)); + + mAcpiCpuData.IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR)); + ASSERT (mAcpiCpuData.IdtrProfile != 0); + + CopyMem ((VOID *)(UINTN)mAcpiCpuData.IdtrProfile, (VOID *)(UINTN)AcpiCpuData->IdtrProfile, sizeof (IA32_DESCRIPTOR)); + + mAcpiCpuData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); + ASSERT (mAcpiCpuData.PreSmmInitRegisterTable != 0); + + CopyRegisterTable ( + (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.PreSmmInitRegisterTable, + (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->PreSmmInitRegisterTable, + mAcpiCpuData.NumberOfCpus + ); + + mAcpiCpuData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); + ASSERT (mAcpiCpuData.RegisterTable != 0); + + CopyRegisterTable ( + (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable, + (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable, + mAcpiCpuData.NumberOfCpus + ); + + // + // Copy AP's GDT, IDT and Machine Check handler into SMRAM. + // + Gdtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.GdtrProfile; + Idtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.IdtrProfile; + + GdtForAp = AllocatePool ((Gdtr->Limit + 1) + (Idtr->Limit + 1) + mAcpiCpuData.ApMachineCheckHandlerSize); + ASSERT (GdtForAp != NULL); + IdtForAp = (VOID *) ((UINTN)GdtForAp + (Gdtr->Limit + 1)); + MachineCheckHandlerForAp = (VOID *) ((UINTN)IdtForAp + (Idtr->Limit + 1)); + + CopyMem (GdtForAp, (VOID *)Gdtr->Base, Gdtr->Limit + 1); + CopyMem (IdtForAp, (VOID *)Idtr->Base, Idtr->Limit + 1); + CopyMem (MachineCheckHandlerForAp, (VOID *)(UINTN)mAcpiCpuData.ApMachineCheckHandlerBase, mAcpiCpuData.ApMachineCheckHandlerSize); + + Gdtr->Base = (UINTN)GdtForAp; + Idtr->Base = (UINTN)IdtForAp; + mAcpiCpuData.ApMachineCheckHandlerBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MachineCheckHandlerForAp; + + CpuStatus = &mAcpiCpuData.CpuStatus; + CopyMem (CpuStatus, &AcpiCpuData->CpuStatus, sizeof (CPU_STATUS_INFORMATION)); + if (AcpiCpuData->CpuStatus.ValidCoreCountPerPackage != 0) { + CpuStatus->ValidCoreCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool ( + sizeof (UINT32) * CpuStatus->PackageCount, + (UINT32 *)(UINTN)AcpiCpuData->CpuStatus.ValidCoreCountPerPackage + ); + ASSERT (CpuStatus->ValidCoreCountPerPackage != 0); + } + if (AcpiCpuData->ApLocation != 0) { + mAcpiCpuData.ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool ( + mAcpiCpuData.NumberOfCpus * sizeof (EFI_CPU_PHYSICAL_LOCATION), + (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)AcpiCpuData->ApLocation + ); + ASSERT (mAcpiCpuData.ApLocation != 0); + } + if (CpuStatus->PackageCount != 0) { + mCpuFlags.CoreSemaphoreCount = AllocateZeroPool ( + sizeof (UINT32) * CpuStatus->PackageCount * + CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount + ); + ASSERT (mCpuFlags.CoreSemaphoreCount != NULL); + mCpuFlags.PackageSemaphoreCount = AllocateZeroPool ( + sizeof (UINT32) * CpuStatus->PackageCount * + CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount + ); + ASSERT (mCpuFlags.PackageSemaphoreCount != NULL); + } + InitializeSpinLock((SPIN_LOCK*) &mCpuFlags.MemoryMappedLock); +} + +/** + Get ACPI S3 enable flag. + +**/ +VOID +GetAcpiS3EnableFlag ( + VOID + ) +{ + mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c new file mode 100644 index 000000000..c9138a531 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -0,0 +1,366 @@ +/** @file +Implementation of SMM CPU Services Protocol. + +Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +// +// SMM CPU Service Protocol instance +// +EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = { + SmmGetProcessorInfo, + SmmSwitchBsp, + SmmAddProcessor, + SmmRemoveProcessor, + SmmWhoAmI, + SmmRegisterExceptionHandler +}; + +/** + Gets processor information on the requested processor at the instant this call is made. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + +**/ +EFI_STATUS +EFIAPI +SmmGetProcessorInfo ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ) +{ + // + // Check parameter + // + if (ProcessorNumber >= mMaxNumberOfCpus || ProcessorInfoBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) { + return EFI_NOT_FOUND; + } + + // + // Fill in processor information + // + CopyMem (ProcessorInfoBuffer, &gSmmCpuPrivate->ProcessorInfo[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION)); + return EFI_SUCCESS; +} + +/** + This service switches the requested AP to be the BSP since the next SMI. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. + + @retval EFI_SUCCESS BSP will be switched in next SMI. + @retval EFI_UNSUPPORTED Switching the BSP or a processor to be hot-removed is not supported. + @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. +**/ +EFI_STATUS +EFIAPI +SmmSwitchBsp ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ) +{ + // + // Check parameter + // + if (ProcessorNumber >= mMaxNumberOfCpus) { + return EFI_INVALID_PARAMETER; + } + + if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) { + return EFI_NOT_FOUND; + } + + if (gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone || + gSmst->CurrentlyExecutingCpu == ProcessorNumber) { + return EFI_UNSUPPORTED; + } + + // + // Setting of the BSP for next SMI is pending until all SMI handlers are finished + // + gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuSwitchBsp; + return EFI_SUCCESS; +} + +/** + Notify that a processor was hot-added. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorId Local APIC ID of the hot-added processor. + @param[out] ProcessorNumber The handle number of the hot-added processor. + + @retval EFI_SUCCESS The hot-addition of the specified processors was successfully notified. + @retval EFI_UNSUPPORTED Hot addition of processor is not supported. + @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. + @retval EFI_ALREADY_STARTED The processor is already online in the system. +**/ +EFI_STATUS +EFIAPI +SmmAddProcessor ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINT64 ProcessorId, + OUT UINTN *ProcessorNumber + ) +{ + UINTN Index; + + if (!FeaturePcdGet (PcdCpuHotPlugSupport)) { + return EFI_UNSUPPORTED; + } + + // + // Check parameter + // + if (ProcessorNumber == NULL || ProcessorId == INVALID_APIC_ID) { + return EFI_INVALID_PARAMETER; + } + + // + // Check if the processor already exists + // + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ProcessorId) { + return EFI_ALREADY_STARTED; + } + } + + // + // Check CPU hot plug data. The CPU RAS handler should have created the mapping + // of the APIC ID to SMBASE. + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (mCpuHotPlugData.ApicId[Index] == ProcessorId && + gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) { + gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId; + gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0; + GetProcessorLocationByApicId ( + (UINT32)ProcessorId, + &gSmmCpuPrivate->ProcessorInfo[Index].Location.Package, + &gSmmCpuPrivate->ProcessorInfo[Index].Location.Core, + &gSmmCpuPrivate->ProcessorInfo[Index].Location.Thread + ); + + *ProcessorNumber = Index; + gSmmCpuPrivate->Operation[Index] = SmmCpuAdd; + return EFI_SUCCESS; + } + } + + return EFI_INVALID_PARAMETER; +} + +/** + Notify that a processor was hot-removed. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of the hot-added processor. + + @retval EFI_SUCCESS The hot-removal of the specified processors was successfully notified. + @retval EFI_UNSUPPORTED Hot removal of processor is not supported. + @retval EFI_UNSUPPORTED Hot removal of BSP is not supported. + @retval EFI_UNSUPPORTED Hot removal of a processor with pending hot-plug operation is not supported. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. +**/ +EFI_STATUS +EFIAPI +SmmRemoveProcessor ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ) +{ + if (!FeaturePcdGet (PcdCpuHotPlugSupport)) { + return EFI_UNSUPPORTED; + } + + // + // Check parameter + // + if (ProcessorNumber >= mMaxNumberOfCpus || + gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) { + return EFI_INVALID_PARAMETER; + } + + // + // Can't remove BSP + // + if (ProcessorNumber == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) { + return EFI_UNSUPPORTED; + } + + if (gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) { + return EFI_UNSUPPORTED; + } + + gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId = INVALID_APIC_ID; + mCpuHotPlugData.ApicId[ProcessorNumber] = INVALID_APIC_ID; + + // + // Removal of the processor from the CPU list is pending until all SMI handlers are finished + // + gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuRemove; + return EFI_SUCCESS; +} + +/** + This return the handle number for the calling processor. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[out] ProcessorNumber The handle number of currently executing processor. + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +EFI_STATUS +EFIAPI +SmmWhoAmI ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ) +{ + UINTN Index; + UINT64 ApicId; + + // + // Check parameter + // + if (ProcessorNumber == NULL) { + return EFI_INVALID_PARAMETER; + } + + ApicId = GetApicId (); + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) { + *ProcessorNumber = Index; + return EFI_SUCCESS; + } + } + // + // This should not happen + // + ASSERT (FALSE); + return EFI_NOT_FOUND; +} + +/** + Update the SMM CPU list per the pending operation. + + This function is called after return from SMI handlers. +**/ +VOID +SmmCpuUpdate ( + VOID + ) +{ + UINTN Index; + + // + // Handle pending BSP switch operations + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->Operation[Index] == SmmCpuSwitchBsp) { + gSmmCpuPrivate->Operation[Index] = SmmCpuNone; + mSmmMpSyncData->SwitchBsp = TRUE; + mSmmMpSyncData->CandidateBsp[Index] = TRUE; + } + } + + // + // Handle pending hot-add operations + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->Operation[Index] == SmmCpuAdd) { + gSmmCpuPrivate->Operation[Index] = SmmCpuNone; + mNumberOfCpus++; + } + } + + // + // Handle pending hot-remove operations + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->Operation[Index] == SmmCpuRemove) { + gSmmCpuPrivate->Operation[Index] = SmmCpuNone; + mNumberOfCpus--; + } + } +} + +/** + Register exception handler. + + @param This A pointer to the SMM_CPU_SERVICE_PROTOCOL instance. + @param ExceptionType Defines which interrupt or exception to hook. Type EFI_EXCEPTION_TYPE and + the valid values for this parameter are defined in EFI_DEBUG_SUPPORT_PROTOCOL + of the UEFI 2.0 specification. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER + that is called when a processor interrupt occurs. + If this parameter is NULL, then the handler will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported. + +**/ +EFI_STATUS +EFIAPI +SmmRegisterExceptionHandler ( + IN EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + return RegisterCpuInterruptHandler (ExceptionType, InterruptHandler); +} + +/** + Initialize SMM CPU Services. + + It installs EFI SMM CPU Services Protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + + @retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully. +**/ +EFI_STATUS +InitializeSmmCpuServices ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + + Status = gSmst->SmmInstallProtocolInterface ( + &Handle, + &gEfiSmmCpuServiceProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmCpuService + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h new file mode 100644 index 000000000..98b0feb42 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h @@ -0,0 +1,175 @@ +/** @file +Include file for SMM CPU Services protocol implementation. + +Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_SERVICE_H_ +#define _CPU_SERVICE_H_ + +typedef enum { + SmmCpuNone, + SmmCpuAdd, + SmmCpuRemove, + SmmCpuSwitchBsp +} SMM_CPU_OPERATION; + +// +// SMM CPU Service Protocol function prototypes. +// + +/** + Gets processor information on the requested processor at the instant this call is made. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + +**/ +EFI_STATUS +EFIAPI +SmmGetProcessorInfo ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + This service switches the requested AP to be the BSP since the next SMI. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. + + @retval EFI_SUCCESS BSP will be switched in next SMI. + @retval EFI_UNSUPPORTED Switching the BSP or a processor to be hot-removed is not supported. + @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. +**/ +EFI_STATUS +EFIAPI +SmmSwitchBsp ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ); + +/** + Notify that a processor was hot-added. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorId Local APIC ID of the hot-added processor. + @param[out] ProcessorNumber The handle number of the hot-added processor. + + @retval EFI_SUCCESS The hot-addition of the specified processors was successfully notified. + @retval EFI_UNSUPPORTED Hot addition of processor is not supported. + @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. + @retval EFI_ALREADY_STARTED The processor is already online in the system. +**/ +EFI_STATUS +EFIAPI +SmmAddProcessor ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINT64 ProcessorId, + OUT UINTN *ProcessorNumber + ); + +/** + Notify that a processor was hot-removed. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of the hot-added processor. + + @retval EFI_SUCCESS The hot-removal of the specified processors was successfully notified. + @retval EFI_UNSUPPORTED Hot removal of processor is not supported. + @retval EFI_UNSUPPORTED Hot removal of BSP is not supported. + @retval EFI_UNSUPPORTED Hot removal of a processor with pending hot-plug operation is not supported. + @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid. +**/ +EFI_STATUS +EFIAPI +SmmRemoveProcessor ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN UINTN ProcessorNumber + ); + +/** + This return the handle number for the calling processor. + + @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. + @param[out] ProcessorNumber The handle number of currently executing processor. + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +EFI_STATUS +EFIAPI +SmmWhoAmI ( + IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ); + +/** + Register exception handler. + + @param This A pointer to the SMM_CPU_SERVICE_PROTOCOL instance. + @param ExceptionType Defines which interrupt or exception to hook. Type EFI_EXCEPTION_TYPE and + the valid values for this parameter are defined in EFI_DEBUG_SUPPORT_PROTOCOL + of the UEFI 2.0 specification. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER + that is called when a processor interrupt occurs. + If this parameter is NULL, then the handler will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported. + +**/ +EFI_STATUS +EFIAPI +SmmRegisterExceptionHandler ( + IN EFI_SMM_CPU_SERVICE_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE ExceptionType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +// +// Internal function prototypes +// + +/** + Update the SMM CPU list per the pending operation. + + This function is called after return from SMI handlers. +**/ +VOID +SmmCpuUpdate ( + VOID + ); + +/** + Initialize SMM CPU Services. + + It installs EFI SMM CPU Services Protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + + @retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully. +**/ +EFI_STATUS +InitializeSmmCpuServices ( + IN EFI_HANDLE Handle + ); + +#endif diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Cet.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Cet.nasm new file mode 100644 index 000000000..0919d6d05 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Cet.nasm @@ -0,0 +1,33 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------- + +%include "Nasm.inc" + +SECTION .text + +global ASM_PFX(DisableCet) +ASM_PFX(DisableCet): + + ; Skip the pushed data for call + mov eax, 1 + INCSSP_EAX + + mov eax, cr4 + btr eax, 23 ; clear CET + mov cr4, eax + ret + +global ASM_PFX(EnableCet) +ASM_PFX(EnableCet): + + mov eax, cr4 + bts eax, 23 ; set CET + mov cr4, eax + + ; use jmp to skip the check for ret + pop eax + jmp eax + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm new file mode 100644 index 000000000..dbd1418c0 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.nasm @@ -0,0 +1,153 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpFuncs.nasm +; +; Abstract: +; +; This is the assembly code for Multi-processor S3 support +; +;------------------------------------------------------------------------------- + +SECTION .text + +extern ASM_PFX(InitializeFloatingPointUnits) + +%define VacantFlag 0x0 +%define NotVacantFlag 0xff + +%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart +%define StackStart LockLocation + 0x4 +%define StackSize LockLocation + 0x8 +%define RendezvousProc LockLocation + 0xC +%define GdtrProfile LockLocation + 0x10 +%define IdtrProfile LockLocation + 0x16 +%define BufferStart LockLocation + 0x1C + +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc procedure follows. All APs execute their procedure. This +;procedure serializes all the AP processors through an Init sequence. It must be +;noted that APs arrive here very raw...ie: real mode, no stack. +;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC +;IS IN MACHINE CODE. +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc (&WakeUpBuffer,MemAddress); + +BITS 16 +global ASM_PFX(RendezvousFunnelProc) +ASM_PFX(RendezvousFunnelProc): +RendezvousFunnelProcStart: + +; At this point CS = 0x(vv00) and ip= 0x0. + + mov ax, cs + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + +flat32Start: + + mov si, BufferStart + mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer + + mov si, GdtrProfile +o32 lgdt [cs:si] + + mov si, IdtrProfile +o32 lidt [cs:si] + + xor ax, ax + mov ds, ax + + mov eax, cr0 ; Get control register 0 + or eax, 0x000000001 ; Set PE bit (bit #0) + mov cr0, eax + +FLAT32_JUMP: + +a32 jmp dword 0x20:0x0 + +BITS 32 +PMODE_ENTRY: ; protected mode entry point + + mov ax, 0x8 +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax ; Flat mode setup. + + mov esi, edx + + mov edi, esi + add edi, LockLocation + mov al, NotVacantFlag +TestLock: + xchg byte [edi], al + cmp al, NotVacantFlag + jz TestLock + +ProgramStack: + + mov edi, esi + add edi, StackSize + mov eax, dword [edi] + mov edi, esi + add edi, StackStart + add eax, dword [edi] + mov esp, eax + mov dword [edi], eax + +Releaselock: + + mov al, VacantFlag + mov edi, esi + add edi, LockLocation + xchg byte [edi], al + + ; + ; Call assembly function to initialize FPU. + ; + mov ebx, ASM_PFX(InitializeFloatingPointUnits) + call ebx + ; + ; Call C Function + ; + mov edi, esi + add edi, RendezvousProc + mov eax, dword [edi] + + test eax, eax + jz GoToSleep + call eax ; Call C function + +GoToSleep: + cli + hlt + jmp $-2 + +RendezvousFunnelProcEnd: +;------------------------------------------------------------------------------------- +; AsmGetAddressMap (&AddressMap); +;------------------------------------------------------------------------------------- +global ASM_PFX(AsmGetAddressMap) +ASM_PFX(AsmGetAddressMap): + + pushad + mov ebp,esp + + mov ebx, dword [ebp+0x24] + mov dword [ebx], RendezvousFunnelProcStart + mov dword [ebx+0x4], PMODE_ENTRY - RendezvousFunnelProcStart + mov dword [ebx+0x8], FLAT32_JUMP - RendezvousFunnelProcStart + mov dword [ebx+0xc], RendezvousFunnelProcEnd - RendezvousFunnelProcStart + + popad + ret + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c new file mode 100644 index 000000000..2483f2ea8 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -0,0 +1,352 @@ +/** @file +Page table manipulation functions for IA-32 processors + +Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +/** + Disable CET. +**/ +VOID +EFIAPI +DisableCet ( + VOID + ); + +/** + Enable CET. +**/ +VOID +EFIAPI +EnableCet ( + VOID + ); + +/** + Create PageTable for SMM use. + + @return PageTable Address + +**/ +UINT32 +SmmInitPageTable ( + VOID + ) +{ + UINTN PageFaultHandlerHookAddress; + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + EFI_STATUS Status; + + // + // Initialize spin lock + // + InitializeSpinLock (mPFLock); + + mPhysicalAddressBits = 32; + + if (FeaturePcdGet (PcdCpuSmmProfileEnable) || + HEAP_GUARD_NONSTOP_MODE || + NULL_DETECTION_NONSTOP_MODE) { + // + // Set own Page Fault entry instead of the default one, because SMM Profile + // feature depends on IRET instruction to do Single Step + // + PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile; + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base; + IdtEntry += EXCEPT_IA32_PAGE_FAULT; + IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress; + IdtEntry->Bits.Reserved_0 = 0; + IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; + IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16); + } else { + // + // Register SMM Page Fault Handler + // + Status = SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler); + ASSERT_EFI_ERROR (Status); + } + + // + // Additional SMM IDT initialization for SMM stack guard + // + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + InitializeIDTSmmStackGuard (); + } + return Gen4GPageTable (TRUE); +} + +/** + Page Fault handler for SMM use. + +**/ +VOID +SmiDefaultPFHandler ( + VOID + ) +{ + CpuDeadLoop (); +} + +/** + ThePage Fault handler wrapper for SMM use. + + @param InterruptType Defines the type of interrupt or exception that + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. +**/ +VOID +EFIAPI +SmiPFHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINTN PFAddress; + UINTN GuardPageAddress; + UINTN CpuIndex; + + ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT); + + AcquireSpinLock (mPFLock); + + PFAddress = AsmReadCr2 (); + + // + // If a page fault occurs in SMRAM range, it might be in a SMM stack guard page, + // or SMM page protection violation. + // + if ((PFAddress >= mCpuHotPlugData.SmrrBase) && + (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) { + DumpCpuContext (InterruptType, SystemContext); + CpuIndex = GetCpuIndex (); + GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize); + if ((FeaturePcdGet (PcdCpuSmmStackGuard)) && + (PFAddress >= GuardPageAddress) && + (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) { + DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n")); + } else { + if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) { + DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%x)\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp); + ); + } else { + DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%x)\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip); + ); + } + + if (HEAP_GUARD_NONSTOP_MODE) { + GuardPagePFHandler (SystemContext.SystemContextIa32->ExceptionData); + goto Exit; + } + } + CpuDeadLoop (); + goto Exit; + } + + // + // If a page fault occurs in non-SMRAM range. + // + if ((PFAddress < mCpuHotPlugData.SmrrBase) || + (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) { + if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) { + DumpCpuContext (InterruptType, SystemContext); + DEBUG ((DEBUG_ERROR, "Code executed on IP(0x%x) out of SMM range after SMM is locked!\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp); + ); + CpuDeadLoop (); + goto Exit; + } + + // + // If NULL pointer was just accessed + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0 && + (PFAddress < EFI_PAGE_SIZE)) { + DumpCpuContext (InterruptType, SystemContext); + DEBUG ((DEBUG_ERROR, "!!! NULL pointer access !!!\n")); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip); + ); + + if (NULL_DETECTION_NONSTOP_MODE) { + GuardPagePFHandler (SystemContext.SystemContextIa32->ExceptionData); + goto Exit; + } + + CpuDeadLoop (); + goto Exit; + } + + 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)) { + SmmProfilePFHandler ( + SystemContext.SystemContextIa32->Eip, + SystemContext.SystemContextIa32->ExceptionData + ); + } else { + DumpCpuContext (InterruptType, SystemContext); + SmiDefaultPFHandler (); + } + +Exit: + ReleaseSpinLock (mPFLock); +} + +/** + This function sets memory attribute for page table. +**/ +VOID +SetPageTableAttributes ( + VOID + ) +{ + UINTN Index2; + UINTN Index3; + UINT64 *L1PageTable; + UINT64 *L2PageTable; + UINT64 *L3PageTable; + BOOLEAN IsSplitted; + BOOLEAN PageTableSplitted; + BOOLEAN CetEnabled; + + // + // Don't mark page table to read-only if heap guard is enabled. + // + // BIT2: SMM page guard enabled + // BIT3: SMM pool guard enabled + // + if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { + DEBUG ((DEBUG_INFO, "Don't mark page table to read-only as heap guard is enabled\n")); + return ; + } + + // + // Don't mark page table to read-only if SMM profile is enabled. + // + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + DEBUG ((DEBUG_INFO, "Don't mark page table to read-only as SMM profile is enabled\n")); + return ; + } + + DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); + + // + // Disable write protection, because we need mark page table to be write protected. + // We need *write* page table memory, to mark itself to be *read only*. + // + CetEnabled = ((AsmReadCr4() & CR4_CET_ENABLE) != 0) ? TRUE : FALSE; + if (CetEnabled) { + // + // CET must be disabled if WP is disabled. + // + DisableCet(); + } + AsmWriteCr0 (AsmReadCr0() & ~CR0_WP); + + do { + DEBUG ((DEBUG_INFO, "Start...\n")); + PageTableSplitted = FALSE; + + L3PageTable = (UINT64 *)GetPageTableBase (); + + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + + for (Index3 = 0; Index3 < 4; Index3++) { + L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L2PageTable == NULL) { + continue; + } + + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + + for (Index2 = 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++) { + if ((L2PageTable[Index2] & IA32_PG_PS) != 0) { + // 2M + continue; + } + L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L1PageTable == NULL) { + continue; + } + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + } + } + } while (PageTableSplitted); + + // + // Enable write protection, after page table updated. + // + AsmWriteCr0 (AsmReadCr0() | CR0_WP); + if (CetEnabled) { + // + // re-enable CET. + // + EnableCet(); + } + + return ; +} + +/** + This function returns with no action for 32 bit. + + @param[out] *Cr2 Pointer to variable to hold CR2 register value. +**/ +VOID +SaveCr2 ( + OUT UINTN *Cr2 + ) +{ + return ; +} + +/** + This function returns with no action for 32 bit. + + @param[in] Cr2 Value to write into CR2 register. +**/ +VOID +RestoreCr2 ( + IN UINTN Cr2 + ) +{ + 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/Semaphore.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c new file mode 100644 index 000000000..31ee067ad --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c @@ -0,0 +1,42 @@ +/** @file +Semaphore mechanism to indicate to the BSP that an AP has exited SMM +after SMBASE relocation. + +Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +UINTN mSmmRelocationOriginalAddress; +volatile BOOLEAN *mRebasedFlag; + +/** + Hook return address of SMM Save State so that semaphore code + can be executed immediately after AP exits SMM to indicate to + the BSP that an AP has exited SMM after SMBASE relocation. + + @param[in] CpuIndex The processor index. + @param[in] RebasedFlag A pointer to a flag that is set to TRUE + immediately after AP exits SMM. + +**/ +VOID +SemaphoreHook ( + IN UINTN CpuIndex, + IN volatile BOOLEAN *RebasedFlag + ) +{ + SMRAM_SAVE_STATE_MAP *CpuState; + + mRebasedFlag = RebasedFlag; + + CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET); + mSmmRelocationOriginalAddress = (UINTN)HookReturnFromSmm ( + CpuIndex, + CpuState, + (UINT64)(UINTN)&SmmRelocationSemaphoreComplete, + (UINT64)(UINTN)&SmmRelocationSemaphoreComplete + ); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm new file mode 100644 index 000000000..f96de9bde --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm @@ -0,0 +1,299 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiEntry.nasm +; +; Abstract: +; +; Code template of the SMI handler for a particular processor +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" +%include "Nasm.inc" + +%define MSR_IA32_S_CET 0x6A2 +%define MSR_IA32_CET_SH_STK_EN 0x1 +%define MSR_IA32_CET_WR_SHSTK_EN 0x2 +%define MSR_IA32_CET_ENDBR_EN 0x4 +%define MSR_IA32_CET_LEG_IW_EN 0x8 +%define MSR_IA32_CET_NO_TRACK_EN 0x10 +%define MSR_IA32_CET_SUPPRESS_DIS 0x20 +%define MSR_IA32_CET_SUPPRESS 0x400 +%define MSR_IA32_CET_TRACKER 0x800 +%define MSR_IA32_PL0_SSP 0x6A4 + +%define CR4_CET 0x800000 + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +; +; Constants relating to PROCESSOR_SMM_DESCRIPTOR +; +%define DSC_OFFSET 0xfb00 +%define DSC_GDTPTR 0x30 +%define DSC_GDTSIZ 0x38 +%define DSC_CS 14 +%define DSC_DS 16 +%define DSC_SS 18 +%define DSC_OTHERSEG 20 + +%define PROTECT_MODE_CS 0x8 +%define PROTECT_MODE_DS 0x20 +%define TSS_SEGMENT 0x40 + +extern ASM_PFX(SmiRendezvous) +extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) +extern ASM_PFX(CpuSmmDebugEntry) +extern ASM_PFX(CpuSmmDebugExit) + +global ASM_PFX(gcSmiHandlerTemplate) +global ASM_PFX(gcSmiHandlerSize) +global ASM_PFX(gPatchSmiCr3) +global ASM_PFX(gPatchSmiStack) +global ASM_PFX(gPatchSmbase) +extern ASM_PFX(mXdSupported) +global ASM_PFX(gPatchXdSupported) +extern ASM_PFX(gSmiHandlerIdtr) + +extern ASM_PFX(mCetSupported) +global ASM_PFX(mPatchCetSupported) +global ASM_PFX(mPatchCetPl0Ssp) +global ASM_PFX(mPatchCetInterruptSsp) + + SECTION .text + +BITS 16 +ASM_PFX(gcSmiHandlerTemplate): +_SmiEntryPoint: + mov bx, _GdtDesc - _SmiEntryPoint + 0x8000 + mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ] + dec ax + mov [cs:bx], ax + mov eax, [cs:DSC_OFFSET + DSC_GDTPTR] + mov [cs:bx + 2], eax + mov ebp, eax ; ebp = GDT base +o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx] + mov ax, PROTECT_MODE_CS + mov [cs:bx-0x2],ax + mov edi, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmbase): + lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000] + mov [cs:bx-0x6],eax + mov ebx, cr0 + and ebx, 0x9ffafff3 + or ebx, 0x23 + mov cr0, ebx + jmp dword 0x0:0x0 +_GdtDesc: + DW 0 + DD 0 + +BITS 32 +@32bit: + mov ax, PROTECT_MODE_DS +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax + mov esp, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmiStack): + mov eax, ASM_PFX(gSmiHandlerIdtr) + lidt [eax] + jmp ProtFlatMode + +ProtFlatMode: + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmiCr3): + mov cr3, eax +; +; Need to test for CR4 specific bit support +; + mov eax, 1 + cpuid ; use CPUID to determine if specific CR4 bits are supported + xor eax, eax ; Clear EAX + test edx, BIT2 ; Check for DE capabilities + jz .0 + or eax, BIT3 +.0: + test edx, BIT6 ; Check for PAE capabilities + jz .1 + or eax, BIT5 +.1: + test edx, BIT7 ; Check for MCE capabilities + jz .2 + or eax, BIT6 +.2: + test edx, BIT24 ; Check for FXSR capabilities + jz .3 + or eax, BIT9 +.3: + test edx, BIT25 ; Check for SSE capabilities + jz .4 + or eax, BIT10 +.4: ; as cr4.PGE is not set here, refresh cr3 + mov cr4, eax ; in PreModifyMtrrs() to flush TLB. + + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 + jz .6 +; Load TSS + mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag + mov eax, TSS_SEGMENT + ltr ax +.6: + +; enable NXE if supported + mov al, strict byte 1 ; source operand may be patched +ASM_PFX(gPatchXdSupported): + cmp al, 0 + jz @SkipXd +; +; Check XD disable bit +; + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + push edx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .5 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.5: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr + jmp @XdDone +@SkipXd: + sub esp, 4 +@XdDone: + + mov ebx, cr0 + or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, ebx + lea ebx, [edi + DSC_OFFSET] + mov ax, [ebx + DSC_DS] + mov ds, eax + mov ax, [ebx + DSC_OTHERSEG] + mov es, eax + mov fs, eax + mov gs, eax + mov ax, [ebx + DSC_SS] + mov ss, eax + + mov ebx, [esp + 4] ; ebx <- CpuIndex + +; enable CET if supported + mov al, strict byte 1 ; source operand may be patched +ASM_PFX(mPatchCetSupported): + cmp al, 0 + jz CetDone + + mov ecx, MSR_IA32_S_CET + rdmsr + push edx + push eax + + mov ecx, MSR_IA32_PL0_SSP + rdmsr + push edx + push eax + + mov ecx, MSR_IA32_S_CET + mov eax, MSR_IA32_CET_SH_STK_EN + xor edx, edx + wrmsr + + mov ecx, MSR_IA32_PL0_SSP + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(mPatchCetPl0Ssp): + xor edx, edx + wrmsr + mov ecx, cr0 + btr ecx, 16 ; clear WP + mov cr0, ecx + mov [eax], eax ; reload SSP, and clear busyflag. + xor ecx, ecx + mov [eax + 4], ecx + + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(mPatchCetInterruptSsp): + cmp eax, 0 + jz CetInterruptDone + mov [eax], eax ; reload SSP, and clear busyflag. + xor ecx, ecx + mov [eax + 4], ecx +CetInterruptDone: + + mov ecx, cr0 + bts ecx, 16 ; set WP + mov cr0, ecx + + mov eax, 0x668 | CR4_CET + mov cr4, eax + + SETSSBSY + +CetDone: + + push ebx + mov eax, ASM_PFX(CpuSmmDebugEntry) + call eax + add esp, 4 + + push ebx + mov eax, ASM_PFX(SmiRendezvous) + call eax + add esp, 4 + + push ebx + mov eax, ASM_PFX(CpuSmmDebugExit) + call eax + add esp, 4 + + mov eax, ASM_PFX(mCetSupported) + mov al, [eax] + cmp al, 0 + jz CetDone2 + + mov eax, 0x668 + mov cr4, eax ; disable CET + + mov ecx, MSR_IA32_PL0_SSP + pop eax + pop edx + wrmsr + + mov ecx, MSR_IA32_S_CET + pop eax + pop edx + wrmsr +CetDone2: + + mov eax, ASM_PFX(mXdSupported) + mov al, [eax] + cmp al, 0 + jz .7 + pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .7 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.7: + + StuffRsb32 + rsm + +ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint + +global ASM_PFX(PiSmmCpuSmiEntryFixupAddress) +ASM_PFX(PiSmmCpuSmiEntryFixupAddress): + ret diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm new file mode 100644 index 000000000..e7b85a994 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm @@ -0,0 +1,705 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiException.nasm +; +; Abstract: +; +; Exception handlers used in SM mode +; +;------------------------------------------------------------------------------- + +extern ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable)) +extern ASM_PFX(SmiPFHandler) +extern ASM_PFX(mSetupDebugTrap) + +global ASM_PFX(gcSmiIdtr) +global ASM_PFX(gcSmiGdtr) +global ASM_PFX(gTaskGateDescriptor) +global ASM_PFX(gcPsd) + + SECTION .data + +NullSeg: DQ 0 ; reserved by architecture +CodeSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +ProtModeCodeSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +ProtModeSsSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x93 + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +DataSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x93 + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +CodeSeg16: + DW -1 + DW 0 + DB 0 + DB 0x9b + DB 0x8f + DB 0 +DataSeg16: + DW -1 + DW 0 + DB 0 + DB 0x93 + DB 0x8f + DB 0 +CodeSeg64: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xaf ; LimitHigh + DB 0 ; BaseHigh +GDT_SIZE equ $ - NullSeg + +TssSeg: + DW TSS_DESC_SIZE ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x89 + DB 0x80 ; LimitHigh + DB 0 ; BaseHigh +ExceptionTssSeg: + DW EXCEPTION_TSS_DESC_SIZE ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x89 + DB 0x80 ; LimitHigh + DB 0 ; BaseHigh + +CODE_SEL equ CodeSeg32 - NullSeg +DATA_SEL equ DataSeg32 - NullSeg +TSS_SEL equ TssSeg - NullSeg +EXCEPTION_TSS_SEL equ ExceptionTssSeg - NullSeg + +struc IA32_TSS + resw 1 + resw 1 + .ESP0: resd 1 + .SS0: resw 1 + resw 1 + .ESP1: resd 1 + .SS1: resw 1 + resw 1 + .ESP2: resd 1 + .SS2: resw 1 + resw 1 + ._CR3: resd 1 + .EIP: resd 1 + .EFLAGS: resd 1 + ._EAX: resd 1 + ._ECX: resd 1 + ._EDX: resd 1 + ._EBX: resd 1 + ._ESP: resd 1 + ._EBP: resd 1 + ._ESI: resd 1 + ._EDI: resd 1 + ._ES: resw 1 + resw 1 + ._CS: resw 1 + resw 1 + ._SS: resw 1 + resw 1 + ._DS: resw 1 + resw 1 + ._FS: resw 1 + resw 1 + ._GS: resw 1 + resw 1 + .LDT: resw 1 + resw 1 + resw 1 + resw 1 +endstruc + +; Create 2 TSS segments just after GDT +TssDescriptor: + DW 0 ; PreviousTaskLink + DW 0 ; Reserved + DD 0 ; ESP0 + DW 0 ; SS0 + DW 0 ; Reserved + DD 0 ; ESP1 + DW 0 ; SS1 + DW 0 ; Reserved + DD 0 ; ESP2 + DW 0 ; SS2 + DW 0 ; Reserved + DD 0 ; CR3 + DD 0 ; EIP + DD 0 ; EFLAGS + DD 0 ; EAX + DD 0 ; ECX + DD 0 ; EDX + DD 0 ; EBX + DD 0 ; ESP + DD 0 ; EBP + DD 0 ; ESI + DD 0 ; EDI + DW 0 ; ES + DW 0 ; Reserved + DW 0 ; CS + DW 0 ; Reserved + DW 0 ; SS + DW 0 ; Reserved + DW 0 ; DS + DW 0 ; Reserved + DW 0 ; FS + DW 0 ; Reserved + DW 0 ; GS + DW 0 ; Reserved + DW 0 ; LDT Selector + DW 0 ; Reserved + DW 0 ; T + DW 0 ; I/O Map Base +TSS_DESC_SIZE equ $ - TssDescriptor + +ExceptionTssDescriptor: + DW 0 ; PreviousTaskLink + DW 0 ; Reserved + DD 0 ; ESP0 + DW 0 ; SS0 + DW 0 ; Reserved + DD 0 ; ESP1 + DW 0 ; SS1 + DW 0 ; Reserved + DD 0 ; ESP2 + DW 0 ; SS2 + DW 0 ; Reserved + DD 0 ; CR3 + DD PFHandlerEntry ; EIP + DD 00000002 ; EFLAGS + DD 0 ; EAX + DD 0 ; ECX + DD 0 ; EDX + DD 0 ; EBX + DD 0 ; ESP + DD 0 ; EBP + DD 0 ; ESI + DD 0 ; EDI + DW DATA_SEL ; ES + DW 0 ; Reserved + DW CODE_SEL ; CS + DW 0 ; Reserved + DW DATA_SEL ; SS + DW 0 ; Reserved + DW DATA_SEL ; DS + DW 0 ; Reserved + DW DATA_SEL ; FS + DW 0 ; Reserved + DW DATA_SEL ; GS + DW 0 ; Reserved + DW 0 ; LDT Selector + DW 0 ; Reserved + DW 0 ; T + DW 0 ; I/O Map Base + DD 0 ; SSP +EXCEPTION_TSS_DESC_SIZE equ $ - ExceptionTssDescriptor + +ASM_PFX(gcPsd): + DB 'PSDSIG ' + DW PSD_SIZE + DW 2 + DW 1 << 2 + DW CODE_SEL + DW DATA_SEL + DW DATA_SEL + DW DATA_SEL + DW 0 + DQ 0 + DQ 0 + DQ 0 + DD 0 + DD NullSeg + DD GDT_SIZE + DD 0 + times 24 DB 0 + DD 0 + DD 0 +PSD_SIZE equ $ - ASM_PFX(gcPsd) + +ASM_PFX(gcSmiGdtr): + DW GDT_SIZE - 1 + DD NullSeg + +ASM_PFX(gcSmiIdtr): + DW 0 + DD 0 + +ASM_PFX(gTaskGateDescriptor): + DW 0 ; Reserved + DW EXCEPTION_TSS_SEL ; TSS Segment selector + DB 0 ; Reserved + DB 0x85 ; Task Gate, present, DPL = 0 + DW 0 ; Reserved + + SECTION .text +;------------------------------------------------------------------------------ +; PageFaultIdtHandlerSmmProfile is the entry point page fault only +; +; +; Stack: +; +---------------------+ +; + EFlags + +; +---------------------+ +; + CS + +; +---------------------+ +; + EIP + +; +---------------------+ +; + Error Code + +; +---------------------+ +; + Vector Number + +; +---------------------+ +; + EBP + +; +---------------------+ <-- EBP +; +; +;------------------------------------------------------------------------------ +global ASM_PFX(PageFaultIdtHandlerSmmProfile) +ASM_PFX(PageFaultIdtHandlerSmmProfile): + push 0xe ; Page Fault + + push ebp + mov ebp, esp + + ; + ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 + ; is 16-byte aligned + ; + and esp, 0xfffffff0 + sub esp, 12 + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + push eax + push ecx + push edx + push ebx + lea ecx, [ebp + 6 * 4] + push ecx ; ESP + push dword [ebp] ; EBP + push esi + push edi + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; + mov eax, ss + push eax + movzx eax, word [ebp + 4 * 4] + push eax + mov eax, ds + push eax + mov eax, es + push eax + mov eax, fs + push eax + mov eax, gs + push eax + +;; UINT32 Eip; + mov eax, [ebp + 3 * 4] + push eax + +;; UINT32 Gdtr[2], Idtr[2]; + sub esp, 8 + sidt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + + sub esp, 8 + sgdt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + +;; UINT32 Ldtr, Tr; + xor eax, eax + str ax + push eax + sldt ax + push eax + +;; UINT32 EFlags; + mov eax, [ebp + 5 * 4] + push eax + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + mov eax, cr4 + or eax, 0x208 + mov cr4, eax + push eax + mov eax, cr3 + push eax + mov eax, cr2 + push eax + xor eax, eax + push eax + mov eax, cr0 + push eax + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov eax, dr7 + push eax + mov eax, dr6 + push eax + mov eax, dr3 + push eax + mov eax, dr2 + push eax + mov eax, dr1 + push eax + mov eax, dr0 + push eax + +;; FX_SAVE_STATE_IA32 FxSaveState; + sub esp, 512 + mov edi, esp + fxsave [edi] + +; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear + cld + +;; UINT32 ExceptionData; + push dword [ebp + 2 * 4] + +;; call into exception handler + +;; Prepare parameter and call + mov edx, esp + push edx + mov edx, dword [ebp + 1 * 4] + push edx + + ; + ; Call External Exception Handler + ; + mov eax, ASM_PFX(SmiPFHandler) + call eax + add esp, 8 + +;; UINT32 ExceptionData; + add esp, 4 + +;; FX_SAVE_STATE_IA32 FxSaveState; + mov esi, esp + fxrstor [esi] + add esp, 512 + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; Skip restoration of DRx registers to support debuggers +;; that set breakpoint in interrupt/exception context + add esp, 4 * 6 + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + pop eax + mov cr0, eax + add esp, 4 ; not for Cr1 + pop eax + mov cr2, eax + pop eax + mov cr3, eax + pop eax + mov cr4, eax + +;; UINT32 EFlags; + pop dword [ebp + 5 * 4] + +;; UINT32 Ldtr, Tr; +;; UINT32 Gdtr[2], Idtr[2]; +;; Best not let anyone mess with these particular registers... + add esp, 24 + +;; UINT32 Eip; + pop dword [ebp + 3 * 4] + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; +;; NOTE - modified segment registers could hang the debugger... We +;; could attempt to insulate ourselves against this possibility, +;; but that poses risks as well. +;; + pop gs + pop fs + pop es + pop ds + pop dword [ebp + 4 * 4] + pop ss + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + pop edi + pop esi + add esp, 4 ; not for ebp + add esp, 4 ; not for esp + pop ebx + pop edx + pop ecx + pop eax + + mov esp, ebp + pop ebp + +; Enable TF bit after page fault handler runs + bts dword [esp + 16], 8 ; EFLAGS + + add esp, 8 ; skip INT# & ErrCode +Return: + iretd +; +; Page Fault Exception Handler entry when SMM Stack Guard is enabled +; Executiot starts here after a task switch +; +PFHandlerEntry: +; +; Get this processor's TSS +; + sub esp, 8 + sgdt [esp + 2] + mov eax, [esp + 4] ; GDT base + add esp, 8 + mov ecx, [eax + TSS_SEL + 2] + shl ecx, 8 + mov cl, [eax + TSS_SEL + 7] + ror ecx, 8 ; ecx = TSS base + + mov ebp, esp + + ; + ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 + ; is 16-byte aligned + ; + and esp, 0xfffffff0 + sub esp, 12 + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + push dword [ecx + IA32_TSS._EAX] + push dword [ecx + IA32_TSS._ECX] + push dword [ecx + IA32_TSS._EDX] + push dword [ecx + IA32_TSS._EBX] + push dword [ecx + IA32_TSS._ESP] + push dword [ecx + IA32_TSS._EBP] + push dword [ecx + IA32_TSS._ESI] + push dword [ecx + IA32_TSS._EDI] + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; + movzx eax, word [ecx + IA32_TSS._SS] + push eax + movzx eax, word [ecx + IA32_TSS._CS] + push eax + movzx eax, word [ecx + IA32_TSS._DS] + push eax + movzx eax, word [ecx + IA32_TSS._ES] + push eax + movzx eax, word [ecx + IA32_TSS._FS] + push eax + movzx eax, word [ecx + IA32_TSS._GS] + push eax + +;; UINT32 Eip; + push dword [ecx + IA32_TSS.EIP] + +;; UINT32 Gdtr[2], Idtr[2]; + sub esp, 8 + sidt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + + sub esp, 8 + sgdt [esp] + mov eax, [esp + 2] + xchg eax, [esp] + and eax, 0xFFFF + mov [esp+4], eax + +;; UINT32 Ldtr, Tr; + mov eax, TSS_SEL + push eax + movzx eax, word [ecx + IA32_TSS.LDT] + push eax + +;; UINT32 EFlags; + push dword [ecx + IA32_TSS.EFLAGS] + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + mov eax, cr4 + or eax, 0x208 + mov cr4, eax + push eax + mov eax, cr3 + push eax + mov eax, cr2 + push eax + xor eax, eax + push eax + mov eax, cr0 + push eax + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov eax, dr7 + push eax + mov eax, dr6 + push eax + mov eax, dr3 + push eax + mov eax, dr2 + push eax + mov eax, dr1 + push eax + mov eax, dr0 + push eax + +;; FX_SAVE_STATE_IA32 FxSaveState; +;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM) +;; when executing fxsave/fxrstor instruction + clts + sub esp, 512 + mov edi, esp + fxsave [edi] + +; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear + cld + +;; UINT32 ExceptionData; + push dword [ebp] + +;; call into exception handler + mov ebx, ecx + mov eax, ASM_PFX(SmiPFHandler) + +;; Prepare parameter and call + mov edx, esp + push edx + mov edx, 14 + push edx + + ; + ; Call External Exception Handler + ; + call eax + add esp, 8 + + mov ecx, ebx +;; UINT32 ExceptionData; + add esp, 4 + +;; FX_SAVE_STATE_IA32 FxSaveState; + mov esi, esp + fxrstor [esi] + add esp, 512 + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; Skip restoration of DRx registers to support debuggers +;; that set breakpoints in interrupt/exception context + add esp, 4 * 6 + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + pop eax + mov cr0, eax + add esp, 4 ; not for Cr1 + pop eax + mov cr2, eax + pop eax + mov dword [ecx + IA32_TSS._CR3], eax + pop eax + mov cr4, eax + +;; UINT32 EFlags; + pop dword [ecx + IA32_TSS.EFLAGS] + +;; UINT32 Ldtr, Tr; +;; UINT32 Gdtr[2], Idtr[2]; +;; Best not let anyone mess with these particular registers... + add esp, 24 + +;; UINT32 Eip; + pop dword [ecx + IA32_TSS.EIP] + +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; +;; NOTE - modified segment registers could hang the debugger... We +;; could attempt to insulate ourselves against this possibility, +;; but that poses risks as well. +;; + pop eax +o16 mov [ecx + IA32_TSS._GS], ax + pop eax +o16 mov [ecx + IA32_TSS._FS], ax + pop eax +o16 mov [ecx + IA32_TSS._ES], ax + pop eax +o16 mov [ecx + IA32_TSS._DS], ax + pop eax +o16 mov [ecx + IA32_TSS._CS], ax + pop eax +o16 mov [ecx + IA32_TSS._SS], ax + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + pop dword [ecx + IA32_TSS._EDI] + pop dword [ecx + IA32_TSS._ESI] + add esp, 4 ; not for ebp + add esp, 4 ; not for esp + pop dword [ecx + IA32_TSS._EBX] + pop dword [ecx + IA32_TSS._EDX] + pop dword [ecx + IA32_TSS._ECX] + pop dword [ecx + IA32_TSS._EAX] + + mov esp, ebp + +; Set single step DB# if SMM profile is enabled and page fault exception happens + cmp byte [dword ASM_PFX(mSetupDebugTrap)], 0 + jz @Done2 + +; Create return context for iretd in stub function + mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack pointer + mov ebx, dword [ecx + IA32_TSS.EIP] + mov [eax - 0xc], ebx ; create EIP in old stack + movzx ebx, word [ecx + IA32_TSS._CS] + mov [eax - 0x8], ebx ; create CS in old stack + mov ebx, dword [ecx + IA32_TSS.EFLAGS] + bts ebx, 8 + mov [eax - 0x4], ebx ; create eflags in old stack + mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack pointer + sub eax, 0xc ; minus 12 byte + mov dword [ecx + IA32_TSS._ESP], eax ; Set new stack pointer +; Replace the EIP of interrupted task with stub function + mov eax, ASM_PFX(PageFaultStubFunction) + mov dword [ecx + IA32_TSS.EIP], eax +; Jump to the iretd so next page fault handler as a task will start again after iretd. +@Done2: + add esp, 4 ; skip ErrCode + + jmp Return + +global ASM_PFX(PageFaultStubFunction) +ASM_PFX(PageFaultStubFunction): +; +; we need clean TS bit in CR0 to execute +; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions. +; + clts + iretd + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c new file mode 100644 index 000000000..ef277349d --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c @@ -0,0 +1,204 @@ +/** @file + SMM CPU misc functions for Ia32 arch specific. + +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +extern UINT64 gTaskGateDescriptor; + +EFI_PHYSICAL_ADDRESS mGdtBuffer; +UINTN mGdtBufferSize; + +extern BOOLEAN mCetSupported; +extern UINTN mSmmShadowStackSize; + +X86_ASSEMBLY_PATCH_LABEL mPatchCetPl0Ssp; +X86_ASSEMBLY_PATCH_LABEL mPatchCetInterruptSsp; +UINT32 mCetPl0Ssp; +UINT32 mCetInterruptSsp; + +/** + Initialize IDT for SMM Stack Guard. + +**/ +VOID +EFIAPI +InitializeIDTSmmStackGuard ( + VOID + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtGate; + + // + // If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT + // is a Task Gate Descriptor so that when a Page Fault Exception occurs, + // the processors can use a known good stack in case stack is ran out. + // + IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base; + IdtGate += EXCEPT_IA32_PAGE_FAULT; + IdtGate->Uint64 = gTaskGateDescriptor; +} + +/** + Initialize Gdt for all processors. + + @param[in] Cr3 CR3 value. + @param[out] GdtStepSize The step size for GDT table. + + @return GdtBase for processor 0. + GdtBase for processor X is: GdtBase + (GdtStepSize * X) +**/ +VOID * +InitGdt ( + IN UINTN Cr3, + OUT UINTN *GdtStepSize + ) +{ + UINTN Index; + IA32_SEGMENT_DESCRIPTOR *GdtDescriptor; + UINTN TssBase; + UINTN GdtTssTableSize; + UINT8 *GdtTssTables; + UINTN GdtTableStepSize; + UINTN InterruptShadowStack; + + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // For IA32 SMM, if SMM Stack Guard feature is enabled, we use 2 TSS. + // in this case, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention + // on each SMI entry. + // + + // + // Enlarge GDT to contain 2 TSS descriptors + // + gcSmiGdtr.Limit += (UINT16)(2 * sizeof (IA32_SEGMENT_DESCRIPTOR)); + + GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + EXCEPTION_TSS_SIZE + 7) & ~7; // 8 bytes aligned + mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + // + // IA32 Stack Guard need use task switch to switch stack that need + // write GDT and TSS, so AllocateCodePages() could not be used here + // as code pages will be set to RO. + // + GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (mGdtBufferSize)); + ASSERT (GdtTssTables != NULL); + mGdtBuffer = (UINTN)GdtTssTables; + GdtTableStepSize = GdtTssTableSize; + + for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { + CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE + EXCEPTION_TSS_SIZE); + // + // Fixup TSS descriptors + // + TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1); + GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2; + GdtDescriptor->Bits.BaseLow = (UINT16)TssBase; + GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16); + GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24); + + TssBase += TSS_SIZE; + GdtDescriptor++; + GdtDescriptor->Bits.BaseLow = (UINT16)TssBase; + GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16); + GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24); + // + // Fixup TSS segments + // + // ESP as known good stack + // + *(UINTN *)(TssBase + TSS_IA32_ESP_OFFSET) = mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize; + *(UINT32 *)(TssBase + TSS_IA32_CR3_OFFSET) = Cr3; + + // + // Setup ShadowStack for stack switch + // + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + InterruptShadowStack = (UINTN)(mSmmStackArrayBase + mSmmStackSize + EFI_PAGES_TO_SIZE (1) - sizeof(UINT64) + (mSmmStackSize + mSmmShadowStackSize) * Index); + *(UINT32 *)(TssBase + TSS_IA32_SSP_OFFSET) = (UINT32)InterruptShadowStack; + } + } + } else { + // + // Just use original table, AllocatePage and copy them here to make sure GDTs are covered in page memory. + // + GdtTssTableSize = gcSmiGdtr.Limit + 1; + mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize)); + ASSERT (GdtTssTables != NULL); + mGdtBuffer = (UINTN)GdtTssTables; + GdtTableStepSize = GdtTssTableSize; + + for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { + CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1); + } + } + + *GdtStepSize = GdtTableStepSize; + return GdtTssTables; +} + +/** + Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. + + @param[in] ApHltLoopCode The address of the safe hlt-loop function. + @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. + @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. + +**/ +VOID +TransferApToSafeState ( + IN UINTN ApHltLoopCode, + IN UINTN TopOfStack, + IN UINTN NumberToFinishAddress + ) +{ + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)ApHltLoopCode, + (VOID *)NumberToFinishAddress, + NULL, + (VOID *)TopOfStack + ); + // + // It should never reach here + // + ASSERT (FALSE); +} + +/** + Initialize the shadow stack related data structure. + + @param CpuIndex The index of CPU. + @param ShadowStack The bottom of the shadow stack for this CPU. +**/ +VOID +InitShadowStack ( + IN UINTN CpuIndex, + IN VOID *ShadowStack + ) +{ + UINTN SmmShadowStackSize; + + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + SmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize))); + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + SmmShadowStackSize += EFI_PAGES_TO_SIZE (2); + } + mCetPl0Ssp = (UINT32)((UINTN)ShadowStack + SmmShadowStackSize - sizeof(UINT64)); + PatchInstructionX86 (mPatchCetPl0Ssp, mCetPl0Ssp, 4); + DEBUG ((DEBUG_INFO, "mCetPl0Ssp - 0x%x\n", mCetPl0Ssp)); + DEBUG ((DEBUG_INFO, "ShadowStack - 0x%x\n", ShadowStack)); + DEBUG ((DEBUG_INFO, " SmmShadowStackSize - 0x%x\n", SmmShadowStackSize)); + + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + mCetInterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64)); + PatchInstructionX86 (mPatchCetInterruptSsp, mCetInterruptSsp, 4); + DEBUG ((DEBUG_INFO, "mCetInterruptSsp - 0x%x\n", mCetInterruptSsp)); + } + } +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm new file mode 100644 index 000000000..b5e77a1a5 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm @@ -0,0 +1,96 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmmInit.nasm +; +; Abstract: +; +; Functions for relocating SMBASE's for all processors +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +extern ASM_PFX(SmmInitHandler) +extern ASM_PFX(mRebasedFlag) +extern ASM_PFX(mSmmRelocationOriginalAddress) + +global ASM_PFX(gPatchSmmCr3) +global ASM_PFX(gPatchSmmCr4) +global ASM_PFX(gPatchSmmCr0) +global ASM_PFX(gPatchSmmInitStack) +global ASM_PFX(gcSmiInitGdtr) +global ASM_PFX(gcSmmInitSize) +global ASM_PFX(gcSmmInitTemplate) + +%define PROTECT_MODE_CS 0x8 +%define PROTECT_MODE_DS 0x20 + + SECTION .text + +ASM_PFX(gcSmiInitGdtr): + DW 0 + DQ 0 + +global ASM_PFX(SmmStartup) + +BITS 16 +ASM_PFX(SmmStartup): + mov eax, 0x80000001 ; read capability + cpuid + mov ebx, edx ; rdmsr will change edx. keep it in ebx. + and ebx, BIT20 ; extract NX capability bit + shr ebx, 9 ; shift bit to IA32_EFER.NXE[BIT11] position + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr3): + mov cr3, eax +o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr4): + mov cr4, eax + mov ecx, 0xc0000080 ; IA32_EFER MSR + rdmsr + or eax, ebx ; set NXE bit if NX is available + wrmsr + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr0): + mov di, PROTECT_MODE_DS + mov cr0, eax + jmp PROTECT_MODE_CS : dword @32bit + +BITS 32 +@32bit: + mov ds, edi + mov es, edi + mov fs, edi + mov gs, edi + mov ss, edi + mov esp, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmInitStack): + call ASM_PFX(SmmInitHandler) + StuffRsb32 + rsm + +BITS 16 +ASM_PFX(gcSmmInitTemplate): + mov ebp, ASM_PFX(SmmStartup) + sub ebp, 0x30000 + jmp ebp + +ASM_PFX(gcSmmInitSize): DW $ - ASM_PFX(gcSmmInitTemplate) + +BITS 32 +global ASM_PFX(SmmRelocationSemaphoreComplete) +ASM_PFX(SmmRelocationSemaphoreComplete): + push eax + mov eax, [ASM_PFX(mRebasedFlag)] + mov byte [eax], 1 + pop eax + jmp [ASM_PFX(mSmmRelocationOriginalAddress)] + +global ASM_PFX(PiSmmCpuSmmInitFixupAddress) +ASM_PFX(PiSmmCpuSmmInitFixupAddress): + ret diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c new file mode 100644 index 000000000..e83031fc0 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c @@ -0,0 +1,74 @@ +/** @file +IA-32 processor specific functions to enable SMM profile. + +Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" +#include "SmmProfileInternal.h" + +/** + Create SMM page table for S3 path. + +**/ +VOID +InitSmmS3Cr3 ( + VOID + ) +{ + mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (TRUE); + + return ; +} + +/** + Allocate pages for creating 4KB-page based on 2MB-page when page fault happens. + 32-bit firmware does not need it. + +**/ +VOID +InitPagesForPFHandler ( + VOID + ) +{ +} + +/** + 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. 32-bit firmware does not need it. + + @param PageTable PageTable Address. + @param PFAddress The memory address which caused page fault exception. + @param CpuIndex The index of the processor. + @param ErrorCode The Error code of exception. + @param IsValidPFAddress The flag indicates if SMM profile data need be added. + +**/ +VOID +RestorePageTableAbove4G ( + UINT64 *PageTable, + UINT64 PFAddress, + UINTN CpuIndex, + UINTN ErrorCode, + BOOLEAN *IsValidPFAddress + ) +{ +} + +/** + Clear TF in FLAGS. + + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. + +**/ +VOID +ClearTrapFlag ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ) +{ + SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h new file mode 100644 index 000000000..533e8561b --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h @@ -0,0 +1,91 @@ +/** @file +IA-32 processor specific header file to enable SMM profile. + +Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_PROFILE_ARCH_H_ +#define _SMM_PROFILE_ARCH_H_ + +#pragma pack (1) + +typedef struct _MSR_DS_AREA_STRUCT { + UINT32 BTSBufferBase; + UINT32 BTSIndex; + UINT32 BTSAbsoluteMaximum; + UINT32 BTSInterruptThreshold; + UINT32 PEBSBufferBase; + UINT32 PEBSIndex; + UINT32 PEBSAbsoluteMaximum; + UINT32 PEBSInterruptThreshold; + UINT32 PEBSCounterReset[4]; + UINT32 Reserved; +} MSR_DS_AREA_STRUCT; + +typedef struct _BRANCH_TRACE_RECORD { + UINT32 LastBranchFrom; + UINT32 LastBranchTo; + UINT32 Rsvd0 : 4; + UINT32 BranchPredicted : 1; + UINT32 Rsvd1 : 27; +} BRANCH_TRACE_RECORD; + +typedef struct _PEBS_RECORD { + UINT32 Eflags; + UINT32 LinearIP; + UINT32 Eax; + UINT32 Ebx; + UINT32 Ecx; + UINT32 Edx; + UINT32 Esi; + UINT32 Edi; + UINT32 Ebp; + UINT32 Esp; +} PEBS_RECORD; + +#pragma pack () + +#define PHYSICAL_ADDRESS_MASK ((1ull << 32) - SIZE_4KB) + +/** + 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. 32-bit firmware does not need it. + + @param PageTable PageTable Address. + @param PFAddress The memory address which caused page fault exception. + @param CpuIndex The index of the processor. + @param ErrorCode The Error code of exception. + @param IsValidPFAddress The flag indicates if SMM profile data need be added. + +**/ +VOID +RestorePageTableAbove4G ( + UINT64 *PageTable, + UINT64 PFAddress, + UINTN CpuIndex, + UINTN ErrorCode, + BOOLEAN *IsValidPFAddress + ); + +/** + Create SMM page table for S3 path. + +**/ +VOID +InitSmmS3Cr3 ( + VOID + ); + +/** + Allocate pages for creating 4KB-page based on 2MB-page when page fault happens. + +**/ +VOID +InitPagesForPFHandler ( + VOID + ); + +#endif // _SMM_PROFILE_ARCH_H_ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c new file mode 100644 index 000000000..57e788c01 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -0,0 +1,1995 @@ +/** @file +SMM MP service implementation + +Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +// +// Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE) +// +MTRR_SETTINGS gSmiMtrrs; +UINT64 gPhyMask; +SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData = NULL; +UINTN mSmmMpSyncDataSize; +SMM_CPU_SEMAPHORES mSmmCpuSemaphores; +UINTN mSemaphoreSize; +SPIN_LOCK *mPFLock = NULL; +SMM_CPU_SYNC_MODE mCpuSmmSyncMode; +BOOLEAN mMachineCheckSupported = FALSE; + +/** + Performs an atomic compare exchange operation to get semaphore. + The compare exchange operation must be performed using + MP safe mechanisms. + + @param Sem IN: 32-bit unsigned integer + OUT: original integer - 1 + @return Original integer - 1 + +**/ +UINT32 +WaitForSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + UINT32 Value; + + do { + Value = *Sem; + } while (Value == 0 || + InterlockedCompareExchange32 ( + (UINT32*)Sem, + Value, + Value - 1 + ) != Value); + return Value - 1; +} + + +/** + Performs an atomic compare exchange operation to release semaphore. + The compare exchange operation must be performed using + MP safe mechanisms. + + @param Sem IN: 32-bit unsigned integer + OUT: original integer + 1 + @return Original integer + 1 + +**/ +UINT32 +ReleaseSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + UINT32 Value; + + do { + Value = *Sem; + } while (Value + 1 != 0 && + InterlockedCompareExchange32 ( + (UINT32*)Sem, + Value, + Value + 1 + ) != Value); + return Value + 1; +} + +/** + Performs an atomic compare exchange operation to lock semaphore. + The compare exchange operation must be performed using + MP safe mechanisms. + + @param Sem IN: 32-bit unsigned integer + OUT: -1 + @return Original integer + +**/ +UINT32 +LockdownSemaphore ( + IN OUT volatile UINT32 *Sem + ) +{ + UINT32 Value; + + do { + Value = *Sem; + } while (InterlockedCompareExchange32 ( + (UINT32*)Sem, + Value, (UINT32)-1 + ) != Value); + return Value; +} + +/** + Wait all APs to performs an atomic compare exchange operation to release semaphore. + + @param NumberOfAPs AP number + +**/ +VOID +WaitForAllAPs ( + IN UINTN NumberOfAPs + ) +{ + UINTN BspIndex; + + BspIndex = mSmmMpSyncData->BspIndex; + while (NumberOfAPs-- > 0) { + WaitForSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + } +} + +/** + Performs an atomic compare exchange operation to release semaphore + for each AP. + +**/ +VOID +ReleaseAllAPs ( + VOID + ) +{ + UINTN Index; + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (IsPresentAp (Index)) { + ReleaseSemaphore (mSmmMpSyncData->CpuData[Index].Run); + } + } +} + +/** + Checks if all CPUs (with certain exceptions) have checked in for this SMI run + + @param Exceptions CPU Arrival exception flags. + + @retval TRUE if all CPUs the have checked in. + @retval FALSE if at least one Normal AP hasn't checked in. + +**/ +BOOLEAN +AllCpusInSmmWithExceptions ( + SMM_CPU_ARRIVAL_EXCEPTIONS Exceptions + ) +{ + UINTN Index; + SMM_CPU_DATA_BLOCK *CpuData; + EFI_PROCESSOR_INFORMATION *ProcessorInfo; + + ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus); + + if (*mSmmMpSyncData->Counter == mNumberOfCpus) { + return TRUE; + } + + CpuData = mSmmMpSyncData->CpuData; + ProcessorInfo = gSmmCpuPrivate->ProcessorInfo; + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (!(*(CpuData[Index].Present)) && ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) { + if (((Exceptions & ARRIVAL_EXCEPTION_DELAYED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmDelayed) != 0) { + continue; + } + if (((Exceptions & ARRIVAL_EXCEPTION_BLOCKED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmBlocked) != 0) { + continue; + } + if (((Exceptions & ARRIVAL_EXCEPTION_SMI_DISABLED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmEnable) != 0) { + continue; + } + return FALSE; + } + } + + + return TRUE; +} + +/** + Has OS enabled Lmce in the MSR_IA32_MCG_EXT_CTL + + @retval TRUE Os enable lmce. + @retval FALSE Os not enable lmce. + +**/ +BOOLEAN +IsLmceOsEnabled ( + VOID + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + MSR_IA32_FEATURE_CONTROL_REGISTER FeatureCtrl; + MSR_IA32_MCG_EXT_CTL_REGISTER McgExtCtrl; + + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + if (McgCap.Bits.MCG_LMCE_P == 0) { + return FALSE; + } + + FeatureCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL); + if (FeatureCtrl.Bits.LmceOn == 0) { + return FALSE; + } + + McgExtCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_EXT_CTL); + return (BOOLEAN) (McgExtCtrl.Bits.LMCE_EN == 1); +} + +/** + Return if Local machine check exception signaled. + + Indicates (when set) that a local machine check exception was generated. This indicates that the current machine-check event was + delivered to only the logical processor. + + @retval TRUE LMCE was signaled. + @retval FALSE LMCE was not signaled. + +**/ +BOOLEAN +IsLmceSignaled ( + VOID + ) +{ + MSR_IA32_MCG_STATUS_REGISTER McgStatus; + + McgStatus.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_STATUS); + return (BOOLEAN) (McgStatus.Bits.LMCE_S == 1); +} + +/** + Given timeout constraint, wait for all APs to arrive, and insure when this function returns, no AP will execute normal mode code before + entering SMM, except SMI disabled APs. + +**/ +VOID +SmmWaitForApArrival ( + VOID + ) +{ + UINT64 Timer; + UINTN Index; + BOOLEAN LmceEn; + BOOLEAN LmceSignal; + + ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus); + + LmceEn = FALSE; + LmceSignal = FALSE; + if (mMachineCheckSupported) { + LmceEn = IsLmceOsEnabled (); + LmceSignal = IsLmceSignaled(); + } + + // + // Platform implementor should choose a timeout value appropriately: + // - The timeout value should balance the SMM time constrains and the likelihood that delayed CPUs are excluded in the SMM run. Note + // the SMI Handlers must ALWAYS take into account the cases that not all APs are available in an SMI run. + // - The timeout value must, in the case of 2nd timeout, be at least long enough to give time for all APs to receive the SMI IPI + // and either enter SMM or buffer the SMI, to insure there is no CPU running normal mode code when SMI handling starts. This will + // be TRUE even if a blocked CPU is brought out of the blocked state by a normal mode CPU (before the normal mode CPU received the + // SMI IPI), because with a buffered SMI, and CPU will enter SMM immediately after it is brought out of the blocked state. + // - The timeout value must be longer than longest possible IO operation in the system + // + + // + // Sync with APs 1st timeout + // + for (Timer = StartSyncTimer (); + !IsSyncTimerTimeout (Timer) && !(LmceEn && LmceSignal) && + !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED ); + ) { + CpuPause (); + } + + // + // Not all APs have arrived, so we need 2nd round of timeout. IPIs should be sent to ALL none present APs, + // because: + // a) Delayed AP may have just come out of the delayed state. Blocked AP may have just been brought out of blocked state by some AP running + // normal mode code. These APs need to be guaranteed to have an SMI pending to insure that once they are out of delayed / blocked state, they + // enter SMI immediately without executing instructions in normal mode. Note traditional flow requires there are no APs doing normal mode + // work while SMI handling is on-going. + // b) As a consequence of SMI IPI sending, (spurious) SMI may occur after this SMM run. + // c) ** NOTE **: Use SMI disabling feature VERY CAREFULLY (if at all) for traditional flow, because a processor in SMI-disabled state + // will execute normal mode code, which breaks the traditional SMI handlers' assumption that no APs are doing normal + // mode work while SMI handling is on-going. + // d) We don't add code to check SMI disabling status to skip sending IPI to SMI disabled APs, because: + // - In traditional flow, SMI disabling is discouraged. + // - In relaxed flow, CheckApArrival() will check SMI disabling status before calling this function. + // In both cases, adding SMI-disabling checking code increases overhead. + // + if (*mSmmMpSyncData->Counter < mNumberOfCpus) { + // + // Send SMI IPIs to bring outside processors in + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (!(*(mSmmMpSyncData->CpuData[Index].Present)) && gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) { + SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId); + } + } + + // + // Sync with APs 2nd timeout. + // + for (Timer = StartSyncTimer (); + !IsSyncTimerTimeout (Timer) && + !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED ); + ) { + CpuPause (); + } + } + + return; +} + + +/** + Replace OS MTRR's with SMI MTRR's. + + @param CpuIndex Processor Index + +**/ +VOID +ReplaceOSMtrrs ( + IN UINTN CpuIndex + ) +{ + SmmCpuFeaturesDisableSmrr (); + + // + // Replace all MTRRs registers + // + MtrrSetAllMtrrs (&gSmiMtrrs); +} + +/** + Wheck whether task has been finished by all APs. + + @param BlockMode Whether did it in block mode or non-block mode. + + @retval TRUE Task has been finished by all APs. + @retval FALSE Task not has been finished by all APs. + +**/ +BOOLEAN +WaitForAllAPsNotBusy ( + IN BOOLEAN BlockMode + ) +{ + UINTN Index; + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + // + // Ignore BSP and APs which not call in SMM. + // + if (!IsPresentAp(Index)) { + continue; + } + + if (BlockMode) { + AcquireSpinLock(mSmmMpSyncData->CpuData[Index].Busy); + ReleaseSpinLock(mSmmMpSyncData->CpuData[Index].Busy); + } else { + if (AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[Index].Busy)) { + ReleaseSpinLock(mSmmMpSyncData->CpuData[Index].Busy); + } else { + return FALSE; + } + } + } + + return TRUE; +} + +/** + Check whether it is an present AP. + + @param CpuIndex The AP index which calls this function. + + @retval TRUE It's a present AP. + @retval TRUE This is not an AP or it is not present. + +**/ +BOOLEAN +IsPresentAp ( + IN UINTN CpuIndex + ) +{ + return ((CpuIndex != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) && + *(mSmmMpSyncData->CpuData[CpuIndex].Present)); +} + +/** + Clean up the status flags used during executing the procedure. + + @param CpuIndex The AP index which calls this function. + +**/ +VOID +ReleaseToken ( + IN UINTN CpuIndex + ) +{ + PROCEDURE_TOKEN *Token; + + Token = mSmmMpSyncData->CpuData[CpuIndex].Token; + + if (InterlockedDecrement (&Token->RunningApCount) == 0) { + ReleaseSpinLock (Token->SpinLock); + } + + mSmmMpSyncData->CpuData[CpuIndex].Token = NULL; +} + +/** + Free the tokens in the maintained list. + +**/ +VOID +ResetTokens ( + VOID + ) +{ + // + // Reset the FirstFreeToken to the beginning of token list upon exiting SMI. + // + gSmmCpuPrivate->FirstFreeToken = GetFirstNode (&gSmmCpuPrivate->TokenList); +} + +/** + SMI handler for BSP. + + @param CpuIndex BSP processor Index + @param SyncMode SMM MP sync mode + +**/ +VOID +BSPHandler ( + IN UINTN CpuIndex, + IN SMM_CPU_SYNC_MODE SyncMode + ) +{ + UINTN Index; + MTRR_SETTINGS Mtrrs; + UINTN ApCount; + BOOLEAN ClearTopLevelSmiResult; + UINTN PresentCount; + + ASSERT (CpuIndex == mSmmMpSyncData->BspIndex); + ApCount = 0; + + // + // Flag BSP's presence + // + *mSmmMpSyncData->InsideSmm = TRUE; + + // + // Initialize Debug Agent to start source level debug in BSP handler + // + InitializeDebugAgent (DEBUG_AGENT_INIT_ENTER_SMI, NULL, NULL); + + // + // Mark this processor's presence + // + *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE; + + // + // Clear platform top level SMI status bit before calling SMI handlers. If + // we cleared it after SMI handlers are run, we would miss the SMI that + // occurs after SMI handlers are done and before SMI status bit is cleared. + // + ClearTopLevelSmiResult = ClearTopLevelSmiStatus(); + ASSERT (ClearTopLevelSmiResult == TRUE); + + // + // Set running processor index + // + gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu = CpuIndex; + + // + // If Traditional Sync Mode or need to configure MTRRs: gather all available APs. + // + if (SyncMode == SmmCpuSyncModeTradition || SmmCpuFeaturesNeedConfigureMtrrs()) { + + // + // Wait for APs to arrive + // + SmmWaitForApArrival(); + + // + // Lock the counter down and retrieve the number of APs + // + *mSmmMpSyncData->AllCpusInSync = TRUE; + ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1; + + // + // Wait for all APs to get ready for programming MTRRs + // + WaitForAllAPs (ApCount); + + if (SmmCpuFeaturesNeedConfigureMtrrs()) { + // + // Signal all APs it's time for backup MTRRs + // + ReleaseAllAPs (); + + // + // WaitForSemaphore() may wait for ever if an AP happens to enter SMM at + // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set + // to a large enough value to avoid this situation. + // Note: For HT capable CPUs, threads within a core share the same set of MTRRs. + // We do the backup first and then set MTRR to avoid race condition for threads + // in the same core. + // + MtrrGetAllMtrrs(&Mtrrs); + + // + // Wait for all APs to complete their MTRR saving + // + WaitForAllAPs (ApCount); + + // + // Let all processors program SMM MTRRs together + // + ReleaseAllAPs (); + + // + // WaitForSemaphore() may wait for ever if an AP happens to enter SMM at + // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set + // to a large enough value to avoid this situation. + // + ReplaceOSMtrrs (CpuIndex); + + // + // Wait for all APs to complete their MTRR programming + // + WaitForAllAPs (ApCount); + } + } + + // + // The BUSY lock is initialized to Acquired state + // + AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + + // + // Perform the pre tasks + // + PerformPreTasks (); + + // + // Invoke SMM Foundation EntryPoint with the processor information context. + // + gSmmCpuPrivate->SmmCoreEntry (&gSmmCpuPrivate->SmmCoreEntryContext); + + // + // Make sure all APs have completed their pending none-block tasks + // + WaitForAllAPsNotBusy (TRUE); + + // + // Perform the remaining tasks + // + PerformRemainingTasks (); + + // + // If Relaxed-AP Sync Mode: gather all available APs after BSP SMM handlers are done, and + // make those APs to exit SMI synchronously. APs which arrive later will be excluded and + // will run through freely. + // + if (SyncMode != SmmCpuSyncModeTradition && !SmmCpuFeaturesNeedConfigureMtrrs()) { + + // + // Lock the counter down and retrieve the number of APs + // + *mSmmMpSyncData->AllCpusInSync = TRUE; + ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1; + // + // Make sure all APs have their Present flag set + // + while (TRUE) { + PresentCount = 0; + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (*(mSmmMpSyncData->CpuData[Index].Present)) { + PresentCount ++; + } + } + if (PresentCount > ApCount) { + break; + } + } + } + + // + // Notify all APs to exit + // + *mSmmMpSyncData->InsideSmm = FALSE; + ReleaseAllAPs (); + + // + // Wait for all APs to complete their pending tasks + // + WaitForAllAPs (ApCount); + + if (SmmCpuFeaturesNeedConfigureMtrrs()) { + // + // Signal APs to restore MTRRs + // + ReleaseAllAPs (); + + // + // Restore OS MTRRs + // + SmmCpuFeaturesReenableSmrr (); + MtrrSetAllMtrrs(&Mtrrs); + + // + // Wait for all APs to complete MTRR programming + // + WaitForAllAPs (ApCount); + } + + // + // Stop source level debug in BSP handler, the code below will not be + // debugged. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_EXIT_SMI, NULL, NULL); + + // + // Signal APs to Reset states/semaphore for this processor + // + ReleaseAllAPs (); + + // + // Perform pending operations for hot-plug + // + SmmCpuUpdate (); + + // + // Clear the Present flag of BSP + // + *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE; + + // + // Gather APs to exit SMM synchronously. Note the Present flag is cleared by now but + // WaitForAllAps does not depend on the Present flag. + // + WaitForAllAPs (ApCount); + + // + // Reset the tokens buffer. + // + ResetTokens (); + + // + // Reset BspIndex to -1, meaning BSP has not been elected. + // + if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) { + mSmmMpSyncData->BspIndex = (UINT32)-1; + } + + // + // Allow APs to check in from this point on + // + *mSmmMpSyncData->Counter = 0; + *mSmmMpSyncData->AllCpusInSync = FALSE; +} + +/** + SMI handler for AP. + + @param CpuIndex AP processor Index. + @param ValidSmi Indicates that current SMI is a valid SMI or not. + @param SyncMode SMM MP sync mode. + +**/ +VOID +APHandler ( + IN UINTN CpuIndex, + IN BOOLEAN ValidSmi, + IN SMM_CPU_SYNC_MODE SyncMode + ) +{ + UINT64 Timer; + UINTN BspIndex; + MTRR_SETTINGS Mtrrs; + EFI_STATUS ProcedureStatus; + + // + // Timeout BSP + // + for (Timer = StartSyncTimer (); + !IsSyncTimerTimeout (Timer) && + !(*mSmmMpSyncData->InsideSmm); + ) { + CpuPause (); + } + + if (!(*mSmmMpSyncData->InsideSmm)) { + // + // BSP timeout in the first round + // + if (mSmmMpSyncData->BspIndex != -1) { + // + // BSP Index is known + // + BspIndex = mSmmMpSyncData->BspIndex; + ASSERT (CpuIndex != BspIndex); + + // + // Send SMI IPI to bring BSP in + // + SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[BspIndex].ProcessorId); + + // + // Now clock BSP for the 2nd time + // + for (Timer = StartSyncTimer (); + !IsSyncTimerTimeout (Timer) && + !(*mSmmMpSyncData->InsideSmm); + ) { + CpuPause (); + } + + if (!(*mSmmMpSyncData->InsideSmm)) { + // + // Give up since BSP is unable to enter SMM + // and signal the completion of this AP + WaitForSemaphore (mSmmMpSyncData->Counter); + return; + } + } else { + // + // Don't know BSP index. Give up without sending IPI to BSP. + // + WaitForSemaphore (mSmmMpSyncData->Counter); + return; + } + } + + // + // BSP is available + // + BspIndex = mSmmMpSyncData->BspIndex; + ASSERT (CpuIndex != BspIndex); + + // + // Mark this processor's presence + // + *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE; + + if (SyncMode == SmmCpuSyncModeTradition || SmmCpuFeaturesNeedConfigureMtrrs()) { + // + // Notify BSP of arrival at this point + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + } + + if (SmmCpuFeaturesNeedConfigureMtrrs()) { + // + // Wait for the signal from BSP to backup MTRRs + // + WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + // + // Backup OS MTRRs + // + MtrrGetAllMtrrs(&Mtrrs); + + // + // Signal BSP the completion of this AP + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + + // + // Wait for BSP's signal to program MTRRs + // + WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + // + // Replace OS MTRRs with SMI MTRRs + // + ReplaceOSMtrrs (CpuIndex); + + // + // Signal BSP the completion of this AP + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + } + + while (TRUE) { + // + // Wait for something to happen + // + WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + // + // Check if BSP wants to exit SMM + // + if (!(*mSmmMpSyncData->InsideSmm)) { + break; + } + + // + // BUSY should be acquired by SmmStartupThisAp() + // + ASSERT ( + !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy) + ); + + // + // Invoke the scheduled procedure + // + ProcedureStatus = (*mSmmMpSyncData->CpuData[CpuIndex].Procedure) ( + (VOID*)mSmmMpSyncData->CpuData[CpuIndex].Parameter + ); + if (mSmmMpSyncData->CpuData[CpuIndex].Status != NULL) { + *mSmmMpSyncData->CpuData[CpuIndex].Status = ProcedureStatus; + } + + if (mSmmMpSyncData->CpuData[CpuIndex].Token != NULL) { + ReleaseToken (CpuIndex); + } + + // + // Release BUSY + // + ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + } + + if (SmmCpuFeaturesNeedConfigureMtrrs()) { + // + // Notify BSP the readiness of this AP to program MTRRs + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + + // + // Wait for the signal from BSP to program MTRRs + // + WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + // + // Restore OS MTRRs + // + SmmCpuFeaturesReenableSmrr (); + MtrrSetAllMtrrs(&Mtrrs); + } + + // + // Notify BSP the readiness of this AP to Reset states/semaphore for this processor + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + + // + // Wait for the signal from BSP to Reset states/semaphore for this processor + // + WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + // + // Reset states/semaphore for this processor + // + *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE; + + // + // Notify BSP the readiness of this AP to exit SMM + // + ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run); + +} + +/** + Create 4G PageTable in SMRAM. + + @param[in] Is32BitPageTable Whether the page table is 32-bit PAE + @return PageTable Address + +**/ +UINT32 +Gen4GPageTable ( + IN BOOLEAN Is32BitPageTable + ) +{ + VOID *PageTable; + UINTN Index; + UINT64 *Pte; + UINTN PagesNeeded; + UINTN Low2MBoundary; + UINTN High2MBoundary; + UINTN Pages; + UINTN GuardPage; + UINT64 *Pdpte; + UINTN PageIndex; + UINTN PageAddress; + + Low2MBoundary = 0; + High2MBoundary = 0; + PagesNeeded = 0; + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // Add one more page for known good stack, then find the lower 2MB aligned address. + // + Low2MBoundary = (mSmmStackArrayBase + EFI_PAGE_SIZE) & ~(SIZE_2MB-1); + // + // Add two more pages for known good stack and stack guard page, + // then find the lower 2MB aligned address. + // + High2MBoundary = (mSmmStackArrayEnd - mSmmStackSize + EFI_PAGE_SIZE * 2) & ~(SIZE_2MB-1); + PagesNeeded = ((High2MBoundary - Low2MBoundary) / SIZE_2MB) + 1; + } + // + // Allocate the page table + // + PageTable = AllocatePageTableMemory (5 + PagesNeeded); + ASSERT (PageTable != NULL); + + PageTable = (VOID *)((UINTN)PageTable); + Pte = (UINT64*)PageTable; + + // + // Zero out all page table entries first + // + ZeroMem (Pte, EFI_PAGES_TO_SIZE (1)); + + // + // Set Page Directory Pointers + // + for (Index = 0; Index < 4; Index++) { + Pte[Index] = ((UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1)) | mAddressEncMask | + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS); + } + Pte += EFI_PAGE_SIZE / sizeof (*Pte); + + // + // Fill in Page Directory Entries + // + for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) { + Pte[Index] = (Index << 21) | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS; + } + + Pdpte = (UINT64*)PageTable; + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + Pages = (UINTN)PageTable + EFI_PAGES_TO_SIZE (5); + GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE; + for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) { + Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1)); + Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + // + // Fill in Page Table Entries + // + Pte = (UINT64*)Pages; + PageAddress = PageIndex; + for (Index = 0; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) { + if (PageAddress == GuardPage) { + // + // Mark the guard page as non-present + // + Pte[Index] = PageAddress | mAddressEncMask; + GuardPage += mSmmStackSize; + if (GuardPage > mSmmStackArrayEnd) { + GuardPage = 0; + } + } else { + Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + PageAddress+= EFI_PAGE_SIZE; + } + Pages += EFI_PAGE_SIZE; + } + } + + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) { + Pte = (UINT64*)(UINTN)(Pdpte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1)); + if ((Pte[0] & IA32_PG_PS) == 0) { + // 4K-page entries are already mapped. Just hide the first one anyway. + Pte = (UINT64*)(UINTN)(Pte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1)); + Pte[0] &= ~(UINT64)IA32_PG_P; // Hide page 0 + } else { + // Create 4K-page entries + Pages = (UINTN)AllocatePageTableMemory (1); + ASSERT (Pages != 0); + + Pte[0] = (UINT64)(Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS); + + Pte = (UINT64*)Pages; + PageAddress = 0; + Pte[0] = PageAddress | mAddressEncMask; // Hide page 0 but present left + for (Index = 1; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) { + PageAddress += EFI_PAGE_SIZE; + Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + } + } + + return (UINT32)(UINTN)PageTable; +} + +/** + Checks whether the input token is the current used token. + + @param[in] Token This parameter describes the token that was passed into DispatchProcedure or + BroadcastProcedure. + + @retval TRUE The input token is the current used token. + @retval FALSE The input token is not the current used token. +**/ +BOOLEAN +IsTokenInUse ( + IN SPIN_LOCK *Token + ) +{ + LIST_ENTRY *Link; + PROCEDURE_TOKEN *ProcToken; + + if (Token == NULL) { + return FALSE; + } + + Link = GetFirstNode (&gSmmCpuPrivate->TokenList); + // + // Only search used tokens. + // + while (Link != gSmmCpuPrivate->FirstFreeToken) { + ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link); + + if (ProcToken->SpinLock == Token) { + return TRUE; + } + + Link = GetNextNode (&gSmmCpuPrivate->TokenList, Link); + } + + return FALSE; +} + +/** + Allocate buffer for the SPIN_LOCK and PROCEDURE_TOKEN. + + @return First token of the token buffer. +**/ +LIST_ENTRY * +AllocateTokenBuffer ( + VOID + ) +{ + UINTN SpinLockSize; + UINT32 TokenCountPerChunk; + UINTN Index; + SPIN_LOCK *SpinLock; + UINT8 *SpinLockBuffer; + PROCEDURE_TOKEN *ProcTokens; + + SpinLockSize = GetSpinLockProperties (); + + TokenCountPerChunk = FixedPcdGet32 (PcdCpuSmmMpTokenCountPerChunk); + ASSERT (TokenCountPerChunk != 0); + if (TokenCountPerChunk == 0) { + DEBUG ((DEBUG_ERROR, "PcdCpuSmmMpTokenCountPerChunk should not be Zero!\n")); + CpuDeadLoop (); + } + DEBUG ((DEBUG_INFO, "CpuSmm: SpinLock Size = 0x%x, PcdCpuSmmMpTokenCountPerChunk = 0x%x\n", SpinLockSize, TokenCountPerChunk)); + + // + // Separate the Spin_lock and Proc_token because the alignment requires by Spin_Lock. + // + SpinLockBuffer = AllocatePool (SpinLockSize * TokenCountPerChunk); + ASSERT (SpinLockBuffer != NULL); + + ProcTokens = AllocatePool (sizeof (PROCEDURE_TOKEN) * TokenCountPerChunk); + ASSERT (ProcTokens != NULL); + + for (Index = 0; Index < TokenCountPerChunk; Index++) { + SpinLock = (SPIN_LOCK *)(SpinLockBuffer + SpinLockSize * Index); + InitializeSpinLock (SpinLock); + + ProcTokens[Index].Signature = PROCEDURE_TOKEN_SIGNATURE; + ProcTokens[Index].SpinLock = SpinLock; + ProcTokens[Index].RunningApCount = 0; + + InsertTailList (&gSmmCpuPrivate->TokenList, &ProcTokens[Index].Link); + } + + return &ProcTokens[0].Link; +} + +/** + Get the free token. + + If no free token, allocate new tokens then return the free one. + + @param RunningApsCount The Running Aps count for this token. + + @retval return the first free PROCEDURE_TOKEN. + +**/ +PROCEDURE_TOKEN * +GetFreeToken ( + IN UINT32 RunningApsCount + ) +{ + PROCEDURE_TOKEN *NewToken; + + // + // If FirstFreeToken meets the end of token list, enlarge the token list. + // Set FirstFreeToken to the first free token. + // + if (gSmmCpuPrivate->FirstFreeToken == &gSmmCpuPrivate->TokenList) { + gSmmCpuPrivate->FirstFreeToken = AllocateTokenBuffer (); + } + NewToken = PROCEDURE_TOKEN_FROM_LINK (gSmmCpuPrivate->FirstFreeToken); + gSmmCpuPrivate->FirstFreeToken = GetNextNode (&gSmmCpuPrivate->TokenList, gSmmCpuPrivate->FirstFreeToken); + + NewToken->RunningApCount = RunningApsCount; + AcquireSpinLock (NewToken->SpinLock); + + return NewToken; +} + +/** + Checks status of specified AP. + + This function checks whether the specified AP has finished the task assigned + by StartupThisAP(), and whether timeout expires. + + @param[in] Token This parameter describes the token that was passed into DispatchProcedure or + BroadcastProcedure. + + @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs(). + @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired. +**/ +EFI_STATUS +IsApReady ( + IN SPIN_LOCK *Token + ) +{ + if (AcquireSpinLockOrFail (Token)) { + ReleaseSpinLock (Token); + return EFI_SUCCESS; + } + + return EFI_NOT_READY; +} + +/** + Schedule a procedure to run on the specified CPU. + + @param[in] Procedure The address of the procedure to run + @param[in] CpuIndex Target CPU Index + @param[in,out] ProcArguments The parameter to pass to the procedure + @param[in] Token This is an optional parameter that allows the caller to execute the + procedure in a blocking or non-blocking fashion. If it is NULL the + call is blocking, and the call will not return until the AP has + completed the procedure. If the token is not NULL, the call will + return immediately. The caller can check whether the procedure has + completed with CheckOnProcedure or WaitForProcedure. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish + execution of Procedure, either for blocking or non-blocking mode. + Zero means infinity. If the timeout expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. If + the timeout expires in blocking mode, the call returns EFI_TIMEOUT. + If the timeout expires in non-blocking mode, the timeout determined + can be through CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an implementation + supports this feature can be determined via the Attributes data + member. + @param[in,out] CpuStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS The procedure has been successfully scheduled + +**/ +EFI_STATUS +InternalSmmStartupThisAp ( + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL, + IN MM_COMPLETION *Token, + IN UINTN TimeoutInMicroseconds, + IN OUT EFI_STATUS *CpuStatus + ) +{ + PROCEDURE_TOKEN *ProcToken; + + if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus) { + DEBUG((DEBUG_ERROR, "CpuIndex(%d) >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus(%d)\n", CpuIndex, gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus)); + return EFI_INVALID_PARAMETER; + } + if (CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) { + DEBUG((DEBUG_ERROR, "CpuIndex(%d) == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu\n", CpuIndex)); + return EFI_INVALID_PARAMETER; + } + if (gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId == INVALID_APIC_ID) { + return EFI_INVALID_PARAMETER; + } + if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) { + if (mSmmMpSyncData->EffectiveSyncMode == SmmCpuSyncModeTradition) { + DEBUG((DEBUG_ERROR, "!mSmmMpSyncData->CpuData[%d].Present\n", CpuIndex)); + } + return EFI_INVALID_PARAMETER; + } + if (gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove) { + if (!FeaturePcdGet (PcdCpuHotPlugSupport)) { + DEBUG((DEBUG_ERROR, "gSmmCpuPrivate->Operation[%d] == SmmCpuRemove\n", CpuIndex)); + } + return EFI_INVALID_PARAMETER; + } + if ((TimeoutInMicroseconds != 0) && ((mSmmMp.Attributes & EFI_MM_MP_TIMEOUT_SUPPORTED) == 0)) { + return EFI_INVALID_PARAMETER; + } + if (Procedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + + mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure; + mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments; + if (Token != NULL) { + ProcToken= GetFreeToken (1); + mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken; + *Token = (MM_COMPLETION)ProcToken->SpinLock; + } + mSmmMpSyncData->CpuData[CpuIndex].Status = CpuStatus; + if (mSmmMpSyncData->CpuData[CpuIndex].Status != NULL) { + *mSmmMpSyncData->CpuData[CpuIndex].Status = EFI_NOT_READY; + } + + ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run); + + if (Token == NULL) { + AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + } + + return EFI_SUCCESS; +} + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in,out] ProcedureArguments The parameter passed into Procedure for + all APs. + @param[in,out] Token This is an optional parameter that allows the caller to execute the + procedure in a blocking or non-blocking fashion. If it is NULL the + call is blocking, and the call will not return until the AP has + completed the procedure. If the token is not NULL, the call will + return immediately. The caller can check whether the procedure has + completed with CheckOnProcedure or WaitForProcedure. + @param[in,out] CPUStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval others Failed to Startup all APs. + +**/ +EFI_STATUS +InternalSmmStartupAllAPs ( + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ) +{ + UINTN Index; + UINTN CpuCount; + PROCEDURE_TOKEN *ProcToken; + + if ((TimeoutInMicroseconds != 0) && ((mSmmMp.Attributes & EFI_MM_MP_TIMEOUT_SUPPORTED) == 0)) { + return EFI_INVALID_PARAMETER; + } + if (Procedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + CpuCount = 0; + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (IsPresentAp (Index)) { + CpuCount ++; + + if (gSmmCpuPrivate->Operation[Index] == SmmCpuRemove) { + return EFI_INVALID_PARAMETER; + } + + if (!AcquireSpinLockOrFail(mSmmMpSyncData->CpuData[Index].Busy)) { + return EFI_NOT_READY; + } + ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Busy); + } + } + if (CpuCount == 0) { + return EFI_NOT_STARTED; + } + + if (Token != NULL) { + ProcToken = GetFreeToken ((UINT32)mMaxNumberOfCpus); + *Token = (MM_COMPLETION)ProcToken->SpinLock; + } else { + ProcToken = NULL; + } + + // + // Make sure all BUSY should be acquired. + // + // Because former code already check mSmmMpSyncData->CpuData[***].Busy for each AP. + // Here code always use AcquireSpinLock instead of AcquireSpinLockOrFail for not + // block mode. + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (IsPresentAp (Index)) { + AcquireSpinLock (mSmmMpSyncData->CpuData[Index].Busy); + } + } + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (IsPresentAp (Index)) { + mSmmMpSyncData->CpuData[Index].Procedure = (EFI_AP_PROCEDURE2) Procedure; + mSmmMpSyncData->CpuData[Index].Parameter = ProcedureArguments; + if (ProcToken != NULL) { + mSmmMpSyncData->CpuData[Index].Token = ProcToken; + } + if (CPUStatus != NULL) { + mSmmMpSyncData->CpuData[Index].Status = &CPUStatus[Index]; + if (mSmmMpSyncData->CpuData[Index].Status != NULL) { + *mSmmMpSyncData->CpuData[Index].Status = EFI_NOT_READY; + } + } + } else { + // + // PI spec requirement: + // For every excluded processor, the array entry must contain a value of EFI_NOT_STARTED. + // + if (CPUStatus != NULL) { + CPUStatus[Index] = EFI_NOT_STARTED; + } + + // + // Decrease the count to mark this processor(AP or BSP) as finished. + // + if (ProcToken != NULL) { + WaitForSemaphore (&ProcToken->RunningApCount); + } + } + } + + ReleaseAllAPs (); + + if (Token == NULL) { + // + // Make sure all APs have completed their tasks. + // + WaitForAllAPsNotBusy (TRUE); + } + + return EFI_SUCCESS; +} + +/** + ISO C99 6.5.2.2 "Function calls", paragraph 9: + If the function is defined with a type that is not compatible with + the type (of the expression) pointed to by the expression that + denotes the called function, the behavior is undefined. + + So add below wrapper function to convert between EFI_AP_PROCEDURE + and EFI_AP_PROCEDURE2. + + Wrapper for Procedures. + + @param[in] Buffer Pointer to PROCEDURE_WRAPPER buffer. + +**/ +EFI_STATUS +EFIAPI +ProcedureWrapper ( + IN VOID *Buffer + ) +{ + PROCEDURE_WRAPPER *Wrapper; + + Wrapper = Buffer; + Wrapper->Procedure (Wrapper->ProcedureArgument); + + return EFI_SUCCESS; +} + +/** + Schedule a procedure to run on the specified CPU in blocking mode. + + @param[in] Procedure The address of the procedure to run + @param[in] CpuIndex Target CPU Index + @param[in, out] ProcArguments The parameter to pass to the procedure + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS The procedure has been successfully scheduled + +**/ +EFI_STATUS +EFIAPI +SmmBlockingStartupThisAp ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL + ) +{ + PROCEDURE_WRAPPER Wrapper; + + Wrapper.Procedure = Procedure; + Wrapper.ProcedureArgument = ProcArguments; + + // + // Use wrapper function to convert EFI_AP_PROCEDURE to EFI_AP_PROCEDURE2. + // + return InternalSmmStartupThisAp (ProcedureWrapper, CpuIndex, &Wrapper, NULL, 0, NULL); +} + +/** + Schedule a procedure to run on the specified CPU. + + @param Procedure The address of the procedure to run + @param CpuIndex Target CPU Index + @param ProcArguments The parameter to pass to the procedure + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS The procedure has been successfully scheduled + +**/ +EFI_STATUS +EFIAPI +SmmStartupThisAp ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL + ) +{ + MM_COMPLETION Token; + + gSmmCpuPrivate->ApWrapperFunc[CpuIndex].Procedure = Procedure; + gSmmCpuPrivate->ApWrapperFunc[CpuIndex].ProcedureArgument = ProcArguments; + + // + // Use wrapper function to convert EFI_AP_PROCEDURE to EFI_AP_PROCEDURE2. + // + return InternalSmmStartupThisAp ( + ProcedureWrapper, + CpuIndex, + &gSmmCpuPrivate->ApWrapperFunc[CpuIndex], + FeaturePcdGet (PcdCpuSmmBlockStartupThisAp) ? NULL : &Token, + 0, + NULL + ); +} + +/** + This function sets DR6 & DR7 according to SMM save state, before running SMM C code. + They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode. + + NOTE: It might not be appreciated in runtime since it might + conflict with OS debugging facilities. Turn them off in RELEASE. + + @param CpuIndex CPU Index + +**/ +VOID +EFIAPI +CpuSmmDebugEntry ( + IN UINTN CpuIndex + ) +{ + SMRAM_SAVE_STATE_MAP *CpuSaveState; + + if (FeaturePcdGet (PcdCpuSmmDebug)) { + ASSERT(CpuIndex < mMaxNumberOfCpus); + CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex]; + if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { + AsmWriteDr6 (CpuSaveState->x86._DR6); + AsmWriteDr7 (CpuSaveState->x86._DR7); + } else { + AsmWriteDr6 ((UINTN)CpuSaveState->x64._DR6); + AsmWriteDr7 ((UINTN)CpuSaveState->x64._DR7); + } + } +} + +/** + This function restores DR6 & DR7 to SMM save state. + + NOTE: It might not be appreciated in runtime since it might + conflict with OS debugging facilities. Turn them off in RELEASE. + + @param CpuIndex CPU Index + +**/ +VOID +EFIAPI +CpuSmmDebugExit ( + IN UINTN CpuIndex + ) +{ + SMRAM_SAVE_STATE_MAP *CpuSaveState; + + if (FeaturePcdGet (PcdCpuSmmDebug)) { + ASSERT(CpuIndex < mMaxNumberOfCpus); + CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex]; + if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { + CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 (); + CpuSaveState->x86._DR6 = (UINT32)AsmReadDr6 (); + } else { + CpuSaveState->x64._DR7 = AsmReadDr7 (); + CpuSaveState->x64._DR6 = AsmReadDr6 (); + } + } +} + +/** + C function for SMI entry, each processor comes here upon SMI trigger. + + @param CpuIndex CPU Index + +**/ +VOID +EFIAPI +SmiRendezvous ( + IN UINTN CpuIndex + ) +{ + EFI_STATUS Status; + BOOLEAN ValidSmi; + BOOLEAN IsBsp; + BOOLEAN BspInProgress; + UINTN Index; + UINTN Cr2; + + ASSERT(CpuIndex < mMaxNumberOfCpus); + + // + // Save Cr2 because Page Fault exception in SMM may override its value, + // when using on-demand paging for above 4G memory. + // + Cr2 = 0; + SaveCr2 (&Cr2); + + // + // Call the user register Startup function first. + // + if (mSmmMpSyncData->StartupProcedure != NULL) { + mSmmMpSyncData->StartupProcedure (mSmmMpSyncData->StartupProcArgs); + } + + // + // Perform CPU specific entry hooks + // + SmmCpuFeaturesRendezvousEntry (CpuIndex); + + // + // Determine if this is a valid SMI + // + ValidSmi = PlatformValidSmi(); + + // + // Determine if BSP has been already in progress. Note this must be checked after + // ValidSmi because BSP may clear a valid SMI source after checking in. + // + BspInProgress = *mSmmMpSyncData->InsideSmm; + + if (!BspInProgress && !ValidSmi) { + // + // If we reach here, it means when we sampled the ValidSmi flag, SMI status had not + // been cleared by BSP in a new SMI run (so we have a truly invalid SMI), or SMI + // status had been cleared by BSP and an existing SMI run has almost ended. (Note + // we sampled ValidSmi flag BEFORE judging BSP-in-progress status.) In both cases, there + // is nothing we need to do. + // + goto Exit; + } else { + // + // Signal presence of this processor + // + if (ReleaseSemaphore (mSmmMpSyncData->Counter) == 0) { + // + // BSP has already ended the synchronization, so QUIT!!! + // + + // + // Wait for BSP's signal to finish SMI + // + while (*mSmmMpSyncData->AllCpusInSync) { + CpuPause (); + } + goto Exit; + } else { + + // + // The BUSY lock is initialized to Released state. + // This needs to be done early enough to be ready for BSP's SmmStartupThisAp() call. + // E.g., with Relaxed AP flow, SmmStartupThisAp() may be called immediately + // after AP's present flag is detected. + // + InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy); + } + + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + ActivateSmmProfile (CpuIndex); + } + + if (BspInProgress) { + // + // BSP has been elected. Follow AP path, regardless of ValidSmi flag + // as BSP may have cleared the SMI status + // + APHandler (CpuIndex, ValidSmi, mSmmMpSyncData->EffectiveSyncMode); + } else { + // + // We have a valid SMI + // + + // + // Elect BSP + // + IsBsp = FALSE; + if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) { + if (!mSmmMpSyncData->SwitchBsp || mSmmMpSyncData->CandidateBsp[CpuIndex]) { + // + // Call platform hook to do BSP election + // + Status = PlatformSmmBspElection (&IsBsp); + if (EFI_SUCCESS == Status) { + // + // Platform hook determines successfully + // + if (IsBsp) { + mSmmMpSyncData->BspIndex = (UINT32)CpuIndex; + } + } else { + // + // Platform hook fails to determine, use default BSP election method + // + InterlockedCompareExchange32 ( + (UINT32*)&mSmmMpSyncData->BspIndex, + (UINT32)-1, + (UINT32)CpuIndex + ); + } + } + } + + // + // "mSmmMpSyncData->BspIndex == CpuIndex" means this is the BSP + // + if (mSmmMpSyncData->BspIndex == CpuIndex) { + + // + // Clear last request for SwitchBsp. + // + if (mSmmMpSyncData->SwitchBsp) { + mSmmMpSyncData->SwitchBsp = FALSE; + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + mSmmMpSyncData->CandidateBsp[Index] = FALSE; + } + } + + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + SmmProfileRecordSmiNum (); + } + + // + // BSP Handler is always called with a ValidSmi == TRUE + // + BSPHandler (CpuIndex, mSmmMpSyncData->EffectiveSyncMode); + } else { + APHandler (CpuIndex, ValidSmi, mSmmMpSyncData->EffectiveSyncMode); + } + } + + ASSERT (*mSmmMpSyncData->CpuData[CpuIndex].Run == 0); + + // + // Wait for BSP's signal to exit SMI + // + while (*mSmmMpSyncData->AllCpusInSync) { + CpuPause (); + } + } + +Exit: + SmmCpuFeaturesRendezvousExit (CpuIndex); + + // + // Restore Cr2 + // + RestoreCr2 (Cr2); +} + +/** + Allocate buffer for SpinLock and Wrapper function buffer. + +**/ +VOID +InitializeDataForMmMp ( + VOID + ) +{ + gSmmCpuPrivate->ApWrapperFunc = AllocatePool (sizeof (PROCEDURE_WRAPPER) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); + ASSERT (gSmmCpuPrivate->ApWrapperFunc != NULL); + + InitializeListHead (&gSmmCpuPrivate->TokenList); + + gSmmCpuPrivate->FirstFreeToken = AllocateTokenBuffer (); +} + +/** + Allocate buffer for all semaphores and spin locks. + +**/ +VOID +InitializeSmmCpuSemaphores ( + VOID + ) +{ + UINTN ProcessorCount; + UINTN TotalSize; + UINTN GlobalSemaphoresSize; + UINTN CpuSemaphoresSize; + UINTN SemaphoreSize; + UINTN Pages; + UINTN *SemaphoreBlock; + UINTN SemaphoreAddr; + + SemaphoreSize = GetSpinLockProperties (); + ProcessorCount = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + GlobalSemaphoresSize = (sizeof (SMM_CPU_SEMAPHORE_GLOBAL) / sizeof (VOID *)) * SemaphoreSize; + CpuSemaphoresSize = (sizeof (SMM_CPU_SEMAPHORE_CPU) / sizeof (VOID *)) * ProcessorCount * SemaphoreSize; + TotalSize = GlobalSemaphoresSize + CpuSemaphoresSize; + DEBUG((EFI_D_INFO, "One Semaphore Size = 0x%x\n", SemaphoreSize)); + DEBUG((EFI_D_INFO, "Total Semaphores Size = 0x%x\n", TotalSize)); + Pages = EFI_SIZE_TO_PAGES (TotalSize); + SemaphoreBlock = AllocatePages (Pages); + ASSERT (SemaphoreBlock != NULL); + ZeroMem (SemaphoreBlock, TotalSize); + + SemaphoreAddr = (UINTN)SemaphoreBlock; + mSmmCpuSemaphores.SemaphoreGlobal.Counter = (UINT32 *)SemaphoreAddr; + SemaphoreAddr += SemaphoreSize; + mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm = (BOOLEAN *)SemaphoreAddr; + SemaphoreAddr += SemaphoreSize; + mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync = (BOOLEAN *)SemaphoreAddr; + SemaphoreAddr += SemaphoreSize; + mSmmCpuSemaphores.SemaphoreGlobal.PFLock = (SPIN_LOCK *)SemaphoreAddr; + SemaphoreAddr += SemaphoreSize; + mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock + = (SPIN_LOCK *)SemaphoreAddr; + SemaphoreAddr += SemaphoreSize; + + SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize; + mSmmCpuSemaphores.SemaphoreCpu.Busy = (SPIN_LOCK *)SemaphoreAddr; + SemaphoreAddr += ProcessorCount * SemaphoreSize; + mSmmCpuSemaphores.SemaphoreCpu.Run = (UINT32 *)SemaphoreAddr; + SemaphoreAddr += ProcessorCount * SemaphoreSize; + mSmmCpuSemaphores.SemaphoreCpu.Present = (BOOLEAN *)SemaphoreAddr; + + mPFLock = mSmmCpuSemaphores.SemaphoreGlobal.PFLock; + mConfigSmmCodeAccessCheckLock = mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock; + + mSemaphoreSize = SemaphoreSize; +} + +/** + Initialize un-cacheable data. + +**/ +VOID +EFIAPI +InitializeMpSyncData ( + VOID + ) +{ + UINTN CpuIndex; + + if (mSmmMpSyncData != NULL) { + // + // mSmmMpSyncDataSize includes one structure of SMM_DISPATCHER_MP_SYNC_DATA, one + // CpuData array of SMM_CPU_DATA_BLOCK and one CandidateBsp array of BOOLEAN. + // + ZeroMem (mSmmMpSyncData, mSmmMpSyncDataSize); + mSmmMpSyncData->CpuData = (SMM_CPU_DATA_BLOCK *)((UINT8 *)mSmmMpSyncData + sizeof (SMM_DISPATCHER_MP_SYNC_DATA)); + mSmmMpSyncData->CandidateBsp = (BOOLEAN *)(mSmmMpSyncData->CpuData + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); + if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) { + // + // Enable BSP election by setting BspIndex to -1 + // + mSmmMpSyncData->BspIndex = (UINT32)-1; + } + mSmmMpSyncData->EffectiveSyncMode = mCpuSmmSyncMode; + + mSmmMpSyncData->Counter = mSmmCpuSemaphores.SemaphoreGlobal.Counter; + mSmmMpSyncData->InsideSmm = mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm; + mSmmMpSyncData->AllCpusInSync = mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync; + ASSERT (mSmmMpSyncData->Counter != NULL && mSmmMpSyncData->InsideSmm != NULL && + mSmmMpSyncData->AllCpusInSync != NULL); + *mSmmMpSyncData->Counter = 0; + *mSmmMpSyncData->InsideSmm = FALSE; + *mSmmMpSyncData->AllCpusInSync = FALSE; + + for (CpuIndex = 0; CpuIndex < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; CpuIndex ++) { + mSmmMpSyncData->CpuData[CpuIndex].Busy = + (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Busy + mSemaphoreSize * CpuIndex); + mSmmMpSyncData->CpuData[CpuIndex].Run = + (UINT32 *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Run + mSemaphoreSize * CpuIndex); + mSmmMpSyncData->CpuData[CpuIndex].Present = + (BOOLEAN *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Present + mSemaphoreSize * CpuIndex); + *(mSmmMpSyncData->CpuData[CpuIndex].Busy) = 0; + *(mSmmMpSyncData->CpuData[CpuIndex].Run) = 0; + *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE; + } + } +} + +/** + Initialize global data for MP synchronization. + + @param Stacks Base address of SMI stack buffer for all processors. + @param StackSize Stack size for each processor in SMM. + @param ShadowStackSize Shadow Stack size for each processor in SMM. + +**/ +UINT32 +InitializeMpServiceData ( + IN VOID *Stacks, + IN UINTN StackSize, + IN UINTN ShadowStackSize + ) +{ + UINT32 Cr3; + UINTN Index; + UINT8 *GdtTssTables; + UINTN GdtTableStepSize; + CPUID_VERSION_INFO_EDX RegEdx; + + // + // Determine if this CPU supports machine check + // + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx.Uint32); + mMachineCheckSupported = (BOOLEAN)(RegEdx.Bits.MCA == 1); + + // + // Allocate memory for all locks and semaphores + // + InitializeSmmCpuSemaphores (); + + // + // Initialize mSmmMpSyncData + // + mSmmMpSyncDataSize = sizeof (SMM_DISPATCHER_MP_SYNC_DATA) + + (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); + InitializeMpSyncData (); + + // + // Initialize physical address mask + // NOTE: Physical memory above virtual address limit is not supported !!! + // + AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL); + gPhyMask = LShiftU64 (1, (UINT8)Index) - 1; + gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE; + + // + // Create page tables + // + Cr3 = SmmInitPageTable (); + + GdtTssTables = InitGdt (Cr3, &GdtTableStepSize); + + // + // Install SMI handler for each CPU + // + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + InstallSmiHandler ( + Index, + (UINT32)mCpuHotPlugData.SmBase[Index], + (VOID*)((UINTN)Stacks + (StackSize + ShadowStackSize) * Index), + StackSize, + (UINTN)(GdtTssTables + GdtTableStepSize * Index), + gcSmiGdtr.Limit + 1, + gcSmiIdtr.Base, + gcSmiIdtr.Limit + 1, + Cr3 + ); + } + + // + // Record current MTRR settings + // + ZeroMem (&gSmiMtrrs, sizeof (gSmiMtrrs)); + MtrrGetAllMtrrs (&gSmiMtrrs); + + return Cr3; +} + +/** + + Register the SMM Foundation entry point. + + @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance + @param SmmEntryPoint SMM Foundation EntryPoint + + @retval EFI_SUCCESS Successfully to register SMM foundation entry point + +**/ +EFI_STATUS +EFIAPI +RegisterSmmEntry ( + IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This, + IN EFI_SMM_ENTRY_POINT SmmEntryPoint + ) +{ + // + // Record SMM Foundation EntryPoint, later invoke it on SMI entry vector. + // + gSmmCpuPrivate->SmmCoreEntry = SmmEntryPoint; + return EFI_SUCCESS; +} + +/** + + Register the SMM Foundation entry point. + + @param[in] Procedure A pointer to the code stream to be run on the designated target AP + of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2 + with the related definitions of + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs. + If caller may pass a value of NULL to deregister any existing + startup procedure. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is + run by the AP. It is an optional common mailbox between APs and + the caller to share information + + @retval EFI_SUCCESS The Procedure has been set successfully. + @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL. + +**/ +EFI_STATUS +RegisterStartupProcedure ( + IN EFI_AP_PROCEDURE Procedure, + IN OUT VOID *ProcedureArguments OPTIONAL + ) +{ + if (Procedure == NULL && ProcedureArguments != NULL) { + return EFI_INVALID_PARAMETER; + } + if (mSmmMpSyncData == NULL) { + return EFI_NOT_READY; + } + + mSmmMpSyncData->StartupProcedure = Procedure; + mSmmMpSyncData->StartupProcArgs = ProcedureArguments; + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c new file mode 100644 index 000000000..db68e1316 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -0,0 +1,1470 @@ +/** @file +Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. + +Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.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; + +// +// SMM Relocation variables +// +volatile BOOLEAN *mRebased; +volatile BOOLEAN mIsBsp; + +/// +/// 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]; + +// +// SMM stack information +// +UINTN mSmmStackArrayBase; +UINTN mSmmStackArrayEnd; +UINTN mSmmStackSize; + +UINTN mSmmShadowStackSize; +BOOLEAN mCetSupported = TRUE; + +UINTN mMaxNumberOfCpus = 1; +UINTN mNumberOfCpus = 1; + +// +// SMM ready to lock flag +// +BOOLEAN mSmmReadyToLock = FALSE; + +// +// Global used to cache PCD for SMM Code Access Check enable +// +BOOLEAN mSmmCodeAccessCheckEnable = 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; + +// +// Control register contents saved for SMM S3 resume state initialization. +// +UINT32 mSmmCr0; +UINT32 mSmmCr4; + +/** + 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 >= gSmst->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 = SmmCpuFeaturesReadSaveStateRegister (CpuIndex, Register, Width, Buffer); + if (Status == EFI_UNSUPPORTED) { + Status = ReadSaveStateRegister (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; + } + + // + // 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 = SmmCpuFeaturesWriteSaveStateRegister (CpuIndex, Register, Width, Buffer); + if (Status == EFI_UNSUPPORTED) { + Status = WriteSaveStateRegister (CpuIndex, Register, Width, Buffer); + } + return Status; +} + + +/** + C function for SMI handler. To change all processor's SMMBase Register. + +**/ +VOID +EFIAPI +SmmInitHandler ( + VOID + ) +{ + UINT32 ApicId; + UINTN Index; + + // + // Update SMM IDT entries' code segment and load IDT + // + AsmWriteIdtr (&gcSmiIdtr); + ApicId = GetApicId (); + + ASSERT (mNumberOfCpus <= mMaxNumberOfCpus); + + for (Index = 0; Index < mNumberOfCpus; Index++) { + if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) { + // + // Initialize SMM specific features on the currently executing CPU + // + SmmCpuFeaturesInitializeProcessor ( + Index, + mIsBsp, + gSmmCpuPrivate->ProcessorInfo, + &mCpuHotPlugData + ); + + if (!mSmmS3Flag) { + // + // Check XD and BTS features on each processor on normal boot + // + CheckFeatureSupported (); + } + + if (mIsBsp) { + // + // BSP rebase is already done above. + // Initialize private data during S3 resume + // + InitializeMpSyncData (); + } + + // + // Hook return after RSM to set SMM re-based flag + // + SemaphoreHook (Index, &mRebased[Index]); + + return; + } + } + ASSERT (FALSE); +} + +/** + Relocate SmmBases for each processor. + + Execute on first boot and all S3 resumes + +**/ +VOID +EFIAPI +SmmRelocateBases ( + VOID + ) +{ + UINT8 BakBuf[BACK_BUF_SIZE]; + SMRAM_SAVE_STATE_MAP BakBuf2; + SMRAM_SAVE_STATE_MAP *CpuStatePtr; + UINT8 *U8Ptr; + UINT32 ApicId; + UINTN Index; + UINTN BspIndex; + + // + // Make sure the reserved size is large enough for procedure SmmInitTemplate. + // + ASSERT (sizeof (BakBuf) >= gcSmmInitSize); + + // + // Patch ASM code template with current CR0, CR3, and CR4 values + // + mSmmCr0 = (UINT32)AsmReadCr0 (); + PatchInstructionX86 (gPatchSmmCr0, mSmmCr0, 4); + PatchInstructionX86 (gPatchSmmCr3, AsmReadCr3 (), 4); + mSmmCr4 = (UINT32)AsmReadCr4 (); + PatchInstructionX86 (gPatchSmmCr4, mSmmCr4 & (~CR4_CET_ENABLE), 4); + + // + // Patch GDTR for SMM base relocation + // + gcSmiInitGdtr.Base = gcSmiGdtr.Base; + gcSmiInitGdtr.Limit = gcSmiGdtr.Limit; + + U8Ptr = (UINT8*)(UINTN)(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET); + CpuStatePtr = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET); + + // + // Backup original contents at address 0x38000 + // + CopyMem (BakBuf, U8Ptr, sizeof (BakBuf)); + CopyMem (&BakBuf2, CpuStatePtr, sizeof (BakBuf2)); + + // + // Load image for relocation + // + CopyMem (U8Ptr, gcSmmInitTemplate, gcSmmInitSize); + + // + // Retrieve the local APIC ID of current processor + // + ApicId = GetApicId (); + + // + // Relocate SM bases for all APs + // This is APs' 1st SMI - rebase will be done here, and APs' default SMI handler will be overridden by gcSmmInitTemplate + // + mIsBsp = FALSE; + BspIndex = (UINTN)-1; + for (Index = 0; Index < mNumberOfCpus; Index++) { + mRebased[Index] = FALSE; + if (ApicId != (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) { + SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId); + // + // Wait for this AP to finish its 1st SMI + // + while (!mRebased[Index]); + } else { + // + // BSP will be Relocated later + // + BspIndex = Index; + } + } + + // + // Relocate BSP's SMM base + // + ASSERT (BspIndex != (UINTN)-1); + mIsBsp = TRUE; + SendSmiIpi (ApicId); + // + // Wait for the BSP to finish its 1st SMI + // + while (!mRebased[BspIndex]); + + // + // Restore contents at address 0x38000 + // + CopyMem (CpuStatePtr, &BakBuf2, sizeof (BakBuf2)); + CopyMem (U8Ptr, BakBuf, sizeof (BakBuf)); +} + +/** + SMM Ready To Lock event notification handler. + + The CPU S3 data is copied to SMRAM for security and mSmmReadyToLock is set to + perform additional lock actions that must be performed from SMM on the next SMI. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. + **/ +EFI_STATUS +EFIAPI +SmmReadyToLockEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + GetAcpiCpuData (); + + // + // Cache a copy of UEFI memory map before we start profiling feature. + // + GetUefiMemoryMap (); + + // + // Set SMM ready to lock flag and return + // + mSmmReadyToLock = TRUE; + return EFI_SUCCESS; +} + +/** + The module Entry Point of the CPU SMM 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 occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +PiCpuSmmEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpServices; + UINTN NumberOfEnabledProcessors; + UINTN Index; + VOID *Buffer; + UINTN BufferPages; + UINTN TileCodeSize; + UINTN TileDataSize; + UINTN TileSize; + UINT8 *Stacks; + VOID *Registration; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + UINTN FamilyId; + UINTN ModelId; + UINT32 Cr3; + + // + // Initialize address fixup + // + PiSmmCpuSmmInitFixupAddress (); + PiSmmCpuSmiEntryFixupAddress (); + + // + // Initialize Debug Agent to support source level debug in SMM code + // + InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, NULL, 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); + + // + // Get MP Services Protocol + // + Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices); + ASSERT_EFI_ERROR (Status); + + // + // Use MP Services Protocol to retrieve the number of processors and number of enabled processors + // + Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfCpus, &NumberOfEnabledProcessors); + ASSERT_EFI_ERROR (Status); + ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + + // + // 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 ( + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + + ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection)); + } + ); + + // + // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable. + // + mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable); + DEBUG ((EFI_D_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable)); + + // + // Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable. + // Make sure AddressEncMask is contained to smallest supported address field. + // + mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + DEBUG ((EFI_D_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask)); + + // + // If support CPU hot plug, we need to allocate resources for possibly hot-added processors + // + if (FeaturePcdGet (PcdCpuHotPlugSupport)) { + mMaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + } else { + mMaxNumberOfCpus = mNumberOfCpus; + } + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus; + + // + // 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_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax > CPUID_EXTENDED_FUNCTION) { + 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); + } + + // + // 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 ((EFI_D_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)); + + // + // Allocate buffer for all of the tiles. + // + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual + // Volume 3C, Section 34.11 SMBASE Relocation + // For Pentium and Intel486 processors, the SMBASE values must be + // aligned on a 32-KByte boundary or the processor will enter shutdown + // state during the execution of a RSM instruction. + // + // Intel486 processors: FamilyId is 4 + // Pentium processors : FamilyId is 5 + // + BufferPages = EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberOfCpus - 1)); + if ((FamilyId == 4) || (FamilyId == 5)) { + Buffer = AllocateAlignedCodePages (BufferPages, SIZE_32KB); + } else { + Buffer = AllocateAlignedCodePages (BufferPages, SIZE_4KB); + } + ASSERT (Buffer != NULL); + DEBUG ((EFI_D_INFO, "SMRAM SaveState Buffer (0x%08x, 0x%08x)\n", Buffer, EFI_PAGES_TO_SIZE(BufferPages))); + + // + // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA. + // + gSmmCpuPrivate->ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * mMaxNumberOfCpus); + ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL); + + 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.SmBase = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus); + ASSERT (mCpuHotPlugData.SmBase != 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++) { + mCpuHotPlugData.SmBase[Index] = (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET; + 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) { + Status = MpServices->GetProcessorInfo (MpServices, Index, &gSmmCpuPrivate->ProcessorInfo[Index]); + ASSERT_EFI_ERROR (Status); + mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId; + + DEBUG ((EFI_D_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)) { + // + // 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 | + // +-------------------------------------------+-----+-------------------------------------------+ + // | | | | + // |<-------------- Processor 0 -------------->| |<-------------- Processor n -------------->| + // + mSmmStackSize += EFI_PAGES_TO_SIZE (2); + } + + mSmmShadowStackSize = 0; + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + // + // Append Shadow Stack after normal stack + // + // |= Stacks + // +--------------------------------------------------+---------------------------------------------------------------+ + // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack | + // +--------------------------------------------------+---------------------------------------------------------------+ + // | |PcdCpuSmmStackSize| |PcdCpuSmmShadowStackSize| + // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->| + // | | + // |<-------------------------------------------- Processor N ------------------------------------------------------->| + // + mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize))); + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2); + } + } + + 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)); + } + + // + // Set SMI stack for SMM base relocation + // + PatchInstructionX86 ( + gPatchSmmInitStack, + (UINTN) (Stacks + mSmmStackSize - sizeof (UINTN)), + sizeof (UINTN) + ); + + // + // Initialize IDT + // + InitializeSmmIdt (); + + // + // Relocate SMM Base addresses to the ones allocated from SMRAM + // + mRebased = (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumberOfCpus); + ASSERT (mRebased != NULL); + SmmRelocateBases (); + + // + // 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)); + + // + // 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)) { + SetNotPresentPage ( + Cr3, + (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE(1) + (mSmmStackSize + mSmmShadowStackSize) * Index, + EFI_PAGES_TO_SIZE(1) + ); + } + } + } + + // + // Fill in SMM Reserved Regions + // + gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0; + gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0; + + // + // 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 = SystemTable->BootServices->InstallMultipleProtocolInterfaces ( + &gSmmCpuPrivate->SmmCpuHandle, + &gEfiSmmConfigurationProtocolGuid, &gSmmCpuPrivate->SmmConfiguration, + NULL + ); + 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 (); + + // + // 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)) { + Status = PcdSet64S (PcdCpuHotPlugDataAddress, (UINT64)(UINTN)&mCpuHotPlugData); + ASSERT_EFI_ERROR (Status); + } + + // + // Initialize SMM CPU Services Support + // + Status = InitializeSmmCpuServices (mSmmCpuHandle); + ASSERT_EFI_ERROR (Status); + + // + // register SMM Ready To Lock Protocol notification + // + Status = gSmst->SmmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + SmmReadyToLockEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); + + // + // Initialize SMM Profile feature + // + InitSmmProfile (Cr3); + + GetAcpiS3EnableFlag (); + InitSmmS3ResumeState (Cr3); + + DEBUG ((EFI_D_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n")); + + return EFI_SUCCESS; +} + +/** + + 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; + + // + // 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); + + // + // 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 ((EFI_D_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; + + // + // Check to see if the Feature Control MSR is supported on this CPU + // + Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu; + if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) { + mSmmCodeAccessCheckEnable = FALSE; + 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; + 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); + } + } +} + +/** + This API provides a way to allocate memory for page table. + + This API can be called more once to allocate memory for page tables. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +AllocatePageTableMemory ( + IN UINTN Pages + ) +{ + VOID *Buffer; + + Buffer = SmmCpuFeaturesAllocatePageTableMemory (Pages); + if (Buffer != NULL) { + return Buffer; + } + return AllocatePages (Pages); +} + +/** + 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; +} + +/** + Allocate aligned pages for code. + + @param[in] Pages Number of pages to be allocated. + @param[in] Alignment The requested alignment of the allocation. + Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return Allocated memory. +**/ +VOID * +AllocateAlignedCodePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + UINTN AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + if (Pages == 0) { + return NULL; + } + if (Alignment > EFI_PAGE_SIZE) { + // + // Calculate the total number of pages since alignment is larger than page size. + // + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + // + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // + ASSERT (RealPages > Pages); + + Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, RealPages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + Status = gSmst->SmmFreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + Status = gSmst->SmmFreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + } else { + // + // Do not over-allocate pages in this case. + // + Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + AlignedMemory = (UINTN) Memory; + } + return (VOID *) AlignedMemory; +} + +/** + Perform the remaining tasks. + +**/ +VOID +PerformRemainingTasks ( + VOID + ) +{ + if (mSmmReadyToLock) { + // + // 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 (); + + SmmCpuFeaturesCompleteSmmReadyToLock (); + + // + // Clean SMM ready to lock flag + // + mSmmReadyToLock = FALSE; + } +} + +/** + Perform the pre tasks. + +**/ +VOID +PerformPreTasks ( + VOID + ) +{ + RestoreSmmConfigurationInS3 (); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h new file mode 100644 index 000000000..7fb3a2d9e --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -0,0 +1,1476 @@ +/** @file +Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. + +Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_PISMMCPUDXESMM_H_ +#define _CPU_PISMMCPUDXESMM_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "CpuService.h" +#include "SmmProfile.h" + +// +// CET definition +// +#define CPUID_CET_SS BIT7 +#define CPUID_CET_IBT BIT20 + +#define CR4_CET_ENABLE BIT23 + +#define MSR_IA32_S_CET 0x6A2 +#define MSR_IA32_PL0_SSP 0x6A4 +#define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8 + +typedef union { + struct { + // enable shadow stacks + UINT32 SH_STK_ENP:1; + // enable the WRSS{D,Q}W instructions. + UINT32 WR_SHSTK_EN:1; + // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction. + UINT32 ENDBR_EN:1; + // enable legacy compatibility treatment for indirect call/jmp tracking. + UINT32 LEG_IW_EN:1; + // enable use of no-track prefix on indirect call/jmp. + UINT32 NO_TRACK_EN:1; + // disable suppression of CET indirect branch tracking on legacy compatibility. + UINT32 SUPPRESS_DIS:1; + UINT32 RSVD:4; + // indirect branch tracking is suppressed. + // This bit can be written to 1 only if TRACKER is written as IDLE. + UINT32 SUPPRESS:1; + // Value of the endbranch state machine + // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1). + UINT32 TRACKER:1; + // linear address of a bitmap in memory indicating valid + // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled + // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on + // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are + // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address + // (this automatically aligns the address on a 4-Kbyte boundary). + UINT32 EB_LEG_BITMAP_BASE_low:12; + UINT32 EB_LEG_BITMAP_BASE_high:32; + } Bits; + UINT64 Uint64; +} MSR_IA32_CET; + +// +// MSRs required for configuration of SMM Code Access Check +// +#define EFI_MSR_SMM_MCA_CAP 0x17D +#define SMM_CODE_ACCESS_CHK_BIT BIT58 + +#define SMM_FEATURE_CONTROL_LOCK_BIT BIT0 +#define SMM_CODE_CHK_EN_BIT BIT2 + +/// +/// Page Table Entry +/// +#define IA32_PG_P BIT0 +#define IA32_PG_RW BIT1 +#define IA32_PG_U BIT2 +#define IA32_PG_WT BIT3 +#define IA32_PG_CD BIT4 +#define IA32_PG_A BIT5 +#define IA32_PG_D BIT6 +#define IA32_PG_PS BIT7 +#define IA32_PG_PAT_2M BIT12 +#define IA32_PG_PAT_4K IA32_PG_PS +#define IA32_PG_PMNT BIT62 +#define IA32_PG_NX BIT63 + +#define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P) +// +// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE +// X64 PAE PDPTE does not have such restriction +// +#define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P) + +#define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS) + +#define PAGING_4K_MASK 0xFFF +#define PAGING_2M_MASK 0x1FFFFF +#define PAGING_1G_MASK 0x3FFFFFFF + +#define PAGING_PAE_INDEX_MASK 0x1FF + +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull +#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull + +#define SMRR_MAX_ADDRESS BASE_4GB + +typedef enum { + PageNone, + Page4K, + Page2M, + Page1G, +} PAGE_ATTRIBUTE; + +typedef struct { + PAGE_ATTRIBUTE Attribute; + UINT64 Length; + UINT64 AddressMask; +} PAGE_ATTRIBUTE_TABLE; + +// +// Size of Task-State Segment defined in IA32 Manual +// +#define TSS_SIZE 104 +#define EXCEPTION_TSS_SIZE (TSS_SIZE + 4) // Add 4 bytes SSP +#define TSS_X64_IST1_OFFSET 36 +#define TSS_IA32_CR3_OFFSET 28 +#define TSS_IA32_ESP_OFFSET 56 +#define TSS_IA32_SSP_OFFSET 104 + +#define CR0_WP BIT16 + +// +// Code select value +// +#define PROTECT_MODE_CODE_SEGMENT 0x08 +#define LONG_MODE_CODE_SEGMENT 0x38 + +// +// The size 0x20 must be bigger than +// the size of template code of SmmInit. Currently, +// the size of SmmInit requires the 0x16 Bytes buffer +// at least. +// +#define BACK_BUF_SIZE 0x20 + +#define EXCEPTION_VECTOR_NUMBER 0x20 + +#define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL + +typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS; +#define ARRIVAL_EXCEPTION_BLOCKED 0x1 +#define ARRIVAL_EXCEPTION_DELAYED 0x2 +#define ARRIVAL_EXCEPTION_SMI_DISABLED 0x4 + +// +// Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE. +// +typedef struct { + EFI_AP_PROCEDURE Procedure; + VOID *ProcedureArgument; +} PROCEDURE_WRAPPER; + +#define PROCEDURE_TOKEN_SIGNATURE SIGNATURE_32 ('P', 'R', 'T', 'S') + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + SPIN_LOCK *SpinLock; + volatile UINT32 RunningApCount; +} PROCEDURE_TOKEN; + +#define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE) + +#define TOKEN_BUFFER_SIGNATURE SIGNATURE_32 ('T', 'K', 'B', 'S') + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT8 *Buffer; +} TOKEN_BUFFER; + +#define TOKEN_BUFFER_FROM_LINK(a) CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE) + +// +// Private structure for the SMM CPU module that is stored in DXE Runtime memory +// Contains the SMM Configuration Protocols that is produced. +// Contains a mix of DXE and SMM contents. All the fields must be used properly. +// +#define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u') + +typedef struct { + UINTN Signature; + + EFI_HANDLE SmmCpuHandle; + + EFI_PROCESSOR_INFORMATION *ProcessorInfo; + SMM_CPU_OPERATION *Operation; + UINTN *CpuSaveStateSize; + VOID **CpuSaveState; + + EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1]; + EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext; + EFI_SMM_ENTRY_POINT SmmCoreEntry; + + EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration; + + PROCEDURE_WRAPPER *ApWrapperFunc; + LIST_ENTRY TokenList; + LIST_ENTRY *FirstFreeToken; +} SMM_CPU_PRIVATE_DATA; + +extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; +extern CPU_HOT_PLUG_DATA mCpuHotPlugData; +extern UINTN mMaxNumberOfCpus; +extern UINTN mNumberOfCpus; +extern EFI_SMM_CPU_PROTOCOL mSmmCpu; +extern EFI_MM_MP_PROTOCOL mSmmMp; + +/// +/// The mode of the CPU at the time an SMI occurs +/// +extern UINT8 mSmmSaveStateRegisterLma; + +// +// SMM CPU Protocol function prototypes. +// + +/** + 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 + ); + +/** + 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 + ); + +/** +Read a CPU Save State register on the target processor. + +This function abstracts the differences that whether the CPU Save State register is in the +IA32 CPU Save State Map or X64 CPU Save State Map. + +This function supports reading a CPU Save State register in SMBase relocation handler. + +@param[in] CpuIndex Specifies the zero-based index of the CPU save state. +@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. +@param[in] Width The number of bytes to read from the CPU save state. +@param[out] 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 +ReadSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + OUT VOID *Buffer + ); + +/** +Write value to a CPU Save State register on the target processor. + +This function abstracts the differences that whether the CPU Save State register is in the +IA32 CPU Save State Map or X64 CPU Save State Map. + +This function supports writing a CPU Save State register in SMBase relocation handler. + +@param[in] CpuIndex Specifies the zero-based index of the CPU save state. +@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. +@param[in] Width The number of bytes to read from the CPU save state. +@param[in] Buffer Upon entry, this holds the new CPU register value. + +@retval EFI_SUCCESS The register was written to 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 +WriteSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + IN CONST VOID *Buffer + ); + +extern CONST UINT8 gcSmmInitTemplate[]; +extern CONST UINT16 gcSmmInitSize; +X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0; +extern UINT32 mSmmCr0; +X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3; +extern UINT32 mSmmCr4; +X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4; +X86_ASSEMBLY_PATCH_LABEL gPatchSmmInitStack; +X86_ASSEMBLY_PATCH_LABEL mPatchCetSupported; +extern BOOLEAN mCetSupported; + +/** + Semaphore operation for all processor relocate SMMBase. +**/ +VOID +EFIAPI +SmmRelocationSemaphoreComplete ( + VOID + ); + +/// +/// The type of SMM CPU Information +/// +typedef struct { + SPIN_LOCK *Busy; + volatile EFI_AP_PROCEDURE2 Procedure; + volatile VOID *Parameter; + volatile UINT32 *Run; + volatile BOOLEAN *Present; + PROCEDURE_TOKEN *Token; + 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 *Counter; + volatile UINT32 BspIndex; + volatile BOOLEAN *InsideSmm; + volatile BOOLEAN *AllCpusInSync; + volatile SMM_CPU_SYNC_MODE EffectiveSyncMode; + volatile BOOLEAN SwitchBsp; + volatile BOOLEAN *CandidateBsp; + EFI_AP_PROCEDURE StartupProcedure; + VOID *StartupProcArgs; +} SMM_DISPATCHER_MP_SYNC_DATA; + +#define SMM_PSD_OFFSET 0xfb00 + +/// +/// All global semaphores' pointer +/// +typedef struct { + volatile UINT32 *Counter; + volatile BOOLEAN *InsideSmm; + volatile BOOLEAN *AllCpusInSync; + SPIN_LOCK *PFLock; + SPIN_LOCK *CodeAccessCheckLock; +} SMM_CPU_SEMAPHORE_GLOBAL; + +/// +/// All semaphores for each processor +/// +typedef struct { + SPIN_LOCK *Busy; + volatile UINT32 *Run; + volatile BOOLEAN *Present; + SPIN_LOCK *Token; +} SMM_CPU_SEMAPHORE_CPU; + +/// +/// All semaphores' information +/// +typedef struct { + SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal; + SMM_CPU_SEMAPHORE_CPU SemaphoreCpu; +} SMM_CPU_SEMAPHORES; + +extern IA32_DESCRIPTOR gcSmiGdtr; +extern EFI_PHYSICAL_ADDRESS mGdtBuffer; +extern UINTN mGdtBufferSize; +extern IA32_DESCRIPTOR gcSmiIdtr; +extern VOID *gcSmiIdtrPtr; +extern UINT64 gPhyMask; +extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData; +extern UINTN mSmmStackArrayBase; +extern UINTN mSmmStackArrayEnd; +extern UINTN mSmmStackSize; +extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService; +extern IA32_DESCRIPTOR gcSmiInitGdtr; +extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores; +extern UINTN mSemaphoreSize; +extern SPIN_LOCK *mPFLock; +extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock; +extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; +extern UINTN mSmmCpuSmramRangeCount; +extern UINT8 mPhysicalAddressBits; + +// +// Copy of the PcdPteMemoryEncryptionAddressOrMask +// +extern UINT64 mAddressEncMask; + +/** + Create 4G PageTable in SMRAM. + + @param[in] Is32BitPageTable Whether the page table is 32-bit PAE + @return PageTable Address + +**/ +UINT32 +Gen4GPageTable ( + IN BOOLEAN Is32BitPageTable + ); + + +/** + Initialize global data for MP synchronization. + + @param Stacks Base address of SMI stack buffer for all processors. + @param StackSize Stack size for each processor in SMM. + @param ShadowStackSize Shadow Stack size for each processor in SMM. + +**/ +UINT32 +InitializeMpServiceData ( + IN VOID *Stacks, + IN UINTN StackSize, + IN UINTN ShadowStackSize + ); + +/** + Initialize Timer for SMM AP Sync. + +**/ +VOID +InitializeSmmTimer ( + VOID + ); + +/** + Start Timer for SMM AP Sync. + +**/ +UINT64 +EFIAPI +StartSyncTimer ( + VOID + ); + +/** + Check if the SMM AP Sync timer is timeout. + + @param Timer The start timer from the begin. + +**/ +BOOLEAN +EFIAPI +IsSyncTimerTimeout ( + IN UINT64 Timer + ); + +/** + Initialize IDT for SMM Stack Guard. + +**/ +VOID +EFIAPI +InitializeIDTSmmStackGuard ( + VOID + ); + +/** + Initialize Gdt for all processors. + + @param[in] Cr3 CR3 value. + @param[out] GdtStepSize The step size for GDT table. + + @return GdtBase for processor 0. + GdtBase for processor X is: GdtBase + (GdtStepSize * X) +**/ +VOID * +InitGdt ( + IN UINTN Cr3, + OUT UINTN *GdtStepSize + ); + +/** + + Register the SMM Foundation entry point. + + @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance + @param SmmEntryPoint SMM Foundation EntryPoint + + @retval EFI_SUCCESS Successfully to register SMM foundation entry point + +**/ +EFI_STATUS +EFIAPI +RegisterSmmEntry ( + IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This, + IN EFI_SMM_ENTRY_POINT SmmEntryPoint + ); + +/** + Create PageTable for SMM use. + + @return PageTable Address + +**/ +UINT32 +SmmInitPageTable ( + VOID + ); + +/** + Schedule a procedure to run on the specified CPU. + + @param Procedure The address of the procedure to run + @param CpuIndex Target CPU number + @param ProcArguments The parameter to pass to the procedure + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS - The procedure has been successfully scheduled + +**/ +EFI_STATUS +EFIAPI +SmmStartupThisAp ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL + ); + +/** + Schedule a procedure to run on the specified CPU in a blocking fashion. + + @param Procedure The address of the procedure to run + @param CpuIndex Target CPU Index + @param ProcArguments The parameter to pass to the procedure + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS The procedure has been successfully scheduled + +**/ +EFI_STATUS +EFIAPI +SmmBlockingStartupThisAp ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL + ); + +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + Initialize MP synchronization data. + +**/ +VOID +EFIAPI +InitializeMpSyncData ( + VOID + ); + +/** + + 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 + ); + +/** + Relocate SmmBases for each processor. + + Execute on first boot and all S3 resumes + +**/ +VOID +EFIAPI +SmmRelocateBases ( + VOID + ); + +/** + Page Fault handler for SMM use. + + @param InterruptType Defines the type of interrupt or exception that + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. +**/ +VOID +EFIAPI +SmiPFHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ); + +/** + Perform the remaining tasks. + +**/ +VOID +PerformRemainingTasks ( + VOID + ); + +/** + Perform the pre tasks. + +**/ +VOID +PerformPreTasks ( + VOID + ); + +/** + Initialize MSR spin lock by MSR index. + + @param MsrIndex MSR index value. + +**/ +VOID +InitMsrSpinLockByIndex ( + IN UINT32 MsrIndex + ); + +/** + Hook return address of SMM Save State so that semaphore code + can be executed immediately after AP exits SMM to indicate to + the BSP that an AP has exited SMM after SMBASE relocation. + + @param[in] CpuIndex The processor index. + @param[in] RebasedFlag A pointer to a flag that is set to TRUE + immediately after AP exits SMM. + +**/ +VOID +SemaphoreHook ( + IN UINTN CpuIndex, + IN volatile BOOLEAN *RebasedFlag + ); + +/** +Configure SMM Code Access Check feature for all processors. +SMM Feature Control MSR will be locked after configuration. +**/ +VOID +ConfigSmmCodeAccessCheck ( + VOID + ); + +/** + Hook the code executed immediately after an RSM instruction on the currently + executing CPU. The mode of code executed immediately after RSM must be + detected, and the appropriate hook must be selected. Always clear the auto + HALT restart flag if it is set. + + @param[in] CpuIndex The processor index for the currently + executing CPU. + @param[in] CpuState Pointer to SMRAM Save State Map for the + currently executing CPU. + @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to + 32-bit mode from 64-bit SMM. + @param[in] NewInstructionPointer Instruction pointer to use if resuming to + same mode as SMM. + + @retval The value of the original instruction pointer before it was hooked. + +**/ +UINT64 +EFIAPI +HookReturnFromSmm ( + IN UINTN CpuIndex, + SMRAM_SAVE_STATE_MAP *CpuState, + UINT64 NewInstructionPointer32, + UINT64 NewInstructionPointer + ); + +/** + Get the size of the SMI Handler in bytes. + + @retval The size, in bytes, of the SMI Handler. + +**/ +UINTN +EFIAPI +GetSmiHandlerSize ( + VOID + ); + +/** + Install the SMI handler for the CPU specified by CpuIndex. This function + is called by the CPU that was elected as monarch during System Management + Mode initialization. + + @param[in] CpuIndex The index of the CPU to install the custom SMI handler. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. + @param[in] SmiStack The stack to use when an SMI is processed by the + the CPU specified by CpuIndex. + @param[in] StackSize The size, in bytes, if the stack used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtBase The base address of the GDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtBase The base address of the IDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] Cr3 The base address of the page tables to use when an SMI + is processed by the CPU specified by CpuIndex. +**/ +VOID +EFIAPI +InstallSmiHandler ( + IN UINTN CpuIndex, + IN UINT32 SmBase, + IN VOID *SmiStack, + IN UINTN StackSize, + IN UINTN GdtBase, + IN UINTN GdtSize, + IN UINTN IdtBase, + IN UINTN IdtSize, + IN UINT32 Cr3 + ); + +/** + Search module name by input IP address and output it. + + @param CallerIpAddress Caller instruction pointer. + +**/ +VOID +DumpModuleInfoByIp ( + IN UINTN CallerIpAddress + ); + +/** + This function sets memory attribute according to MemoryAttributesTable. +**/ +VOID +SetMemMapAttributes ( + VOID + ); + +/** + This function sets UEFI memory attribute according to UEFI memory map. +**/ +VOID +SetUefiMemMapAttributes ( + VOID + ); + +/** + 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 + ); + +/** + This function caches the UEFI memory map information. +**/ +VOID +GetUefiMemoryMap ( + VOID + ); + +/** + This function sets memory attribute for page table. +**/ +VOID +SetPageTableAttributes ( + VOID + ); + +/** + Return page table base. + + @return page table base. +**/ +UINTN +GetPageTableBase ( + VOID + ); + +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ); + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ); + +/** + This API provides a way to allocate memory for page table. + + This API can be called more once to allocate memory for page tables. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +AllocatePageTableMemory ( + IN UINTN Pages + ); + +/** + Allocate pages for code. + + @param[in] Pages Number of pages to be allocated. + + @return Allocated memory. +**/ +VOID * +AllocateCodePages ( + IN UINTN Pages + ); + +/** + Allocate aligned pages for code. + + @param[in] Pages Number of pages to be allocated. + @param[in] Alignment The requested alignment of the allocation. + Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return Allocated memory. +**/ +VOID * +AllocateAlignedCodePages ( + IN UINTN Pages, + IN UINTN Alignment + ); + + +// +// S3 related global variable and function prototype. +// + +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 + ); + +/** + Get ACPI CPU data. + +**/ +VOID +GetAcpiCpuData ( + VOID + ); + +/** + Restore SMM Configuration in S3 boot path. + +**/ +VOID +RestoreSmmConfigurationInS3 ( + VOID + ); + +/** + Get ACPI S3 enable flag. + +**/ +VOID +GetAcpiS3EnableFlag ( + VOID + ); + +/** + Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. + + @param[in] ApHltLoopCode The address of the safe hlt-loop function. + @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. + @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. + +**/ +VOID +TransferApToSafeState ( + IN UINTN ApHltLoopCode, + IN UINTN TopOfStack, + IN UINTN NumberToFinishAddress + ); + +/** + Set ShadowStack memory. + + @param[in] Cr3 The page table base address. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + + @retval EFI_SUCCESS The shadow stack memory is set. +**/ +EFI_STATUS +SetShadowStack ( + IN UINTN Cr3, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +/** + Set not present memory. + + @param[in] Cr3 The page table base address. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + + @retval EFI_SUCCESS The not present memory is set. +**/ +EFI_STATUS +SetNotPresentPage ( + IN UINTN Cr3, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +/** + Initialize the shadow stack related data structure. + + @param CpuIndex The index of CPU. + @param ShadowStack The bottom of the shadow stack for this CPU. +**/ +VOID +InitShadowStack ( + IN UINTN CpuIndex, + IN VOID *ShadowStack + ); + +/** + This function set given attributes of the memory region specified by + BaseAddress and Length. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memory + region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmSetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function clears given attributes of the memory region specified by + BaseAddress and Length. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to clear for the memory + region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be cleared together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmClearMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function retrieves the attributes of the memory region specified by + BaseAddress and Length. If different attributes are got from different part + of the memory region, EFI_NO_MAPPING will be returned. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes Pointer to attributes returned. + + @retval EFI_SUCCESS The attributes got for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes is NULL. + @retval EFI_NO_MAPPING Attributes are not consistent cross the memory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmGetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 *Attributes + ); + +/** + This function fixes up the address of the global variable or function + referred in SmmInit assembly files to be the absolute address. +**/ +VOID +EFIAPI +PiSmmCpuSmmInitFixupAddress ( + ); + +/** + This function fixes up the address of the global variable or function + referred in SmiEntry assembly files to be the absolute address. +**/ +VOID +EFIAPI +PiSmmCpuSmiEntryFixupAddress ( + ); + +/** + This function reads CR2 register when on-demand paging is enabled + for 64 bit and no action for 32 bit. + + @param[out] *Cr2 Pointer to variable to hold CR2 register value. +**/ +VOID +SaveCr2 ( + OUT UINTN *Cr2 + ); + +/** + This function writes into CR2 register when on-demand paging is enabled + for 64 bit and no action for 32 bit. + + @param[in] Cr2 Value to write into CR2 register. +**/ +VOID +RestoreCr2 ( + IN UINTN Cr2 + ); + +/** + Schedule a procedure to run on the specified CPU. + + @param[in] Procedure The address of the procedure to run + @param[in] CpuIndex Target CPU Index + @param[in,out] ProcArguments The parameter to pass to the procedure + @param[in,out] Token This is an optional parameter that allows the caller to execute the + procedure in a blocking or non-blocking fashion. If it is NULL the + call is blocking, and the call will not return until the AP has + completed the procedure. If the token is not NULL, the call will + return immediately. The caller can check whether the procedure has + completed with CheckOnProcedure or WaitForProcedure. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish + execution of Procedure, either for blocking or non-blocking mode. + Zero means infinity. If the timeout expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. If + the timeout expires in blocking mode, the call returns EFI_TIMEOUT. + If the timeout expires in non-blocking mode, the timeout determined + can be through CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an implementation + supports this feature can be determined via the Attributes data + member. + @param[in,out] CpuStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + @retval EFI_INVALID_PARAMETER CpuNumber not valid + @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM + @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy + @retval EFI_SUCCESS The procedure has been successfully scheduled + +**/ +EFI_STATUS +InternalSmmStartupThisAp ( + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN CpuIndex, + IN OUT VOID *ProcArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN UINTN TimeoutInMicroseconds, + IN OUT EFI_STATUS *CpuStatus + ); + +/** + Checks whether the input token is the current used token. + + @param[in] Token This parameter describes the token that was passed into DispatchProcedure or + BroadcastProcedure. + + @retval TRUE The input token is the current used token. + @retval FALSE The input token is not the current used token. +**/ +BOOLEAN +IsTokenInUse ( + IN SPIN_LOCK *Token + ); + +/** + Checks status of specified AP. + + This function checks whether the specified AP has finished the task assigned + by StartupThisAP(), and whether timeout expires. + + @param[in] Token This parameter describes the token that was passed into DispatchProcedure or + BroadcastProcedure. + + @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs(). + @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired. +**/ +EFI_STATUS +IsApReady ( + IN SPIN_LOCK *Token + ); + +/** + Check whether it is an present AP. + + @param CpuIndex The AP index which calls this function. + + @retval TRUE It's a present AP. + @retval TRUE This is not an AP or it is not present. + +**/ +BOOLEAN +IsPresentAp ( + IN UINTN CpuIndex + ); + +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in,out] ProcedureArguments The parameter passed into Procedure for + all APs. + @param[in,out] Token This is an optional parameter that allows the caller to execute the + procedure in a blocking or non-blocking fashion. If it is NULL the + call is blocking, and the call will not return until the AP has + completed the procedure. If the token is not NULL, the call will + return immediately. The caller can check whether the procedure has + completed with CheckOnProcedure or WaitForProcedure. + @param[in,out] CPUStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval others Failed to Startup all APs. + +**/ +EFI_STATUS +InternalSmmStartupAllAPs ( + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ); + +/** + + Register the SMM Foundation entry point. + + @param[in] Procedure A pointer to the code stream to be run on the designated target AP + of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2 + with the related definitions of + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs. + If caller may pass a value of NULL to deregister any existing + startup procedure. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is + run by the AP. It is an optional common mailbox between APs and + the caller to share information + + @retval EFI_SUCCESS The Procedure has been set successfully. + @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL. + +**/ +EFI_STATUS +RegisterStartupProcedure ( + IN EFI_AP_PROCEDURE Procedure, + IN OUT VOID *ProcedureArguments OPTIONAL + ); + +/** + Allocate buffer for SpinLock and Wrapper function buffer. + +**/ +VOID +InitializeDataForMmMp ( + VOID + ); + +/** + 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 + ); + +#endif diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf new file mode 100644 index 000000000..76b146299 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -0,0 +1,153 @@ +## @file +# CPU SMM driver. +# +# This SMM driver performs SMM initialization, deploy SMM Entry Vector, +# provides CPU specific services in SMM. +# +# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PiSmmCpuDxeSmm + MODULE_UNI_FILE = PiSmmCpuDxeSmm.uni + FILE_GUID = A3FF0EF5-0C28-42f5-B544-8C7DE1E80014 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = PiCpuSmmEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PiSmmCpuDxeSmm.c + PiSmmCpuDxeSmm.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 + +[Sources.Ia32] + Ia32/Semaphore.c + Ia32/PageTbl.c + Ia32/SmmFuncsArch.c + Ia32/SmmProfileArch.c + Ia32/SmmProfileArch.h + Ia32/SmmInit.nasm + Ia32/SmiEntry.nasm + Ia32/SmiException.nasm + Ia32/MpFuncs.nasm + Ia32/Cet.nasm + +[Sources.X64] + X64/Semaphore.c + X64/PageTbl.c + X64/SmmFuncsArch.c + X64/SmmProfileArch.c + X64/SmmProfileArch.h + X64/SmmInit.nasm + X64/SmiEntry.nasm + X64/SmiException.nasm + X64/MpFuncs.nasm + X64/Cet.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + PcdLib + DebugLib + BaseLib + SynchronizationLib + BaseMemoryLib + MtrrLib + IoLib + TimerLib + SmmServicesTableLib + MemoryAllocationLib + DebugAgentLib + HobLib + PciLib + LocalApicLib + UefiCpuLib + SmmCpuPlatformHookLib + CpuExceptionHandlerLib + UefiLib + DxeServicesTableLib + CpuLib + ReportStatusCodeLib + SmmCpuFeaturesLib + PeCoffGetEntryPointLib + +[Protocols] + gEfiSmmAccess2ProtocolGuid ## CONSUMES + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiSmmConfigurationProtocolGuid ## PRODUCES + gEfiSmmCpuProtocolGuid ## PRODUCES + gEfiSmmReadyToLockProtocolGuid ## NOTIFY + gEfiSmmCpuServiceProtocolGuid ## PRODUCES + gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES + gEfiMmMpProtocolGuid ## PRODUCES + +[Guids] + gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot. + gEdkiiPiSmmMemoryAttributesTableGuid ## CONSUMES ## SystemTable + gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable + +[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 + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## CONSUMES + +[FixedPcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk ## CONSUMES + +[Pcd.X64] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES + +[Depex] + gEfiMpServiceProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + PiSmmCpuDxeSmmExtra.uni diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni new file mode 100644 index 000000000..1ccae17b6 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni @@ -0,0 +1,15 @@ +// /** @file +// CPU SMM driver. +// +// This SMM driver performs SMM initialization, deploy SMM Entry Vector, +// provides CPU specific services in SMM. +// +// Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "CPU SMM driver" + +#string STR_MODULE_DESCRIPTION #language en-US "This SMM driver performs SMM initialization, deploys SMM Entry Vector, and provides CPU-specific services in SMM." diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni new file mode 100644 index 000000000..97e2815b3 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// PiSmmCpuDxeSmm Localized Strings and Content +// +// Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Processor SMM Initialization DXE Driver" diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c new file mode 100644 index 000000000..9c5a92af6 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -0,0 +1,1588 @@ +/** @file + +Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+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; + +PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { + {Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64}, + {Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64}, + {Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64}, +}; + +UINTN mInternalGr3; + +/** + Set the internal page table base address. + If it is non zero, further MemoryAttribute modification will be on this page table. + If it is zero, further MemoryAttribute modification will be on real page table. + + @param Cr3 page table base. +**/ +VOID +SetPageTableBase ( + IN UINTN Cr3 + ) +{ + mInternalGr3 = Cr3; +} + +/** + Return page table base. + + @return page table base. +**/ +UINTN +GetPageTableBase ( + VOID + ) +{ + if (mInternalGr3 != 0) { + return mInternalGr3; + } + return (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64); +} + +/** + Return length according to page attributes. + + @param[in] PageAttributes The page attribute of the page entry. + + @return The length of page entry. +**/ +UINTN +PageAttributeToLength ( + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mPageAttributeTable)/sizeof(mPageAttributeTable[0]); Index++) { + if (PageAttribute == mPageAttributeTable[Index].Attribute) { + return (UINTN)mPageAttributeTable[Index].Length; + } + } + return 0; +} + +/** + Return address mask according to page attributes. + + @param[in] PageAttributes The page attribute of the page entry. + + @return The address mask of page entry. +**/ +UINTN +PageAttributeToMask ( + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mPageAttributeTable)/sizeof(mPageAttributeTable[0]); Index++) { + if (PageAttribute == mPageAttributeTable[Index].Attribute) { + return (UINTN)mPageAttributeTable[Index].AddressMask; + } + } + return 0; +} + +/** + Return page table entry to match the address. + + @param[in] Address The address to be checked. + @param[out] PageAttributes The page attribute of the page entry. + + @return The page entry. +**/ +VOID * +GetPageTableEntry ( + IN PHYSICAL_ADDRESS Address, + OUT PAGE_ATTRIBUTE *PageAttribute + ) +{ + UINTN Index1; + UINTN Index2; + UINTN Index3; + UINTN Index4; + UINTN Index5; + UINT64 *L1PageTable; + UINT64 *L2PageTable; + UINT64 *L3PageTable; + UINT64 *L4PageTable; + UINT64 *L5PageTable; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + + Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK; + Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK; + Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK; + Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK; + Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK; + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + + if (sizeof(UINTN) == sizeof(UINT64)) { + if (Enable5LevelPaging) { + L5PageTable = (UINT64 *)GetPageTableBase (); + if (L5PageTable[Index5] == 0) { + *PageAttribute = PageNone; + return NULL; + } + + L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + } else { + L4PageTable = (UINT64 *)GetPageTableBase (); + } + if (L4PageTable[Index4] == 0) { + *PageAttribute = PageNone; + return NULL; + } + + L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + } else { + L3PageTable = (UINT64 *)GetPageTableBase (); + } + if (L3PageTable[Index3] == 0) { + *PageAttribute = PageNone; + return NULL; + } + if ((L3PageTable[Index3] & IA32_PG_PS) != 0) { + // 1G + *PageAttribute = Page1G; + return &L3PageTable[Index3]; + } + + L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L2PageTable[Index2] == 0) { + *PageAttribute = PageNone; + return NULL; + } + if ((L2PageTable[Index2] & IA32_PG_PS) != 0) { + // 2M + *PageAttribute = Page2M; + return &L2PageTable[Index2]; + } + + // 4k + L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if ((L1PageTable[Index1] == 0) && (Address != 0)) { + *PageAttribute = PageNone; + return NULL; + } + *PageAttribute = Page4K; + return &L1PageTable[Index1]; +} + +/** + Return memory attributes of page entry. + + @param[in] PageEntry The page entry. + + @return Memory attributes of page entry. +**/ +UINT64 +GetAttributesFromPageEntry ( + IN UINT64 *PageEntry + ) +{ + UINT64 Attributes; + Attributes = 0; + if ((*PageEntry & IA32_PG_P) == 0) { + Attributes |= EFI_MEMORY_RP; + } + if ((*PageEntry & IA32_PG_RW) == 0) { + Attributes |= EFI_MEMORY_RO; + } + if ((*PageEntry & IA32_PG_NX) != 0) { + Attributes |= EFI_MEMORY_XP; + } + return Attributes; +} + +/** + Modify memory attributes of page entry. + + @param[in] PageEntry The page entry. + @param[in] Attributes The bit mask of attributes to modify for the memory region. + @param[in] IsSet TRUE means to set attributes. FALSE means to clear attributes. + @param[out] IsModified TRUE means page table modified. FALSE means page table not modified. +**/ +VOID +ConvertPageEntryAttribute ( + IN UINT64 *PageEntry, + IN UINT64 Attributes, + IN BOOLEAN IsSet, + OUT BOOLEAN *IsModified + ) +{ + UINT64 CurrentPageEntry; + UINT64 NewPageEntry; + + CurrentPageEntry = *PageEntry; + NewPageEntry = CurrentPageEntry; + if ((Attributes & EFI_MEMORY_RP) != 0) { + if (IsSet) { + NewPageEntry &= ~(UINT64)IA32_PG_P; + } else { + NewPageEntry |= IA32_PG_P; + } + } + if ((Attributes & EFI_MEMORY_RO) != 0) { + if (IsSet) { + NewPageEntry &= ~(UINT64)IA32_PG_RW; + if (mInternalGr3 != 0) { + // Environment setup + // ReadOnly page need set Dirty bit for shadow stack + NewPageEntry |= IA32_PG_D; + // Clear user bit for supervisor shadow stack + NewPageEntry &= ~(UINT64)IA32_PG_U; + } else { + // Runtime update + // Clear dirty bit for non shadow stack, to protect RO page. + NewPageEntry &= ~(UINT64)IA32_PG_D; + } + } else { + NewPageEntry |= IA32_PG_RW; + } + } + if ((Attributes & EFI_MEMORY_XP) != 0) { + if (mXdSupported) { + if (IsSet) { + NewPageEntry |= IA32_PG_NX; + } else { + NewPageEntry &= ~IA32_PG_NX; + } + } + } + *PageEntry = NewPageEntry; + if (CurrentPageEntry != NewPageEntry) { + *IsModified = TRUE; + DEBUG ((DEBUG_VERBOSE, "ConvertPageEntryAttribute 0x%lx", CurrentPageEntry)); + DEBUG ((DEBUG_VERBOSE, "->0x%lx\n", NewPageEntry)); + } else { + *IsModified = FALSE; + } +} + +/** + This function returns if there is need to split page entry. + + @param[in] BaseAddress The base address to be checked. + @param[in] Length The length to be checked. + @param[in] PageEntry The page entry to be checked. + @param[in] PageAttribute The page attribute of the page entry. + + @retval SplitAttributes on if there is need to split page entry. +**/ +PAGE_ATTRIBUTE +NeedSplitPage ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 *PageEntry, + IN PAGE_ATTRIBUTE PageAttribute + ) +{ + UINT64 PageEntryLength; + + PageEntryLength = PageAttributeToLength (PageAttribute); + + if (((BaseAddress & (PageEntryLength - 1)) == 0) && (Length >= PageEntryLength)) { + return PageNone; + } + + if (((BaseAddress & PAGING_2M_MASK) != 0) || (Length < SIZE_2MB)) { + return Page4K; + } + + return Page2M; +} + +/** + This function splits one page entry to small page entries. + + @param[in] PageEntry The page entry to be splitted. + @param[in] PageAttribute The page attribute of the page entry. + @param[in] SplitAttribute How to split the page entry. + + @retval RETURN_SUCCESS The page entry is splitted. + @retval RETURN_UNSUPPORTED The page entry does not support to be splitted. + @retval RETURN_OUT_OF_RESOURCES No resource to split page entry. +**/ +RETURN_STATUS +SplitPage ( + IN UINT64 *PageEntry, + IN PAGE_ATTRIBUTE PageAttribute, + IN PAGE_ATTRIBUTE SplitAttribute + ) +{ + UINT64 BaseAddress; + UINT64 *NewPageEntry; + UINTN Index; + + ASSERT (PageAttribute == Page2M || PageAttribute == Page1G); + + if (PageAttribute == Page2M) { + // + // Split 2M to 4K + // + ASSERT (SplitAttribute == Page4K); + if (SplitAttribute == Page4K) { + NewPageEntry = AllocatePageTableMemory (1); + DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); + if (NewPageEntry == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + BaseAddress = *PageEntry & PAGING_2M_ADDRESS_MASK_64; + for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { + NewPageEntry[Index] = (BaseAddress + SIZE_4KB * Index) | mAddressEncMask | ((*PageEntry) & PAGE_PROGATE_BITS); + } + (*PageEntry) = (UINT64)(UINTN)NewPageEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + return RETURN_SUCCESS; + } else { + return RETURN_UNSUPPORTED; + } + } else if (PageAttribute == Page1G) { + // + // Split 1G to 2M + // No need support 1G->4K directly, we should use 1G->2M, then 2M->4K to get more compact page table. + // + ASSERT (SplitAttribute == Page2M || SplitAttribute == Page4K); + if ((SplitAttribute == Page2M || SplitAttribute == Page4K)) { + NewPageEntry = AllocatePageTableMemory (1); + DEBUG ((DEBUG_VERBOSE, "Split - 0x%x\n", NewPageEntry)); + if (NewPageEntry == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + BaseAddress = *PageEntry & PAGING_1G_ADDRESS_MASK_64; + for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { + NewPageEntry[Index] = (BaseAddress + SIZE_2MB * Index) | mAddressEncMask | IA32_PG_PS | ((*PageEntry) & PAGE_PROGATE_BITS); + } + (*PageEntry) = (UINT64)(UINTN)NewPageEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + return RETURN_SUCCESS; + } else { + return RETURN_UNSUPPORTED; + } + } else { + return RETURN_UNSUPPORTED; + } +} + +/** + This function modifies the page attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + Caller should make sure BaseAddress and Length is at page boundary. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to modify for the memory region. + @param[in] IsSet TRUE means to set attributes. FALSE means to clear attributes. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + @param[out] IsModified TRUE means page table modified. FALSE means page table not modified. + + @retval RETURN_SUCCESS The attributes were modified for the memory region. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. +**/ +RETURN_STATUS +EFIAPI +ConvertMemoryPageAttributes ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN BOOLEAN IsSet, + OUT BOOLEAN *IsSplitted, OPTIONAL + OUT BOOLEAN *IsModified OPTIONAL + ) +{ + UINT64 *PageEntry; + PAGE_ATTRIBUTE PageAttribute; + UINTN PageEntryLength; + PAGE_ATTRIBUTE SplitAttribute; + RETURN_STATUS Status; + BOOLEAN IsEntryModified; + EFI_PHYSICAL_ADDRESS MaximumSupportMemAddress; + + ASSERT (Attributes != 0); + ASSERT ((Attributes & ~(EFI_MEMORY_RP | EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0); + + ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0); + ASSERT ((Length & (SIZE_4KB - 1)) == 0); + + if (Length == 0) { + return RETURN_INVALID_PARAMETER; + } + + MaximumSupportMemAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, mPhysicalAddressBits) - 1); + if (BaseAddress > MaximumSupportMemAddress) { + return RETURN_UNSUPPORTED; + } + if (Length > MaximumSupportMemAddress) { + return RETURN_UNSUPPORTED; + } + if ((Length != 0) && (BaseAddress > MaximumSupportMemAddress - (Length - 1))) { + return RETURN_UNSUPPORTED; + } + +// DEBUG ((DEBUG_ERROR, "ConvertMemoryPageAttributes(%x) - %016lx, %016lx, %02lx\n", IsSet, BaseAddress, Length, Attributes)); + + if (IsSplitted != NULL) { + *IsSplitted = FALSE; + } + if (IsModified != NULL) { + *IsModified = FALSE; + } + + // + // Below logic is to check 2M/4K page to make sure we do not waste memory. + // + while (Length != 0) { + PageEntry = GetPageTableEntry (BaseAddress, &PageAttribute); + if (PageEntry == NULL) { + return RETURN_UNSUPPORTED; + } + PageEntryLength = PageAttributeToLength (PageAttribute); + SplitAttribute = NeedSplitPage (BaseAddress, Length, PageEntry, PageAttribute); + if (SplitAttribute == PageNone) { + ConvertPageEntryAttribute (PageEntry, Attributes, IsSet, &IsEntryModified); + if (IsEntryModified) { + if (IsModified != NULL) { + *IsModified = TRUE; + } + } + // + // Convert success, move to next + // + BaseAddress += PageEntryLength; + Length -= PageEntryLength; + } else { + Status = SplitPage (PageEntry, PageAttribute, SplitAttribute); + if (RETURN_ERROR (Status)) { + return RETURN_UNSUPPORTED; + } + if (IsSplitted != NULL) { + *IsSplitted = TRUE; + } + if (IsModified != NULL) { + *IsModified = TRUE; + } + // + // Just split current page + // Convert success in next around + // + } + } + + return RETURN_SUCCESS; +} + +/** + FlushTlb on current processor. + + @param[in,out] Buffer Pointer to private data buffer. +**/ +VOID +EFIAPI +FlushTlbOnCurrentProcessor ( + IN OUT VOID *Buffer + ) +{ + CpuFlushTlb (); +} + +/** + FlushTlb for all processors. +**/ +VOID +FlushTlbForAll ( + VOID + ) +{ + UINTN Index; + + FlushTlbOnCurrentProcessor (NULL); + + for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + if (Index != gSmst->CurrentlyExecutingCpu) { + // Force to start up AP in blocking mode, + SmmBlockingStartupThisAp (FlushTlbOnCurrentProcessor, Index, NULL); + // Do not check return status, because AP might not be present in some corner cases. + } + } +} + +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ) +{ + EFI_STATUS Status; + BOOLEAN IsModified; + + Status = ConvertMemoryPageAttributes (BaseAddress, Length, Attributes, TRUE, IsSplitted, &IsModified); + if (!EFI_ERROR(Status)) { + if (IsModified) { + // + // Flush TLB as last step + // + FlushTlbForAll(); + } + } + + return Status; +} + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be cleared together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not supported for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ) +{ + EFI_STATUS Status; + BOOLEAN IsModified; + + Status = ConvertMemoryPageAttributes (BaseAddress, Length, Attributes, FALSE, IsSplitted, &IsModified); + if (!EFI_ERROR(Status)) { + if (IsModified) { + // + // Flush TLB as last step + // + FlushTlbForAll(); + } + } + + return Status; +} + +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not supported for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + return SmmSetMemoryAttributesEx (BaseAddress, Length, Attributes, NULL); +} + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be cleared together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not supported for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + return SmmClearMemoryAttributesEx (BaseAddress, Length, Attributes, NULL); +} + +/** + Set ShadowStack memory. + + @param[in] Cr3 The page table base address. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + + @retval EFI_SUCCESS The shadow stack memory is set. +**/ +EFI_STATUS +SetShadowStack ( + IN UINTN Cr3, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + EFI_STATUS Status; + + SetPageTableBase (Cr3); + + Status = SmmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO); + + SetPageTableBase (0); + + return Status; +} + +/** + Set not present memory. + + @param[in] Cr3 The page table base address. + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + + @retval EFI_SUCCESS The not present memory is set. +**/ +EFI_STATUS +SetNotPresentPage ( + IN UINTN Cr3, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + EFI_STATUS Status; + + SetPageTableBase (Cr3); + + Status = SmmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RP); + + SetPageTableBase (0); + + return Status; +} + +/** + 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 + ) +{ + UINTN Index; + + ASSERT (TableGuid != NULL); + ASSERT (Table != NULL); + + *Table = NULL; + for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) { + if (CompareGuid (TableGuid, &(gSmst->SmmConfigurationTable[Index].VendorGuid))) { + *Table = gSmst->SmmConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + This function sets SMM save state buffer to be RW and XP. +**/ +VOID +PatchSmmSaveStateMap ( + VOID + ) +{ + UINTN Index; + UINTN TileCodeSize; + UINTN TileDataSize; + UINTN TileSize; + + 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, "PatchSmmSaveStateMap:\n")); + for (Index = 0; Index < mMaxNumberOfCpus - 1; Index++) { + // + // Code + // + SmmSetMemoryAttributes ( + mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET, + TileCodeSize, + EFI_MEMORY_RO + ); + SmmClearMemoryAttributes ( + mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET, + TileCodeSize, + EFI_MEMORY_XP + ); + + // + // Data + // + SmmClearMemoryAttributes ( + mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize, + TileSize - TileCodeSize, + EFI_MEMORY_RO + ); + SmmSetMemoryAttributes ( + mCpuHotPlugData.SmBase[Index] + SMM_HANDLER_OFFSET + TileCodeSize, + TileSize - TileCodeSize, + EFI_MEMORY_XP + ); + } + + // + // Code + // + SmmSetMemoryAttributes ( + mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET, + TileCodeSize, + EFI_MEMORY_RO + ); + SmmClearMemoryAttributes ( + mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET, + TileCodeSize, + EFI_MEMORY_XP + ); + + // + // Data + // + SmmClearMemoryAttributes ( + mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + TileCodeSize, + SIZE_32KB - TileCodeSize, + EFI_MEMORY_RO + ); + SmmSetMemoryAttributes ( + mCpuHotPlugData.SmBase[mMaxNumberOfCpus - 1] + SMM_HANDLER_OFFSET + TileCodeSize, + SIZE_32KB - TileCodeSize, + EFI_MEMORY_XP + ); +} + +/** + This function sets GDT/IDT buffer to be RO and XP. +**/ +VOID +PatchGdtIdtMap ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN Size; + + // + // GDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - GDT:\n")); + + BaseAddress = mGdtBuffer; + Size = ALIGN_VALUE(mGdtBufferSize, SIZE_4KB); + // + // The range should have been set to RO + // if it is allocated with EfiRuntimeServicesCode. + // + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); + + // + // IDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - IDT:\n")); + + BaseAddress = gcSmiIdtr.Base; + Size = ALIGN_VALUE(gcSmiIdtr.Limit + 1, SIZE_4KB); + // + // The range should have been set to RO + // if it is allocated with EfiRuntimeServicesCode. + // + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); +} + +/** + This function sets memory attribute according to MemoryAttributesTable. +**/ +VOID +SetMemMapAttributes ( + VOID + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *MemoryMapStart; + UINTN MemoryMapEntryCount; + UINTN DescriptorSize; + UINTN Index; + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + + SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable); + if (MemoryAttributesTable == NULL) { + DEBUG ((DEBUG_INFO, "MemoryAttributesTable - NULL\n")); + return ; + } + + DEBUG ((DEBUG_INFO, "MemoryAttributesTable:\n")); + DEBUG ((DEBUG_INFO, " Version - 0x%08x\n", MemoryAttributesTable->Version)); + DEBUG ((DEBUG_INFO, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); + DEBUG ((DEBUG_INFO, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); + + MemoryMapEntryCount = MemoryAttributesTable->NumberOfEntries; + DescriptorSize = MemoryAttributesTable->DescriptorSize; + MemoryMapStart = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); + MemoryMap = MemoryMapStart; + for (Index = 0; Index < MemoryMapEntryCount; Index++) { + DEBUG ((DEBUG_INFO, "Entry (0x%x)\n", MemoryMap)); + DEBUG ((DEBUG_INFO, " Type - 0x%x\n", MemoryMap->Type)); + DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", MemoryMap->PhysicalStart)); + DEBUG ((DEBUG_INFO, " VirtualStart - 0x%016lx\n", MemoryMap->VirtualStart)); + DEBUG ((DEBUG_INFO, " NumberOfPages - 0x%016lx\n", MemoryMap->NumberOfPages)); + DEBUG ((DEBUG_INFO, " Attribute - 0x%016lx\n", MemoryMap->Attribute)); + MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); + } + + MemoryMap = MemoryMapStart; + for (Index = 0; Index < MemoryMapEntryCount; Index++) { + DEBUG ((DEBUG_VERBOSE, "SetAttribute: Memory Entry - 0x%lx, 0x%x\n", MemoryMap->PhysicalStart, MemoryMap->NumberOfPages)); + switch (MemoryMap->Type) { + case EfiRuntimeServicesCode: + SmmSetMemoryAttributes ( + MemoryMap->PhysicalStart, + EFI_PAGES_TO_SIZE((UINTN)MemoryMap->NumberOfPages), + EFI_MEMORY_RO + ); + break; + case EfiRuntimeServicesData: + SmmSetMemoryAttributes ( + MemoryMap->PhysicalStart, + EFI_PAGES_TO_SIZE((UINTN)MemoryMap->NumberOfPages), + EFI_MEMORY_XP + ); + break; + default: + SmmSetMemoryAttributes ( + MemoryMap->PhysicalStart, + EFI_PAGES_TO_SIZE((UINTN)MemoryMap->NumberOfPages), + EFI_MEMORY_XP + ); + break; + } + MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); + } + + PatchSmmSaveStateMap (); + PatchGdtIdtMap (); + + return ; +} + +/** + 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; + + DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n")); + + 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); + } + } + // + // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress(). + // +} + +/** + 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. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memory + region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmSetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + return SmmSetMemoryAttributes (BaseAddress, Length, Attributes); +} + +/** + This function clears given attributes of the memory region specified by + BaseAddress and Length. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to clear for the memory + region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be cleared together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmClearMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + return SmmClearMemoryAttributes (BaseAddress, Length, Attributes); +} + +/** + This function retrieves the attributes of the memory region specified by + BaseAddress and Length. If different attributes are got from different part + of the memory region, EFI_NO_MAPPING will be returned. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes Pointer to attributes returned. + + @retval EFI_SUCCESS The attributes got for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes is NULL. + @retval EFI_NO_MAPPING Attributes are not consistent cross the memory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmGetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + OUT UINT64 *Attributes + ) +{ + EFI_PHYSICAL_ADDRESS Address; + UINT64 *PageEntry; + UINT64 MemAttr; + PAGE_ATTRIBUTE PageAttr; + INT64 Size; + + if (Length < SIZE_4KB || Attributes == NULL) { + return EFI_INVALID_PARAMETER; + } + + Size = (INT64)Length; + MemAttr = (UINT64)-1; + + do { + + PageEntry = GetPageTableEntry (BaseAddress, &PageAttr); + if (PageEntry == NULL || PageAttr == PageNone) { + return EFI_UNSUPPORTED; + } + + // + // If the memory range is cross page table boundary, make sure they + // share the same attribute. Return EFI_NO_MAPPING if not. + // + *Attributes = GetAttributesFromPageEntry (PageEntry); + if (MemAttr != (UINT64)-1 && *Attributes != MemAttr) { + return EFI_NO_MAPPING; + } + + switch (PageAttr) { + case Page4K: + Address = *PageEntry & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64; + Size -= (SIZE_4KB - (BaseAddress - Address)); + BaseAddress += (SIZE_4KB - (BaseAddress - Address)); + break; + + case Page2M: + Address = *PageEntry & ~mAddressEncMask & PAGING_2M_ADDRESS_MASK_64; + Size -= SIZE_2MB - (BaseAddress - Address); + BaseAddress += SIZE_2MB - (BaseAddress - Address); + break; + + case Page1G: + Address = *PageEntry & ~mAddressEncMask & PAGING_1G_ADDRESS_MASK_64; + Size -= SIZE_1GB - (BaseAddress - Address); + BaseAddress += SIZE_1GB - (BaseAddress - Address); + break; + + default: + return EFI_UNSUPPORTED; + } + + MemAttr = *Attributes; + + } while (Size > 0); + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c new file mode 100644 index 000000000..9b2b191e0 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c @@ -0,0 +1,344 @@ +/** @file +SMM MP protocol implementation + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" +#include "SmmMp.h" + +/// +/// SMM MP Protocol instance +/// +EFI_MM_MP_PROTOCOL mSmmMp = { + EFI_MM_MP_PROTOCOL_REVISION, + 0, + SmmMpGetNumberOfProcessors, + SmmMpDispatchProcedure, + SmmMpBroadcastProcedure, + SmmMpSetStartupProcedure, + SmmMpCheckForProcedure, + SmmMpWaitForProcedure +}; + +/** + Service to retrieves the number of logical processor in the platform. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in the system, + including the BSP and all APs. + + @retval EFI_SUCCESS The number of processors was retrieved successfully + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL +**/ +EFI_STATUS +EFIAPI +SmmMpGetNumberOfProcessors ( + IN CONST EFI_MM_MP_PROTOCOL *This, + OUT UINTN *NumberOfProcessors + ) +{ + if (NumberOfProcessors == NULL) { + return EFI_INVALID_PARAMETER; + } + + *NumberOfProcessors = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + + return EFI_SUCCESS; +} + +/** + This service allows the caller to invoke a procedure one of the application processors (AP). This + function uses an optional token parameter to support blocking and non-blocking modes. If the token + is passed into the call, the function will operate in a non-blocking fashion and the caller can + check for completion with CheckOnProcedure or WaitForProcedure. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the procedure to be run on the designated target + AP of the system. Type EFI_AP_PROCEDURE2 is defined below in + related definitions. + @param[in] CpuNumber The zero-based index of the processor number of the target + AP, on which the code stream is supposed to run. If the number + points to the calling processor then it will not run the + supplied code. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for this AP to + finish execution of Procedure, either for blocking or + non-blocking mode. Zero means infinity. If the timeout + expires before this AP returns from Procedure, then Procedure + on the AP is terminated. If the timeout expires in blocking + mode, the call returns EFI_TIMEOUT. If the timeout expires + in non-blocking mode, the timeout determined can be through + CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an + implementation supports this feature, can be determined via + the Attributes data member. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code + that is run by the AP. It is an optional common mailbox + between APs and the caller to share information. + @param[in,out] Token This is parameter is broken into two components: + 1.Token->Completion is an optional parameter that allows the + caller to execute the procedure in a blocking or non-blocking + fashion. If it is NULL the call is blocking, and the call will + not return until the AP has completed the procedure. If the + token is not NULL, the call will return immediately. The caller + can check whether the procedure has completed with + CheckOnProcedure or WaitForProcedure. + 2.Token->Status The implementation updates the address pointed + at by this variable with the status code returned by Procedure + when it completes execution on the target AP, or with EFI_TIMEOUT + if the Procedure fails to complete within the optional timeout. + The implementation will update this variable with EFI_NOT_READY + prior to starting Procedure on the target AP + @param[in,out] CPUStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + @retval EFI_SUCCESS In the blocking case, this indicates that Procedure has completed + execution on the target AP. + In the non-blocking case this indicates that the procedure has + been successfully scheduled for execution on the target AP. + @retval EFI_INVALID_PARAMETER The input arguments are out of range. Either the target AP is the + caller of the function, or the Procedure or Token is NULL + @retval EFI_NOT_READY If the target AP is busy executing another procedure + @retval EFI_ALREADY_STARTED Token is already in use for another procedure + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the specified AP + has finished + @retval EFI_OUT_OF_RESOURCES Could not allocate a required resource. + +**/ +EFI_STATUS +EFIAPI +SmmMpDispatchProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN CpuNumber, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ) +{ + return InternalSmmStartupThisAp ( + Procedure, + CpuNumber, + ProcedureArguments, + Token, + TimeoutInMicroseconds, + CPUStatus + ); +} + +/** + This service allows the caller to invoke a procedure on all running application processors (AP) + except the caller. This function uses an optional token parameter to support blocking and + nonblocking modes. If the token is passed into the call, the function will operate in a non-blocking + fashion and the caller can check for completion with CheckOnProcedure or WaitForProcedure. + + It is not necessary for the implementation to run the procedure on every processor on the platform. + Processors that are powered down in such a way that they cannot respond to interrupts, may be + excluded from the broadcast. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the code stream to be run on the APs that have + entered MM. Type EFI_AP_PROCEDURE is defined below in related + definitions. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish + execution of Procedure, either for blocking or non-blocking mode. + Zero means infinity. If the timeout expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. If + the timeout expires in blocking mode, the call returns EFI_TIMEOUT. + If the timeout expires in non-blocking mode, the timeout determined + can be through CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an implementation + supports this feature can be determined via the Attributes data + member. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code + that is run by the AP. It is an optional common mailbox + between APs and the caller to share information. + @param[in,out] Token This is parameter is broken into two components: + 1.Token->Completion is an optional parameter that allows the + caller to execute the procedure in a blocking or non-blocking + fashion. If it is NULL the call is blocking, and the call will + not return until the AP has completed the procedure. If the + token is not NULL, the call will return immediately. The caller + can check whether the procedure has completed with + CheckOnProcedure or WaitForProcedure. + 2.Token->Status The implementation updates the address pointed + at by this variable with the status code returned by Procedure + when it completes execution on the target AP, or with EFI_TIMEOUT + if the Procedure fails to complete within the optional timeout. + The implementation will update this variable with EFI_NOT_READY + prior to starting Procedure on the target AP + @param[in,out] CPUStatus This optional pointer may be used to get the individual status + returned by every AP that participated in the broadcast. This + parameter if used provides the base address of an array to hold + the EFI_STATUS value of each AP in the system. The size of the + array can be ascertained by the GetNumberOfProcessors function. + As mentioned above, the broadcast may not include every processor + in the system. Some implementations may exclude processors that + have been powered down in such a way that they are not responsive + to interrupts. Additionally the broadcast excludes the processor + which is making the BroadcastProcedure call. For every excluded + processor, the array entry must contain a value of EFI_NOT_STARTED + + @retval EFI_SUCCESS In the blocking case, this indicates that Procedure has completed + execution on the APs. + In the non-blocking case this indicates that the procedure has + been successfully scheduled for execution on the APs. + @retval EFI_INVALID_PARAMETER The Procedure or Token is NULL + @retval EFI_NOT_READY If the target AP is busy executing another procedure + @retval EFI_ALREADY_STARTED Token is already in use for another procedure + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the specified AP + has finished. + @retval EFI_OUT_OF_RESOURCES Could not allocate a required resource. + +**/ +EFI_STATUS +EFIAPI +SmmMpBroadcastProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ) +{ + return InternalSmmStartupAllAPs( + Procedure, + TimeoutInMicroseconds, + ProcedureArguments, + Token, + CPUStatus + ); +} + +/** + This service allows the caller to set a startup procedure that will be executed when an AP powers + up from a state where core configuration and context is lost. The procedure is execution has the + following properties: + 1. The procedure executes before the processor is handed over to the operating system. + 2. All processors execute the same startup procedure. + 3. The procedure may run in parallel with other procedures invoked through the functions in this + protocol, or with processors that are executing an MM handler or running in the operating system. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the code stream to be run on the designated target AP + of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2 + with the related definitions of + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs. + If caller may pass a value of NULL to deregister any existing + startup procedure. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is + run by the AP. It is an optional common mailbox between APs and + the caller to share information + + @retval EFI_SUCCESS The Procedure has been set successfully. + @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL. + +**/ +EFI_STATUS +EFIAPI +SmmMpSetStartupProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN OUT VOID *ProcedureArguments OPTIONAL + ) +{ + return RegisterStartupProcedure (Procedure, ProcedureArguments); +} + +/** + When non-blocking execution of a procedure on an AP is invoked with DispatchProcedure, + via the use of a token, this function can be used to check for completion of the procedure on the AP. + The function takes the token that was passed into the DispatchProcedure call. If the procedure + is complete, and therefore it is now possible to run another procedure on the same AP, this function + returns EFI_SUCESS. In this case the status returned by the procedure that executed on the AP is + returned in the token's Status field. If the procedure has not yet completed, then this function + returns EFI_NOT_READY. + + When a non-blocking execution of a procedure is invoked with BroadcastProcedure, via the + use of a token, this function can be used to check for completion of the procedure on all the + broadcast APs. The function takes the token that was passed into the BroadcastProcedure + call. If the procedure is complete on all broadcast APs this function returns EFI_SUCESS. In this + case the Status field in the token passed into the function reflects the overall result of the + invocation, which may be EFI_SUCCESS, if all executions succeeded, or the first observed failure. + If the procedure has not yet completed on the broadcast APs, the function returns + EFI_NOT_READY. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Token This parameter describes the token that was passed into + DispatchProcedure or BroadcastProcedure. + + @retval EFI_SUCCESS Procedure has completed. + @retval EFI_NOT_READY The Procedure has not completed. + @retval EFI_INVALID_PARAMETER Token or Token->Completion is NULL + @retval EFI_NOT_FOUND Token is not currently in use for a non-blocking call + +**/ +EFI_STATUS +EFIAPI +SmmMpCheckForProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN MM_COMPLETION Token + ) +{ + if (Token == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!IsTokenInUse ((SPIN_LOCK *)Token)) { + return EFI_NOT_FOUND; + } + + return IsApReady ((SPIN_LOCK *)Token); +} + +/** + When a non-blocking execution of a procedure on an AP is invoked via DispatchProcedure, + this function will block the caller until the remote procedure has completed on the designated AP. + The non-blocking procedure invocation is identified by the Token parameter, which must match the + token that used when DispatchProcedure was called. Upon completion the status returned by + the procedure that executed on the AP is used to update the token's Status field. + + When a non-blocking execution of a procedure on an AP is invoked via BroadcastProcedure + this function will block the caller until the remote procedure has completed on all of the APs that + entered MM. The non-blocking procedure invocation is identified by the Token parameter, which + must match the token that used when BroadcastProcedure was called. Upon completion the + overall status returned by the procedures that executed on the broadcast AP is used to update the + token's Status field. The overall status may be EFI_SUCCESS, if all executions succeeded, or the + first observed failure. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Token This parameter describes the token that was passed into + DispatchProcedure or BroadcastProcedure. + + @retval EFI_SUCCESS Procedure has completed. + @retval EFI_INVALID_PARAMETER Token or Token->Completion is NULL + @retval EFI_NOT_FOUND Token is not currently in use for a non-blocking call + +**/ +EFI_STATUS +EFIAPI +SmmMpWaitForProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN MM_COMPLETION Token + ) +{ + EFI_STATUS Status; + + do { + Status = SmmMpCheckForProcedure (This, Token); + } while (Status == EFI_NOT_READY); + + return Status; +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.h new file mode 100644 index 000000000..b95ed8c6f --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.h @@ -0,0 +1,285 @@ +/** @file +Include file for SMM MP protocol implementation. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_MP_PROTOCOL_H_ +#define _SMM_MP_PROTOCOL_H_ + +// +// SMM MP Protocol function prototypes. +// + +/** + Service to retrieves the number of logical processor in the platform. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[out] NumberOfProcessors Pointer to the total number of logical processors in the system, + including the BSP and all APs. + + @retval EFI_SUCCESS The number of processors was retrieved successfully + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL +**/ +EFI_STATUS +EFIAPI +SmmMpGetNumberOfProcessors ( + IN CONST EFI_MM_MP_PROTOCOL *This, + OUT UINTN *NumberOfProcessors + ); + + +/** + This service allows the caller to invoke a procedure one of the application processors (AP). This + function uses an optional token parameter to support blocking and non-blocking modes. If the token + is passed into the call, the function will operate in a non-blocking fashion and the caller can + check for completion with CheckOnProcedure or WaitForProcedure. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the procedure to be run on the designated target + AP of the system. Type EFI_AP_PROCEDURE2 is defined below in + related definitions. + @param[in] CpuNumber The zero-based index of the processor number of the target + AP, on which the code stream is supposed to run. If the number + points to the calling processor then it will not run the + supplied code. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for this AP to + finish execution of Procedure, either for blocking or + non-blocking mode. Zero means infinity. If the timeout + expires before this AP returns from Procedure, then Procedure + on the AP is terminated. If the timeout expires in blocking + mode, the call returns EFI_TIMEOUT. If the timeout expires + in non-blocking mode, the timeout determined can be through + CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an + implementation supports this feature, can be determined via + the Attributes data member. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code + that is run by the AP. It is an optional common mailbox + between APs and the caller to share information. + @param[in,out] Token This is parameter is broken into two components: + 1.Token->Completion is an optional parameter that allows the + caller to execute the procedure in a blocking or non-blocking + fashion. If it is NULL the call is blocking, and the call will + not return until the AP has completed the procedure. If the + token is not NULL, the call will return immediately. The caller + can check whether the procedure has completed with + CheckOnProcedure or WaitForProcedure. + 2.Token->Status The implementation updates the address pointed + at by this variable with the status code returned by Procedure + when it completes execution on the target AP, or with EFI_TIMEOUT + if the Procedure fails to complete within the optional timeout. + The implementation will update this variable with EFI_NOT_READY + prior to starting Procedure on the target AP + @param[in,out] CPUStatus This optional pointer may be used to get the status code returned + by Procedure when it completes execution on the target AP, or with + EFI_TIMEOUT if the Procedure fails to complete within the optional + timeout. The implementation will update this variable with + EFI_NOT_READY prior to starting Procedure on the target AP. + + @retval EFI_SUCCESS In the blocking case, this indicates that Procedure has completed + execution on the target AP. + In the non-blocking case this indicates that the procedure has + been successfully scheduled for execution on the target AP. + @retval EFI_INVALID_PARAMETER The input arguments are out of range. Either the target AP is the + caller of the function, or the Procedure or Token is NULL + @retval EFI_NOT_READY If the target AP is busy executing another procedure + @retval EFI_ALREADY_STARTED Token is already in use for another procedure + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the specified AP + has finished + @retval EFI_OUT_OF_RESOURCES Could not allocate a required resource. + +**/ +EFI_STATUS +EFIAPI +SmmMpDispatchProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN CpuNumber, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ); + +/** + This service allows the caller to invoke a procedure on all running application processors (AP) + except the caller. This function uses an optional token parameter to support blocking and + nonblocking modes. If the token is passed into the call, the function will operate in a non-blocking + fashion and the caller can check for completion with CheckOnProcedure or WaitForProcedure. + + It is not necessary for the implementation to run the procedure on every processor on the platform. + Processors that are powered down in such a way that they cannot respond to interrupts, may be + excluded from the broadcast. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the code stream to be run on the APs that have + entered MM. Type EFI_AP_PROCEDURE is defined below in related + definitions. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish + execution of Procedure, either for blocking or non-blocking mode. + Zero means infinity. If the timeout expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. If + the timeout expires in blocking mode, the call returns EFI_TIMEOUT. + If the timeout expires in non-blocking mode, the timeout determined + can be through CheckOnProcedure or WaitForProcedure. + Note that timeout support is optional. Whether an implementation + supports this feature can be determined via the Attributes data + member. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code + that is run by the AP. It is an optional common mailbox + between APs and the caller to share information. + @param[in,out] Token This is parameter is broken into two components: + 1.Token->Completion is an optional parameter that allows the + caller to execute the procedure in a blocking or non-blocking + fashion. If it is NULL the call is blocking, and the call will + not return until the AP has completed the procedure. If the + token is not NULL, the call will return immediately. The caller + can check whether the procedure has completed with + CheckOnProcedure or WaitForProcedure. + 2.Token->Status The implementation updates the address pointed + at by this variable with the status code returned by Procedure + when it completes execution on the target AP, or with EFI_TIMEOUT + if the Procedure fails to complete within the optional timeout. + The implementation will update this variable with EFI_NOT_READY + prior to starting Procedure on the target AP + @param[in,out] CPUStatus This optional pointer may be used to get the individual status + returned by every AP that participated in the broadcast. This + parameter if used provides the base address of an array to hold + the EFI_STATUS value of each AP in the system. The size of the + array can be ascertained by the GetNumberOfProcessors function. + As mentioned above, the broadcast may not include every processor + in the system. Some implementations may exclude processors that + have been powered down in such a way that they are not responsive + to interrupts. Additionally the broadcast excludes the processor + which is making the BroadcastProcedure call. For every excluded + processor, the array entry must contain a value of EFI_NOT_STARTED + + @retval EFI_SUCCESS In the blocking case, this indicates that Procedure has completed + execution on the APs. + In the non-blocking case this indicates that the procedure has + been successfully scheduled for execution on the APs. + @retval EFI_INVALID_PARAMETER The Procedure or Token is NULL + @retval EFI_NOT_READY If the target AP is busy executing another procedure + @retval EFI_ALREADY_STARTED Token is already in use for another procedure + @retval EFI_TIMEOUT In blocking mode, the timeout expired before the specified AP + has finished + @retval EFI_OUT_OF_RESOURCES Could not allocate a required resource. + +**/ +EFI_STATUS +EFIAPI +SmmMpBroadcastProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE2 Procedure, + IN UINTN TimeoutInMicroseconds, + IN OUT VOID *ProcedureArguments OPTIONAL, + IN OUT MM_COMPLETION *Token, + IN OUT EFI_STATUS *CPUStatus + ); + + +/** + This service allows the caller to set a startup procedure that will be executed when an AP powers + up from a state where core configuration and context is lost. The procedure is execution has the + following properties: + 1. The procedure executes before the processor is handed over to the operating system. + 2. All processors execute the same startup procedure. + 3. The procedure may run in parallel with other procedures invoked through the functions in this + protocol, or with processors that are executing an MM handler or running in the operating system. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Procedure A pointer to the code stream to be run on the designated target AP + of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2 + with the related definitions of + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs. + If caller may pass a value of NULL to deregister any existing + startup procedure. + @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is + run by the AP. It is an optional common mailbox between APs and + the caller to share information + + @retval EFI_SUCCESS The Procedure has been set successfully. + @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL. +**/ +EFI_STATUS +EFIAPI +SmmMpSetStartupProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN OUT VOID *ProcedureArguments OPTIONAL + ); + +/** + When non-blocking execution of a procedure on an AP is invoked with DispatchProcedure, + via the use of a token, this function can be used to check for completion of the procedure on the AP. + The function takes the token that was passed into the DispatchProcedure call. If the procedure + is complete, and therefore it is now possible to run another procedure on the same AP, this function + returns EFI_SUCESS. In this case the status returned by the procedure that executed on the AP is + returned in the token's Status field. If the procedure has not yet completed, then this function + returns EFI_NOT_READY. + + When a non-blocking execution of a procedure is invoked with BroadcastProcedure, via the + use of a token, this function can be used to check for completion of the procedure on all the + broadcast APs. The function takes the token that was passed into the BroadcastProcedure + call. If the procedure is complete on all broadcast APs this function returns EFI_SUCESS. In this + case the Status field in the token passed into the function reflects the overall result of the + invocation, which may be EFI_SUCCESS, if all executions succeeded, or the first observed failure. + If the procedure has not yet completed on the broadcast APs, the function returns + EFI_NOT_READY. + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Token This parameter describes the token that was passed into + DispatchProcedure or BroadcastProcedure. + + @retval EFI_SUCCESS Procedure has completed. + @retval EFI_NOT_READY The Procedure has not completed. + @retval EFI_INVALID_PARAMETER Token or Token->Completion is NULL + @retval EFI_NOT_FOUND Token is not currently in use for a non-blocking call + +**/ +EFI_STATUS +EFIAPI +SmmMpCheckForProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN MM_COMPLETION Token + ); + +/** + When a non-blocking execution of a procedure on an AP is invoked via DispatchProcedure, + this function will block the caller until the remote procedure has completed on the designated AP. + The non-blocking procedure invocation is identified by the Token parameter, which must match the + token that used when DispatchProcedure was called. Upon completion the status returned by + the procedure that executed on the AP is used to update the token's Status field. + + When a non-blocking execution of a procedure on an AP is invoked via BroadcastProcedure + this function will block the caller until the remote procedure has completed on all of the APs that + entered MM. The non-blocking procedure invocation is identified by the Token parameter, which + must match the token that used when BroadcastProcedure was called. Upon completion the + overall status returned by the procedures that executed on the broadcast AP is used to update the + token's Status field. The overall status may be EFI_SUCCESS, if all executions succeeded, or the + first observed failure. + + + @param[in] This The EFI_MM_MP_PROTOCOL instance. + @param[in] Token This parameter describes the token that was passed into + DispatchProcedure or BroadcastProcedure. + + @retval EFI_SUCCESS Procedure has completed. + @retval EFI_INVALID_PARAMETER Token or Token->Completion is NULL + @retval EFI_NOT_FOUND Token is not currently in use for a non-blocking call + +**/ +EFI_STATUS +EFIAPI +SmmMpWaitForProcedure ( + IN CONST EFI_MM_MP_PROTOCOL *This, + IN MM_COMPLETION Token + ); + +#endif diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c new file mode 100644 index 000000000..c47b5573e --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -0,0 +1,1510 @@ +/** @file +Enable SMM profile. + +Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" +#include "SmmProfileInternal.h" + +UINT32 mSmmProfileCr3; + +SMM_PROFILE_HEADER *mSmmProfileBase; +MSR_DS_AREA_STRUCT *mMsrDsAreaBase; +// +// The buffer to store SMM profile data. +// +UINTN mSmmProfileSize; + +// +// The buffer to enable branch trace store. +// +UINTN mMsrDsAreaSize = SMM_PROFILE_DTS_SIZE; + +// +// The flag indicates if execute-disable is supported by processor. +// +BOOLEAN mXdSupported = TRUE; + +// +// The flag indicates if execute-disable is enabled on processor. +// +BOOLEAN mXdEnabled = FALSE; + +// +// The flag indicates if BTS is supported by processor. +// +BOOLEAN mBtsSupported = TRUE; + +// +// The flag indicates if SMM profile starts to record data. +// +BOOLEAN mSmmProfileStart = FALSE; + +// +// The flag indicates if #DB will be setup in #PF handler. +// +BOOLEAN mSetupDebugTrap = FALSE; + +// +// Record the page fault exception count for one instruction execution. +// +UINTN *mPFEntryCount; + +UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT]; +UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; + +MSR_DS_AREA_STRUCT **mMsrDsArea; +BRANCH_TRACE_RECORD **mMsrBTSRecord; +UINTN mBTSRecordNumber; +PEBS_RECORD **mMsrPEBSRecord; + +// +// These memory ranges are always present, they does not generate the access type of page fault exception, +// but they possibly generate instruction fetch type of page fault exception. +// +MEMORY_PROTECTION_RANGE *mProtectionMemRange = NULL; +UINTN mProtectionMemRangeCount = 0; + +// +// Some predefined memory ranges. +// +MEMORY_PROTECTION_RANGE mProtectionMemRangeTemplate[] = { + // + // SMRAM range (to be fixed in runtime). + // It is always present and instruction fetches are allowed. + // + {{0x00000000, 0x00000000},TRUE,FALSE}, + + // + // SMM profile data range( to be fixed in runtime). + // It is always present and instruction fetches are not allowed. + // + {{0x00000000, 0x00000000},TRUE,TRUE}, + + // + // SMRAM ranges not covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz (to be fixed in runtime). + // It is always present and instruction fetches are allowed. + // {{0x00000000, 0x00000000},TRUE,FALSE}, + // + + // + // Future extended range could be added here. + // + + // + // PCI MMIO ranges (to be added in runtime). + // They are always present and instruction fetches are not allowed. + // +}; + +// +// These memory ranges are mapped by 4KB-page instead of 2MB-page. +// +MEMORY_RANGE *mSplitMemRange = NULL; +UINTN mSplitMemRangeCount = 0; + +// +// SMI command port. +// +UINT32 mSmiCommandPort; + +/** + Disable branch trace store. + +**/ +VOID +DisableBTS ( + VOID + ) +{ + AsmMsrAnd64 (MSR_DEBUG_CTL, ~((UINT64)(MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR))); +} + +/** + Enable branch trace store. + +**/ +VOID +EnableBTS ( + VOID + ) +{ + AsmMsrOr64 (MSR_DEBUG_CTL, (MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR)); +} + +/** + Get CPU Index from APIC ID. + +**/ +UINTN +GetCpuIndex ( + VOID + ) +{ + UINTN Index; + UINT32 ApicId; + + ApicId = GetApicId (); + + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { + if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) { + return Index; + } + } + ASSERT (FALSE); + return 0; +} + +/** + Get the source of IP after execute-disable exception is triggered. + + @param CpuIndex The index of CPU. + @param DestinationIP The destination address. + +**/ +UINT64 +GetSourceFromDestinationOnBts ( + UINTN CpuIndex, + UINT64 DestinationIP + ) +{ + BRANCH_TRACE_RECORD *CurrentBTSRecord; + UINTN Index; + BOOLEAN FirstMatch; + + FirstMatch = FALSE; + + CurrentBTSRecord = (BRANCH_TRACE_RECORD *)mMsrDsArea[CpuIndex]->BTSIndex; + for (Index = 0; Index < mBTSRecordNumber; Index++) { + if ((UINTN)CurrentBTSRecord < (UINTN)mMsrBTSRecord[CpuIndex]) { + // + // Underflow + // + CurrentBTSRecord = (BRANCH_TRACE_RECORD *)((UINTN)mMsrDsArea[CpuIndex]->BTSAbsoluteMaximum - 1); + CurrentBTSRecord --; + } + if (CurrentBTSRecord->LastBranchTo == DestinationIP) { + // + // Good! find 1st one, then find 2nd one. + // + if (!FirstMatch) { + // + // The first one is DEBUG exception + // + FirstMatch = TRUE; + } else { + // + // Good find proper one. + // + return CurrentBTSRecord->LastBranchFrom; + } + } + CurrentBTSRecord--; + } + + return 0; +} + +/** + SMM profile specific INT 1 (single-step) exception handler. + + @param InterruptType Defines the type of interrupt or exception that + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. +**/ +VOID +EFIAPI +DebugExceptionHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINTN CpuIndex; + UINTN PFEntry; + + if (!mSmmProfileStart && + !HEAP_GUARD_NONSTOP_MODE && + !NULL_DETECTION_NONSTOP_MODE) { + return; + } + CpuIndex = GetCpuIndex (); + + // + // Clear last PF entries + // + for (PFEntry = 0; PFEntry < mPFEntryCount[CpuIndex]; PFEntry++) { + *mLastPFEntryPointer[CpuIndex][PFEntry] = mLastPFEntryValue[CpuIndex][PFEntry]; + } + + // + // Reset page fault exception count for next page fault. + // + mPFEntryCount[CpuIndex] = 0; + + // + // Flush TLB + // + CpuFlushTlb (); + + // + // Clear TF in EFLAGS + // + ClearTrapFlag (SystemContext); +} + +/** + Check if the input address is in SMM ranges. + + @param[in] Address The input address. + + @retval TRUE The input address is in SMM. + @retval FALSE The input address is not in SMM. +**/ +BOOLEAN +IsInSmmRanges ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + UINTN Index; + + if ((Address >= mCpuHotPlugData.SmrrBase) && (Address < mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) { + return TRUE; + } + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + if (Address >= mSmmCpuSmramRanges[Index].CpuStart && + Address < mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) { + return TRUE; + } + } + return FALSE; +} + +/** + Check if the memory address will be mapped by 4KB-page. + + @param Address The address of Memory. + @param Nx The flag indicates if the memory is execute-disable. + +**/ +BOOLEAN +IsAddressValid ( + IN EFI_PHYSICAL_ADDRESS Address, + IN 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; + } + return TRUE; + } +} + +/** + Check if the memory address will be mapped by 4KB-page. + + @param Address The address of Memory. + +**/ +BOOLEAN +IsAddressSplit ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + UINTN Index; + + if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // Check configuration + // + for (Index = 0; Index < mSplitMemRangeCount; Index++) { + if ((Address >= mSplitMemRange[Index].Base) && (Address < mSplitMemRange[Index].Top)) { + return TRUE; + } + } + } else { + if (Address < mCpuHotPlugData.SmrrBase) { + if ((mCpuHotPlugData.SmrrBase - Address) < BASE_2MB) { + return TRUE; + } + } else if (Address > (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize - BASE_2MB)) { + if ((Address - (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize - BASE_2MB)) < BASE_2MB) { + return TRUE; + } + } + } + // + // Return default + // + return FALSE; +} + +/** + Initialize the protected memory ranges and the 4KB-page mapped memory ranges. + +**/ +VOID +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; + + NumberOfDescriptors = 0; + NumberOfAddedDescriptors = mSmmCpuSmramRangeCount; + NumberOfSpliteRange = 0; + MemorySpaceMap = NULL; + + // + // Get MMIO ranges from GCD and add them into protected memory ranges. + // + gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemorySpaceMap + ); + for (Index = 0; Index < NumberOfDescriptors; Index++) { + if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { + NumberOfAddedDescriptors++; + } + } + + 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); + + // + // Copy existing ranges. + // + CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate)); + + // + // 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; + } + 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 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 = MemorySpaceMap[Index].BaseAddress; + mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length; + mProtectionMemRange[NumberOfProtectRange].Present = TRUE; + mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; + NumberOfProtectRange++; + } + + // + // 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. + // + ProtectBaseAddress = mProtectionMemRange[Index].Range.Base; + ProtectEndAddress = mProtectionMemRange[Index].Range.Top; + if (((ProtectBaseAddress & (SIZE_2MB - 1)) != 0) || ((ProtectEndAddress & (SIZE_2MB - 1)) != 0)) { + // + // Check if it is possible to create 4KB-page for not 2MB-aligned range and to create 2MB-page for 2MB-aligned range. + // A mix of 4KB and 2MB page could save SMRAM space. + // + Top2MBAlignedAddress = ProtectEndAddress & ~(SIZE_2MB - 1); + Base2MBAlignedAddress = (ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1); + if ((Top2MBAlignedAddress > Base2MBAlignedAddress) && + ((Top2MBAlignedAddress - Base2MBAlignedAddress) >= SIZE_2MB)) { + // + // There is an range which could be mapped by 2MB-page. + // + High4KBPageSize = ((ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1)) - (ProtectEndAddress & ~(SIZE_2MB - 1)); + Low4KBPageSize = ((ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1)) - (ProtectBaseAddress & ~(SIZE_2MB - 1)); + if (High4KBPageSize != 0) { + // + // Add not 2MB-aligned range to be mapped by 4KB-page. + // + mSplitMemRange[NumberOfSpliteRange].Base = ProtectEndAddress & ~(SIZE_2MB - 1); + mSplitMemRange[NumberOfSpliteRange].Top = (ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1); + NumberOfSpliteRange++; + } + if (Low4KBPageSize != 0) { + // + // Add not 2MB-aligned range to be mapped by 4KB-page. + // + mSplitMemRange[NumberOfSpliteRange].Base = ProtectBaseAddress & ~(SIZE_2MB - 1); + mSplitMemRange[NumberOfSpliteRange].Top = (ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1); + NumberOfSpliteRange++; + } + } else { + // + // The range could only be mapped by 4KB-page. + // + mSplitMemRange[NumberOfSpliteRange].Base = ProtectBaseAddress & ~(SIZE_2MB - 1); + mSplitMemRange[NumberOfSpliteRange].Top = (ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1); + NumberOfSpliteRange++; + } + } + } + + mSplitMemRangeCount = NumberOfSpliteRange; + + DEBUG ((EFI_D_INFO, "SMM Profile Memory Ranges:\n")); + for (Index = 0; Index < mProtectionMemRangeCount; Index++) { + DEBUG ((EFI_D_INFO, "mProtectionMemRange[%d].Base = %lx\n", Index, mProtectionMemRange[Index].Range.Base)); + DEBUG ((EFI_D_INFO, "mProtectionMemRange[%d].Top = %lx\n", Index, mProtectionMemRange[Index].Range.Top)); + } + for (Index = 0; Index < mSplitMemRangeCount; Index++) { + DEBUG ((EFI_D_INFO, "mSplitMemRange[%d].Base = %lx\n", Index, mSplitMemRange[Index].Base)); + DEBUG ((EFI_D_INFO, "mSplitMemRange[%d].Top = %lx\n", Index, mSplitMemRange[Index].Top)); + } +} + +/** + Update page table according to protected memory ranges and the 4KB-page mapped memory ranges. + +**/ +VOID +InitPaging ( + VOID + ) +{ + UINT64 Pml5Entry; + UINT64 Pml4Entry; + UINT64 *Pml5; + UINT64 *Pml4; + UINT64 *Pdpt; + UINT64 *Pd; + UINT64 *Pt; + UINTN Address; + UINTN Pml5Index; + UINTN Pml4Index; + UINTN PdptIndex; + UINTN PdIndex; + UINTN PtIndex; + UINTN NumberOfPdptEntries; + UINTN NumberOfPml4Entries; + UINTN NumberOfPml5Entries; + UINTN SizeOfMemorySpace; + BOOLEAN Nx; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + + if (sizeof (UINTN) == sizeof (UINT64)) { + if (!Enable5LevelPaging) { + Pml5Entry = (UINTN) mSmmProfileCr3 | IA32_PG_P; + Pml5 = &Pml5Entry; + } else { + Pml5 = (UINT64*) (UINTN) mSmmProfileCr3; + } + SizeOfMemorySpace = HighBitSet64 (gPhyMask) + 1; + // + // Calculate the table entries of PML4E and PDPTE. + // + NumberOfPml5Entries = 1; + if (SizeOfMemorySpace > 48) { + NumberOfPml5Entries = (UINTN) LShiftU64 (1, SizeOfMemorySpace - 48); + SizeOfMemorySpace = 48; + } + + NumberOfPml4Entries = 1; + if (SizeOfMemorySpace > 39) { + NumberOfPml4Entries = (UINTN) LShiftU64 (1, SizeOfMemorySpace - 39); + SizeOfMemorySpace = 39; + } + + NumberOfPdptEntries = 1; + ASSERT (SizeOfMemorySpace > 30); + NumberOfPdptEntries = (UINTN) LShiftU64 (1, SizeOfMemorySpace - 30); + } else { + Pml4Entry = (UINTN) mSmmProfileCr3 | IA32_PG_P; + Pml4 = &Pml4Entry; + Pml5Entry = (UINTN) Pml4 | IA32_PG_P; + Pml5 = &Pml5Entry; + NumberOfPml5Entries = 1; + NumberOfPml4Entries = 1; + NumberOfPdptEntries = 4; + } + + // + // Go through page table and change 2MB-page into 4KB-page. + // + for (Pml5Index = 0; Pml5Index < NumberOfPml5Entries; Pml5Index++) { + if ((Pml5[Pml5Index] & IA32_PG_P) == 0) { + // + // If PML5 entry does not exist, skip it + // + continue; + } + Pml4 = (UINT64 *) (UINTN) (Pml5[Pml5Index] & PHYSICAL_ADDRESS_MASK); + for (Pml4Index = 0; Pml4Index < NumberOfPml4Entries; Pml4Index++) { + if ((Pml4[Pml4Index] & IA32_PG_P) == 0) { + // + // If PML4 entry does not exist, skip it + // + continue; + } + Pdpt = (UINT64 *)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + for (PdptIndex = 0; PdptIndex < NumberOfPdptEntries; PdptIndex++, Pdpt++) { + if ((*Pdpt & IA32_PG_P) == 0) { + // + // If PDPT entry does not exist, skip it + // + continue; + } + if ((*Pdpt & IA32_PG_PS) != 0) { + // + // This is 1G entry, skip it + // + continue; + } + Pd = (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + if (Pd == 0) { + continue; + } + for (PdIndex = 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdIndex++, Pd++) { + if ((*Pd & IA32_PG_P) == 0) { + // + // If PD entry does not exist, skip it + // + continue; + } + Address = (UINTN) LShiftU64 ( + LShiftU64 ( + LShiftU64 ((Pml5Index << 9) + Pml4Index, 9) + PdptIndex, + 9 + ) + PdIndex, + 21 + ); + + // + // If it is 2M page, check IsAddressSplit() + // + if (((*Pd & IA32_PG_PS) != 0) && IsAddressSplit (Address)) { + // + // Based on current page table, create 4KB page table for split area. + // + ASSERT (Address == (*Pd & PHYSICAL_ADDRESS_MASK)); + + Pt = AllocatePageTableMemory (1); + ASSERT (Pt != NULL); + + // Split it + for (PtIndex = 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtIndex++) { + Pt[PtIndex] = Address + ((PtIndex << 12) | mAddressEncMask | PAGE_ATTRIBUTE_BITS); + } // end for PT + *Pd = (UINT64)(UINTN)Pt | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } // end if IsAddressSplit + } // end for PD + } // end for PDPT + } // end for PML4 + } // end for PML5 + + // + // Go through page table and set several page table entries to absent or execute-disable. + // + DEBUG ((EFI_D_INFO, "Patch page table start ...\n")); + for (Pml5Index = 0; Pml5Index < NumberOfPml5Entries; Pml5Index++) { + if ((Pml5[Pml5Index] & IA32_PG_P) == 0) { + // + // If PML5 entry does not exist, skip it + // + continue; + } + Pml4 = (UINT64 *) (UINTN) (Pml5[Pml5Index] & PHYSICAL_ADDRESS_MASK); + for (Pml4Index = 0; Pml4Index < NumberOfPml4Entries; Pml4Index++) { + if ((Pml4[Pml4Index] & IA32_PG_P) == 0) { + // + // If PML4 entry does not exist, skip it + // + continue; + } + Pdpt = (UINT64 *)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + for (PdptIndex = 0; PdptIndex < NumberOfPdptEntries; PdptIndex++, Pdpt++) { + if ((*Pdpt & IA32_PG_P) == 0) { + // + // If PDPT entry does not exist, skip it + // + continue; + } + if ((*Pdpt & IA32_PG_PS) != 0) { + // + // This is 1G entry, set NX bit and skip it + // + if (mXdSupported) { + *Pdpt = *Pdpt | IA32_PG_NX; + } + continue; + } + Pd = (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + if (Pd == 0) { + continue; + } + for (PdIndex = 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdIndex++, Pd++) { + if ((*Pd & IA32_PG_P) == 0) { + // + // If PD entry does not exist, skip it + // + continue; + } + Address = (UINTN) LShiftU64 ( + LShiftU64 ( + LShiftU64 ((Pml5Index << 9) + Pml4Index, 9) + PdptIndex, + 9 + ) + PdIndex, + 21 + ); + + if ((*Pd & IA32_PG_PS) != 0) { + // 2MB page + + if (!IsAddressValid (Address, &Nx)) { + // + // Patch to remove Present flag and RW flag + // + *Pd = *Pd & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); + } + if (Nx && mXdSupported) { + *Pd = *Pd | IA32_PG_NX; + } + } else { + // 4KB page + Pt = (UINT64 *)(UINTN)(*Pd & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + if (Pt == 0) { + continue; + } + for (PtIndex = 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtIndex++, Pt++) { + if (!IsAddressValid (Address, &Nx)) { + *Pt = *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); + } + if (Nx && mXdSupported) { + *Pt = *Pt | IA32_PG_NX; + } + Address += SIZE_4KB; + } // end for PT + } // end if PS + } // end for PD + } // end for PDPT + } // end for PML4 + } // end for PML5 + + // + // Flush TLB + // + CpuFlushTlb (); + DEBUG ((EFI_D_INFO, "Patch page table done!\n")); + // + // Set execute-disable flag + // + mXdEnabled = TRUE; + + return ; +} + +/** + 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); + + mSmiCommandPort = Fadt->SmiCmd; + DEBUG ((EFI_D_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort)); +} + +/** + Updates page table to make some memory ranges (like system memory) absent + and make some memory ranges (like MMIO) present and execute disable. It also + update 2MB-page to 4KB-page for some memory ranges. + +**/ +VOID +SmmProfileStart ( + VOID + ) +{ + // + // The flag indicates SMM profile starts to work. + // + mSmmProfileStart = TRUE; +} + +/** + Initialize SMM profile in SmmReadyToLock protocol callback function. + + @param Protocol Points to the protocol's unique identifier. + @param Interface Points to the interface instance. + @param Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS SmmReadyToLock protocol callback runs successfully. +**/ +EFI_STATUS +EFIAPI +InitSmmProfileCallBack ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + 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 + ); + + // + // Get Software SMI from FADT + // + GetSmiCommandPort (); + + // + // Initialize protected memory range for patching page table later. + // + InitProtectedMemRange (); + + return EFI_SUCCESS; +} + +/** + Initialize SMM profile data structures. + +**/ +VOID +InitSmmProfileInternal ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Base; + VOID *Registration; + UINTN Index; + UINTN MsrDsAreaSizePerCpu; + UINTN TotalSize; + + mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mMaxNumberOfCpus); + ASSERT (mPFEntryCount != NULL); + mLastPFEntryValue = (UINT64 (*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool ( + sizeof (mLastPFEntryValue[0]) * mMaxNumberOfCpus); + ASSERT (mLastPFEntryValue != NULL); + mLastPFEntryPointer = (UINT64 *(*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool ( + sizeof (mLastPFEntryPointer[0]) * mMaxNumberOfCpus); + ASSERT (mLastPFEntryPointer != NULL); + + // + // Allocate memory for SmmProfile below 4GB. + // The base address + // + mSmmProfileSize = PcdGet32 (PcdCpuSmmProfileSize); + ASSERT ((mSmmProfileSize & 0xFFF) == 0); + + if (mBtsSupported) { + TotalSize = mSmmProfileSize + mMsrDsAreaSize; + } else { + TotalSize = mSmmProfileSize; + } + + 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; + + // + // Initialize SMM profile data header. + // + mSmmProfileBase->HeaderSize = sizeof (SMM_PROFILE_HEADER); + mSmmProfileBase->MaxDataEntries = (UINT64)((mSmmProfileSize - sizeof(SMM_PROFILE_HEADER)) / sizeof (SMM_PROFILE_ENTRY)); + mSmmProfileBase->MaxDataSize = MultU64x64 (mSmmProfileBase->MaxDataEntries, sizeof(SMM_PROFILE_ENTRY)); + mSmmProfileBase->CurDataEntries = 0; + mSmmProfileBase->CurDataSize = 0; + mSmmProfileBase->TsegStart = mCpuHotPlugData.SmrrBase; + mSmmProfileBase->TsegSize = mCpuHotPlugData.SmrrSize; + mSmmProfileBase->NumSmis = 0; + mSmmProfileBase->NumCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + + if (mBtsSupported) { + mMsrDsArea = (MSR_DS_AREA_STRUCT **)AllocateZeroPool (sizeof (MSR_DS_AREA_STRUCT *) * mMaxNumberOfCpus); + ASSERT (mMsrDsArea != NULL); + mMsrBTSRecord = (BRANCH_TRACE_RECORD **)AllocateZeroPool (sizeof (BRANCH_TRACE_RECORD *) * mMaxNumberOfCpus); + ASSERT (mMsrBTSRecord != NULL); + mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * mMaxNumberOfCpus); + ASSERT (mMsrPEBSRecord != NULL); + + mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + 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++) { + mMsrDsArea[Index] = (MSR_DS_AREA_STRUCT *)((UINTN)mMsrDsAreaBase + MsrDsAreaSizePerCpu * Index); + mMsrBTSRecord[Index] = (BRANCH_TRACE_RECORD *)((UINTN)mMsrDsArea[Index] + sizeof(MSR_DS_AREA_STRUCT)); + mMsrPEBSRecord[Index] = (PEBS_RECORD *)((UINTN)mMsrDsArea[Index] + MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER); + + mMsrDsArea[Index]->BTSBufferBase = (UINTN)mMsrBTSRecord[Index]; + mMsrDsArea[Index]->BTSIndex = mMsrDsArea[Index]->BTSBufferBase; + mMsrDsArea[Index]->BTSAbsoluteMaximum = mMsrDsArea[Index]->BTSBufferBase + mBTSRecordNumber * sizeof(BRANCH_TRACE_RECORD) + 1; + mMsrDsArea[Index]->BTSInterruptThreshold = mMsrDsArea[Index]->BTSAbsoluteMaximum + 1; + + mMsrDsArea[Index]->PEBSBufferBase = (UINTN)mMsrPEBSRecord[Index]; + mMsrDsArea[Index]->PEBSIndex = mMsrDsArea[Index]->PEBSBufferBase; + mMsrDsArea[Index]->PEBSAbsoluteMaximum = mMsrDsArea[Index]->PEBSBufferBase + PEBS_RECORD_NUMBER * sizeof(PEBS_RECORD) + 1; + mMsrDsArea[Index]->PEBSInterruptThreshold = mMsrDsArea[Index]->PEBSAbsoluteMaximum + 1; + } + } + + mProtectionMemRange = mProtectionMemRangeTemplate; + mProtectionMemRangeCount = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE); + + // + // Update TSeg entry. + // + mProtectionMemRange[0].Range.Base = mCpuHotPlugData.SmrrBase; + mProtectionMemRange[0].Range.Top = mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize; + + // + // Update SMM profile entry. + // + mProtectionMemRange[1].Range.Base = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase; + mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + TotalSize; + + // + // Allocate memory reserved for creating 4KB pages. + // + InitPagesForPFHandler (); + + // + // Start SMM profile when SmmReadyToLock protocol is installed. + // + Status = gSmst->SmmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + InitSmmProfileCallBack, + &Registration + ); + ASSERT_EFI_ERROR (Status); + + return ; +} + +/** + Check if feature is supported by a processor. + +**/ +VOID +CheckFeatureSupported ( + VOID + ) +{ + UINT32 RegEax; + UINT32 RegEcx; + UINT32 RegEdx; + MSR_IA32_MISC_ENABLE_REGISTER MiscEnableMsr; + + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); + if (RegEax <= CPUID_EXTENDED_FUNCTION) { + mCetSupported = FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, NULL); + if ((RegEcx & CPUID_CET_SS) == 0) { + mCetSupported = FALSE; + PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1); + } + } + + 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 (mBtsSupported) { + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & CPUID1_EDX_BTS_AVAILABLE) != 0) { + // + // Per IA32 manuals: + // When CPUID.1:EDX[21] is set, the following BTS facilities are available: + // 1. The BTS_UNAVAILABLE flag in the IA32_MISC_ENABLE MSR indicates the + // availability of the BTS facilities, including the ability to set the BTS and + // BTINT bits in the MSR_DEBUGCTLA MSR. + // 2. The IA32_DS_AREA MSR can be programmed to point to the DS save area. + // + MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE); + if (MiscEnableMsr.Bits.BTS == 1) { + // + // BTS facilities is not supported if MSR_IA32_MISC_ENABLE.BTS bit is set. + // + mBtsSupported = FALSE; + } + } + } +} + +/** + Enable single step. + +**/ +VOID +ActivateSingleStepDB ( + VOID + ) +{ + UINTN Dr6; + + Dr6 = AsmReadDr6 (); + if ((Dr6 & DR6_SINGLE_STEP) != 0) { + return; + } + Dr6 |= DR6_SINGLE_STEP; + AsmWriteDr6 (Dr6); +} + +/** + Enable last branch. + +**/ +VOID +ActivateLBR ( + VOID + ) +{ + UINT64 DebugCtl; + + DebugCtl = AsmReadMsr64 (MSR_DEBUG_CTL); + if ((DebugCtl & MSR_DEBUG_CTL_LBR) != 0) { + return ; + } + DebugCtl |= MSR_DEBUG_CTL_LBR; + AsmWriteMsr64 (MSR_DEBUG_CTL, DebugCtl); +} + +/** + Enable branch trace store. + + @param CpuIndex The index of the processor. + +**/ +VOID +ActivateBTS ( + IN UINTN CpuIndex + ) +{ + UINT64 DebugCtl; + + DebugCtl = AsmReadMsr64 (MSR_DEBUG_CTL); + if ((DebugCtl & MSR_DEBUG_CTL_BTS) != 0) { + return ; + } + + AsmWriteMsr64 (MSR_DS_AREA, (UINT64)(UINTN)mMsrDsArea[CpuIndex]); + DebugCtl |= (UINT64)(MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR); + DebugCtl &= ~((UINT64)MSR_DEBUG_CTL_BTINT); + AsmWriteMsr64 (MSR_DEBUG_CTL, DebugCtl); +} + +/** + Increase SMI number in each SMI entry. + +**/ +VOID +SmmProfileRecordSmiNum ( + VOID + ) +{ + if (mSmmProfileStart) { + mSmmProfileBase->NumSmis++; + } +} + +/** + Initialize processor environment for SMM profile. + + @param CpuIndex The index of the processor. + +**/ +VOID +ActivateSmmProfile ( + IN UINTN CpuIndex + ) +{ + // + // Enable Single Step DB# + // + ActivateSingleStepDB (); + + if (mBtsSupported) { + // + // We can not get useful information from LER, so we have to use BTS. + // + ActivateLBR (); + + // + // Enable BTS + // + ActivateBTS (CpuIndex); + } +} + +/** + Initialize SMM profile in SMM CPU entry point. + + @param[in] Cr3 The base address of the page tables to use in SMM. + +**/ +VOID +InitSmmProfile ( + UINT32 Cr3 + ) +{ + // + // Save Cr3 + // + mSmmProfileCr3 = Cr3; + + // + // Skip SMM profile initialization if feature is disabled + // + if (!FeaturePcdGet (PcdCpuSmmProfileEnable) && + !HEAP_GUARD_NONSTOP_MODE && + !NULL_DETECTION_NONSTOP_MODE) { + return; + } + + // + // Initialize SmmProfile here + // + InitSmmProfileInternal (); + + // + // Initialize profile IDT. + // + InitIdtr (); + + // + // Tell #PF handler to prepare a #DB subsequently. + // + mSetupDebugTrap = TRUE; +} + +/** + 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. + + @param PageTable PageTable Address. + @param PFAddress The memory address which caused page fault exception. + @param CpuIndex The index of the processor. + @param ErrorCode The Error code of exception. + +**/ +VOID +RestorePageTableBelow4G ( + UINT64 *PageTable, + UINT64 PFAddress, + UINTN CpuIndex, + UINTN ErrorCode + ) +{ + UINTN PTIndex; + UINTN PFIndex; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + + // + // PML5 + // + if (Enable5LevelPaging) { + PTIndex = (UINTN)BitFieldRead64 (PFAddress, 48, 56); + ASSERT (PageTable[PTIndex] != 0); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); + } + + // + // PML4 + // + if (sizeof(UINT64) == sizeof(UINTN)) { + PTIndex = (UINTN)BitFieldRead64 (PFAddress, 39, 47); + ASSERT (PageTable[PTIndex] != 0); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); + } + + // + // PDPTE + // + PTIndex = (UINTN)BitFieldRead64 (PFAddress, 30, 38); + ASSERT (PageTable[PTIndex] != 0); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); + + // + // PD + // + PTIndex = (UINTN)BitFieldRead64 (PFAddress, 21, 29); + if ((PageTable[PTIndex] & IA32_PG_PS) != 0) { + // + // Large page + // + + // + // Record old entries with non-present status + // Old entries include the memory which instruction is at and the memory which instruction access. + // + // + ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT); + if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) { + PFIndex = mPFEntryCount[CpuIndex]; + mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex]; + mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex]; + mPFEntryCount[CpuIndex]++; + } + + // + // Set new entry + // + PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1)); + PageTable[PTIndex] |= (UINT64)IA32_PG_PS; + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; + if ((ErrorCode & IA32_PF_EC_ID) != 0) { + PageTable[PTIndex] &= ~IA32_PG_NX; + } + } else { + // + // Small page + // + ASSERT (PageTable[PTIndex] != 0); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); + + // + // 4K PTE + // + PTIndex = (UINTN)BitFieldRead64 (PFAddress, 12, 20); + + // + // Record old entries with non-present status + // Old entries include the memory which instruction is at and the memory which instruction access. + // + // + ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT); + if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) { + PFIndex = mPFEntryCount[CpuIndex]; + mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex]; + mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex]; + mPFEntryCount[CpuIndex]++; + } + + // + // Set new entry + // + PageTable[PTIndex] = (PFAddress & ~((1ull << 12) - 1)); + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; + if ((ErrorCode & IA32_PF_EC_ID) != 0) { + PageTable[PTIndex] &= ~IA32_PG_NX; + } + } +} + +/** + Handler for Page Fault triggered by Guard page. + + @param ErrorCode The Error code of exception. + +**/ +VOID +GuardPagePFHandler ( + UINTN ErrorCode + ) +{ + UINT64 *PageTable; + UINT64 PFAddress; + UINT64 RestoreAddress; + UINTN RestorePageNumber; + UINTN CpuIndex; + + PageTable = (UINT64 *)AsmReadCr3 (); + PFAddress = AsmReadCr2 (); + CpuIndex = GetCpuIndex (); + + // + // Memory operation cross pages, like "rep mov" instruction, will cause + // infinite loop between this and Debug Trap handler. We have to make sure + // that current page and the page followed are both in PRESENT state. + // + RestorePageNumber = 2; + RestoreAddress = PFAddress; + while (RestorePageNumber > 0) { + RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode); + RestoreAddress += EFI_PAGE_SIZE; + RestorePageNumber--; + } + + // + // Flush TLB + // + CpuFlushTlb (); +} + +/** + The Page fault handler to save SMM profile data. + + @param Rip The RIP when exception happens. + @param ErrorCode The Error code of exception. + +**/ +VOID +SmmProfilePFHandler ( + UINTN Rip, + UINTN ErrorCode + ) +{ + UINT64 *PageTable; + UINT64 PFAddress; + UINT64 RestoreAddress; + UINTN RestorePageNumber; + UINTN CpuIndex; + UINTN Index; + UINT64 InstructionAddress; + UINTN MaxEntryNumber; + UINTN CurrentEntryNumber; + BOOLEAN IsValidPFAddress; + SMM_PROFILE_ENTRY *SmmProfileEntry; + UINT64 SmiCommand; + EFI_STATUS Status; + 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 (); + } + + IsValidPFAddress = FALSE; + PageTable = (UINT64 *)AsmReadCr3 (); + PFAddress = AsmReadCr2 (); + CpuIndex = GetCpuIndex (); + + // + // Memory operation cross pages, like "rep mov" instruction, will cause + // infinite loop between this and Debug Trap handler. We have to make sure + // that current page and the page followed are both in PRESENT state. + // + RestorePageNumber = 2; + RestoreAddress = PFAddress; + while (RestorePageNumber > 0) { + if (RestoreAddress <= 0xFFFFFFFF) { + RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode); + } else { + RestorePageTableAbove4G (PageTable, RestoreAddress, CpuIndex, ErrorCode, &IsValidPFAddress); + } + RestoreAddress += EFI_PAGE_SIZE; + RestorePageNumber--; + } + + if (!IsValidPFAddress) { + InstructionAddress = Rip; + if ((ErrorCode & IA32_PF_EC_ID) != 0 && (mBtsSupported)) { + // + // If it is instruction fetch failure, get the correct IP from BTS. + // + InstructionAddress = GetSourceFromDestinationOnBts (CpuIndex, Rip); + if (InstructionAddress == 0) { + // + // It indicates the instruction which caused page fault is not a jump instruction, + // set instruction address same as the page fault address. + // + InstructionAddress = PFAddress; + } + } + + // + // Indicate it is not software SMI + // + SmiCommand = 0xFFFFFFFFFFFFFFFFULL; + for (Index = 0; Index < gSmst->NumberOfCpus; Index++) { + Status = SmmReadSaveState(&mSmmCpu, sizeof(IoInfo), EFI_SMM_SAVE_STATE_REGISTER_IO, Index, &IoInfo); + if (EFI_ERROR (Status)) { + continue; + } + if (IoInfo.IoPort == mSmiCommandPort) { + // + // A software SMI triggered by SMI command port has been found, get SmiCommand from SMI command port. + // + SoftSmiValue = IoRead8 (mSmiCommandPort); + SmiCommand = (UINT64)SoftSmiValue; + break; + } + } + + SmmProfileEntry = (SMM_PROFILE_ENTRY *)(UINTN)(mSmmProfileBase + 1); + // + // Check if there is already a same entry in profile data. + // + for (Index = 0; Index < (UINTN) mSmmProfileBase->CurDataEntries; Index++) { + if ((SmmProfileEntry[Index].ErrorCode == (UINT64)ErrorCode) && + (SmmProfileEntry[Index].Address == PFAddress) && + (SmmProfileEntry[Index].CpuNum == (UINT64)CpuIndex) && + (SmmProfileEntry[Index].Instruction == InstructionAddress) && + (SmmProfileEntry[Index].SmiCmd == SmiCommand)) { + // + // Same record exist, need not save again. + // + break; + } + } + if (Index == mSmmProfileBase->CurDataEntries) { + CurrentEntryNumber = (UINTN) mSmmProfileBase->CurDataEntries; + MaxEntryNumber = (UINTN) mSmmProfileBase->MaxDataEntries; + if (FeaturePcdGet (PcdCpuSmmProfileRingBuffer)) { + CurrentEntryNumber = CurrentEntryNumber % MaxEntryNumber; + } + if (CurrentEntryNumber < MaxEntryNumber) { + // + // Log the new entry + // + SmmProfileEntry[CurrentEntryNumber].SmiNum = mSmmProfileBase->NumSmis; + SmmProfileEntry[CurrentEntryNumber].ErrorCode = (UINT64)ErrorCode; + SmmProfileEntry[CurrentEntryNumber].ApicId = (UINT64)GetApicId (); + SmmProfileEntry[CurrentEntryNumber].CpuNum = (UINT64)CpuIndex; + SmmProfileEntry[CurrentEntryNumber].Address = PFAddress; + SmmProfileEntry[CurrentEntryNumber].Instruction = InstructionAddress; + SmmProfileEntry[CurrentEntryNumber].SmiCmd = SmiCommand; + // + // Update current entry index and data size in the header. + // + mSmmProfileBase->CurDataEntries++; + mSmmProfileBase->CurDataSize = MultU64x64 (mSmmProfileBase->CurDataEntries, sizeof (SMM_PROFILE_ENTRY)); + } + } + } + // + // Flush TLB + // + CpuFlushTlb (); + + if (mBtsSupported) { + EnableBTS (); + } +} + +/** + Replace INT1 exception handler to restore page table to absent/execute-disable state + in order to trigger page fault again to save SMM profile data.. + +**/ +VOID +InitIdtr ( + VOID + ) +{ + EFI_STATUS Status; + + Status = SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_DEBUG, DebugExceptionHandler); + ASSERT_EFI_ERROR (Status); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h new file mode 100644 index 000000000..484d81eb0 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h @@ -0,0 +1,135 @@ +/** @file +SMM profile header file. + +Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_PROFILE_H_ +#define _SMM_PROFILE_H_ + +#include "SmmProfileInternal.h" + +// +// External functions +// + +/** + Initialize processor environment for SMM profile. + + @param CpuIndex The index of the processor. + +**/ +VOID +ActivateSmmProfile ( + IN UINTN CpuIndex + ); + +/** + Initialize SMM profile in SMM CPU entry point. + + @param[in] Cr3 The base address of the page tables to use in SMM. + +**/ +VOID +InitSmmProfile ( + UINT32 Cr3 + ); + +/** + Increase SMI number in each SMI entry. + +**/ +VOID +SmmProfileRecordSmiNum ( + VOID + ); + +/** + The Page fault handler to save SMM profile data. + + @param Rip The RIP when exception happens. + @param ErrorCode The Error code of exception. + +**/ +VOID +SmmProfilePFHandler ( + UINTN Rip, + UINTN ErrorCode + ); + +/** + Updates page table to make some memory ranges (like system memory) absent + and make some memory ranges (like MMIO) present and execute disable. It also + update 2MB-page to 4KB-page for some memory ranges. + +**/ +VOID +SmmProfileStart ( + VOID + ); + +/** + Page fault IDT handler for SMM Profile. + +**/ +VOID +EFIAPI +PageFaultIdtHandlerSmmProfile ( + VOID + ); + + +/** + Check if feature is supported by a processor. + +**/ +VOID +CheckFeatureSupported ( + VOID + ); + +/** + Update page table according to protected memory ranges and the 4KB-page mapped memory ranges. + +**/ +VOID +InitPaging ( + VOID + ); + +/** + Get CPU Index from APIC ID. + +**/ +UINTN +GetCpuIndex ( + VOID + ); + +/** + Handler for Page Fault triggered by Guard page. + + @param ErrorCode The Error code of exception. + +**/ +VOID +GuardPagePFHandler ( + UINTN ErrorCode + ); + +// +// The flag indicates if execute-disable is supported by processor. +// +extern BOOLEAN mXdSupported; +// +// The flag indicates if execute-disable is enabled on processor. +// +extern BOOLEAN mXdEnabled; +// +// The flag indicates if #DB will be setup in #PF handler. +// +extern BOOLEAN mSetupDebugTrap; + +#endif // _SMM_PROFILE_H_ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h new file mode 100644 index 000000000..43f6935cf --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -0,0 +1,164 @@ +/** @file +SMM profile internal header file. + +Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_PROFILE_INTERNAL_H_ +#define _SMM_PROFILE_INTERNAL_H_ + +#include +#include +#include +#include +#include + +#include "SmmProfileArch.h" + +// +// Configure the SMM_PROFILE DTS region size +// +#define SMM_PROFILE_DTS_SIZE (4 * 1024 * 1024) // 4M + +#define MAX_PF_PAGE_COUNT 0x2 + +#define PEBS_RECORD_NUMBER 0x2 + +#define MAX_PF_ENTRY_COUNT 10 + +// +// This MACRO just enable unit test for the profile +// Please disable it. +// + +#define IA32_PF_EC_ID (1u << 4) + +#define SMM_PROFILE_NAME L"SmmProfileData" + +// +// CPU generic definition +// +#define CPUID1_EDX_XD_SUPPORT 0x100000 +#define MSR_EFER 0xc0000080 +#define MSR_EFER_XD 0x800 + +#define CPUID1_EDX_BTS_AVAILABLE 0x200000 + +#define DR6_SINGLE_STEP 0x4000 +#define RFLAG_TF 0x100 + +#define MSR_DEBUG_CTL 0x1D9 +#define MSR_DEBUG_CTL_LBR 0x1 +#define MSR_DEBUG_CTL_TR 0x40 +#define MSR_DEBUG_CTL_BTS 0x80 +#define MSR_DEBUG_CTL_BTINT 0x100 +#define MSR_DS_AREA 0x600 + +#define HEAP_GUARD_NONSTOP_MODE \ + ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT6|BIT3|BIT2)) > BIT6) + +#define NULL_DETECTION_NONSTOP_MODE \ + ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT6|BIT1)) > BIT6) + +typedef struct { + EFI_PHYSICAL_ADDRESS Base; + EFI_PHYSICAL_ADDRESS Top; +} MEMORY_RANGE; + +typedef struct { + MEMORY_RANGE Range; + BOOLEAN Present; + BOOLEAN Nx; +} MEMORY_PROTECTION_RANGE; + +typedef struct { + UINT64 HeaderSize; + UINT64 MaxDataEntries; + UINT64 MaxDataSize; + UINT64 CurDataEntries; + UINT64 CurDataSize; + UINT64 TsegStart; + UINT64 TsegSize; + UINT64 NumSmis; + UINT64 NumCpus; +} SMM_PROFILE_HEADER; + +typedef struct { + UINT64 SmiNum; + UINT64 CpuNum; + UINT64 ApicId; + UINT64 ErrorCode; + UINT64 Instruction; + UINT64 Address; + UINT64 SmiCmd; +} SMM_PROFILE_ENTRY; + +extern SMM_S3_RESUME_STATE *mSmmS3ResumeState; +extern UINTN gSmiExceptionHandlers[]; +extern BOOLEAN mXdSupported; +X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported; +extern UINTN *mPFEntryCount; +extern UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT]; +extern UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; + +// +// Internal functions +// + +/** + Update IDT table to replace page fault handler and INT 1 handler. + +**/ +VOID +InitIdtr ( + VOID + ); + +/** + Check if the memory address will be mapped by 4KB-page. + + @param Address The address of Memory. + +**/ +BOOLEAN +IsAddressSplit ( + IN EFI_PHYSICAL_ADDRESS Address + ); + +/** + Check if the memory address will be mapped by 4KB-page. + + @param Address The address of Memory. + @param Nx The flag indicates if the memory is execute-disable. + +**/ +BOOLEAN +IsAddressValid ( + IN EFI_PHYSICAL_ADDRESS Address, + IN BOOLEAN *Nx + ); + +/** + Page Fault handler for SMM use. + +**/ +VOID +SmiDefaultPFHandler ( + VOID + ); + +/** + Clear TF in FLAGS. + + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. + +**/ +VOID +ClearTrapFlag ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ); + +#endif // _SMM_PROFILE_H_ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c new file mode 100644 index 000000000..661cc51f3 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c @@ -0,0 +1,735 @@ +/** @file +Provides services to access SMRAM Save State Map + +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include + +#include "PiSmmCpuDxeSmm.h" + +typedef struct { + UINT64 Signature; // Offset 0x00 + UINT16 Reserved1; // Offset 0x08 + UINT16 Reserved2; // Offset 0x0A + UINT16 Reserved3; // Offset 0x0C + UINT16 SmmCs; // Offset 0x0E + UINT16 SmmDs; // Offset 0x10 + UINT16 SmmSs; // Offset 0x12 + UINT16 SmmOtherSegment; // Offset 0x14 + UINT16 Reserved4; // Offset 0x16 + UINT64 Reserved5; // Offset 0x18 + UINT64 Reserved6; // Offset 0x20 + UINT64 Reserved7; // Offset 0x28 + UINT64 SmmGdtPtr; // Offset 0x30 + UINT32 SmmGdtSize; // Offset 0x38 + UINT32 Reserved8; // Offset 0x3C + UINT64 Reserved9; // Offset 0x40 + UINT64 Reserved10; // Offset 0x48 + UINT16 Reserved11; // Offset 0x50 + UINT16 Reserved12; // Offset 0x52 + UINT32 Reserved13; // Offset 0x54 + UINT64 Reserved14; // Offset 0x58 +} PROCESSOR_SMM_DESCRIPTOR; + +extern CONST PROCESSOR_SMM_DESCRIPTOR gcPsd; + +// +// EFER register LMA bit +// +#define LMA BIT10 + +/// +/// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY +/// +#define SMM_CPU_OFFSET(Field) OFFSET_OF (SMRAM_SAVE_STATE_MAP, Field) + +/// +/// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_STATE_REGISTER_RANGE +/// +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 } + +/// +/// Structure used to describe a range of registers +/// +typedef struct { + EFI_SMM_SAVE_STATE_REGISTER Start; + EFI_SMM_SAVE_STATE_REGISTER End; + UINTN Length; +} CPU_SMM_SAVE_STATE_REGISTER_RANGE; + +/// +/// Structure used to build a lookup table to retrieve the widths and offsets +/// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value +/// + +#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1 +#define SMM_SAVE_STATE_REGISTER_IOMISC_INDEX 2 +#define SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX 3 +#define SMM_SAVE_STATE_REGISTER_MAX_INDEX 4 + +typedef struct { + UINT8 Width32; + UINT8 Width64; + UINT16 Offset32; + UINT16 Offset64Lo; + UINT16 Offset64Hi; + BOOLEAN Writeable; +} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY; + +/// +/// Structure used to build a lookup table for the IOMisc width information +/// +typedef struct { + UINT8 Width; + EFI_SMM_SAVE_STATE_IO_WIDTH IoWidth; +} CPU_SMM_SAVE_STATE_IO_WIDTH; + +/// +/// Variables from SMI Handler +/// +X86_ASSEMBLY_PATCH_LABEL gPatchSmbase; +X86_ASSEMBLY_PATCH_LABEL gPatchSmiStack; +X86_ASSEMBLY_PATCH_LABEL gPatchSmiCr3; +extern volatile UINT8 gcSmiHandlerTemplate[]; +extern CONST UINT16 gcSmiHandlerSize; + +// +// Variables used by SMI Handler +// +IA32_DESCRIPTOR gSmiHandlerIdtr; + +/// +/// Table used by GetRegisterIndex() to convert an EFI_SMM_SAVE_STATE_REGISTER +/// value to an index into a table of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY +/// +CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmCpuRegisterRanges[] = { + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, EFI_SMM_SAVE_STATE_REGISTER_LDTINFO), + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, EFI_SMM_SAVE_STATE_REGISTER_RIP), + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, EFI_SMM_SAVE_STATE_REGISTER_CR4), + { (EFI_SMM_SAVE_STATE_REGISTER)0, (EFI_SMM_SAVE_STATE_REGISTER)0, 0 } +}; + +/// +/// Lookup table used to retrieve the widths and offsets associated with each +/// supported EFI_SMM_SAVE_STATE_REGISTER value +/// +CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmCpuWidthOffset[] = { + {0, 0, 0, 0, 0, FALSE}, // Reserved + + // + // Internally defined CPU Save State Registers. Not defined in PI SMM CPU Protocol. + // + {4, 4, SMM_CPU_OFFSET (x86.SMMRevId) , SMM_CPU_OFFSET (x64.SMMRevId) , 0 , FALSE}, // SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX = 1 + {4, 4, SMM_CPU_OFFSET (x86.IOMisc) , SMM_CPU_OFFSET (x64.IOMisc) , 0 , FALSE}, // SMM_SAVE_STATE_REGISTER_IOMISC_INDEX = 2 + {4, 8, SMM_CPU_OFFSET (x86.IOMemAddr) , SMM_CPU_OFFSET (x64.IOMemAddr) , SMM_CPU_OFFSET (x64.IOMemAddr) + 4, FALSE}, // SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX = 3 + + // + // CPU Save State registers defined in PI SMM CPU Protocol. + // + {0, 8, 0 , SMM_CPU_OFFSET (x64.GdtBaseLoDword) , SMM_CPU_OFFSET (x64.GdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4 + {0, 8, 0 , SMM_CPU_OFFSET (x64.IdtBaseLoDword) , SMM_CPU_OFFSET (x64.IdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5 + {0, 8, 0 , SMM_CPU_OFFSET (x64.LdtBaseLoDword) , SMM_CPU_OFFSET (x64.LdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6 + {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7 + {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8 + {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9 + {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10 + + {4, 4, SMM_CPU_OFFSET (x86._ES) , SMM_CPU_OFFSET (x64._ES) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_ES = 20 + {4, 4, SMM_CPU_OFFSET (x86._CS) , SMM_CPU_OFFSET (x64._CS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CS = 21 + {4, 4, SMM_CPU_OFFSET (x86._SS) , SMM_CPU_OFFSET (x64._SS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_SS = 22 + {4, 4, SMM_CPU_OFFSET (x86._DS) , SMM_CPU_OFFSET (x64._DS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DS = 23 + {4, 4, SMM_CPU_OFFSET (x86._FS) , SMM_CPU_OFFSET (x64._FS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_FS = 24 + {4, 4, SMM_CPU_OFFSET (x86._GS) , SMM_CPU_OFFSET (x64._GS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GS = 25 + {0, 4, 0 , SMM_CPU_OFFSET (x64._LDTR) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL = 26 + {4, 4, SMM_CPU_OFFSET (x86._TR) , SMM_CPU_OFFSET (x64._TR) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_TR_SEL = 27 + {4, 8, SMM_CPU_OFFSET (x86._DR7) , SMM_CPU_OFFSET (x64._DR7) , SMM_CPU_OFFSET (x64._DR7) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28 + {4, 8, SMM_CPU_OFFSET (x86._DR6) , SMM_CPU_OFFSET (x64._DR6) , SMM_CPU_OFFSET (x64._DR6) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R8) , SMM_CPU_OFFSET (x64._R8) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R8 = 30 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R9) , SMM_CPU_OFFSET (x64._R9) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R9 = 31 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R10) , SMM_CPU_OFFSET (x64._R10) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R10 = 32 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R11) , SMM_CPU_OFFSET (x64._R11) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R11 = 33 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R12) , SMM_CPU_OFFSET (x64._R12) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R12 = 34 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R13) , SMM_CPU_OFFSET (x64._R13) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R13 = 35 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R14) , SMM_CPU_OFFSET (x64._R14) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R14 = 36 + {0, 8, 0 , SMM_CPU_OFFSET (x64._R15) , SMM_CPU_OFFSET (x64._R15) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R15 = 37 + {4, 8, SMM_CPU_OFFSET (x86._EAX) , SMM_CPU_OFFSET (x64._RAX) , SMM_CPU_OFFSET (x64._RAX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RAX = 38 + {4, 8, SMM_CPU_OFFSET (x86._EBX) , SMM_CPU_OFFSET (x64._RBX) , SMM_CPU_OFFSET (x64._RBX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RBX = 39 + {4, 8, SMM_CPU_OFFSET (x86._ECX) , SMM_CPU_OFFSET (x64._RCX) , SMM_CPU_OFFSET (x64._RCX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RCX = 40 + {4, 8, SMM_CPU_OFFSET (x86._EDX) , SMM_CPU_OFFSET (x64._RDX) , SMM_CPU_OFFSET (x64._RDX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RDX = 41 + {4, 8, SMM_CPU_OFFSET (x86._ESP) , SMM_CPU_OFFSET (x64._RSP) , SMM_CPU_OFFSET (x64._RSP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RSP = 42 + {4, 8, SMM_CPU_OFFSET (x86._EBP) , SMM_CPU_OFFSET (x64._RBP) , SMM_CPU_OFFSET (x64._RBP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RBP = 43 + {4, 8, SMM_CPU_OFFSET (x86._ESI) , SMM_CPU_OFFSET (x64._RSI) , SMM_CPU_OFFSET (x64._RSI) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RSI = 44 + {4, 8, SMM_CPU_OFFSET (x86._EDI) , SMM_CPU_OFFSET (x64._RDI) , SMM_CPU_OFFSET (x64._RDI) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RDI = 45 + {4, 8, SMM_CPU_OFFSET (x86._EIP) , SMM_CPU_OFFSET (x64._RIP) , SMM_CPU_OFFSET (x64._RIP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RIP = 46 + + {4, 8, SMM_CPU_OFFSET (x86._EFLAGS) , SMM_CPU_OFFSET (x64._RFLAGS) , SMM_CPU_OFFSET (x64._RFLAGS) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51 + {4, 8, SMM_CPU_OFFSET (x86._CR0) , SMM_CPU_OFFSET (x64._CR0) , SMM_CPU_OFFSET (x64._CR0) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52 + {4, 8, SMM_CPU_OFFSET (x86._CR3) , SMM_CPU_OFFSET (x64._CR3) , SMM_CPU_OFFSET (x64._CR3) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53 + {0, 4, 0 , SMM_CPU_OFFSET (x64._CR4) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR4 = 54 +}; + +/// +/// Lookup table for the IOMisc width information +/// +CONST CPU_SMM_SAVE_STATE_IO_WIDTH mSmmCpuIoWidth[] = { + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 0 + { 1, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // SMM_IO_LENGTH_BYTE = 1 + { 2, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16 }, // SMM_IO_LENGTH_WORD = 2 + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 3 + { 4, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32 }, // SMM_IO_LENGTH_DWORD = 4 + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 5 + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 6 + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 } // Undefined = 7 +}; + +/// +/// Lookup table for the IOMisc type information +/// +CONST EFI_SMM_SAVE_STATE_IO_TYPE mSmmCpuIoType[] = { + EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, // SMM_IO_TYPE_OUT_DX = 0 + EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, // SMM_IO_TYPE_IN_DX = 1 + EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_OUTS = 2 + EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_INS = 3 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 4 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 5 + EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, // SMM_IO_TYPE_REP_OUTS = 6 + EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, // SMM_IO_TYPE_REP_INS = 7 + EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, // SMM_IO_TYPE_OUT_IMMEDIATE = 8 + EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, // SMM_IO_TYPE_OUT_IMMEDIATE = 9 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 10 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 11 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 12 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 13 + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 14 + (EFI_SMM_SAVE_STATE_IO_TYPE)0 // Undefined = 15 +}; + +/// +/// The mode of the CPU at the time an SMI occurs +/// +UINT8 mSmmSaveStateRegisterLma; + +/** + Read information from the CPU save state. + + @param Register Specifies the CPU register to read form the save state. + + @retval 0 Register is not valid + @retval >0 Index into mSmmCpuWidthOffset[] associated with Register + +**/ +UINTN +GetRegisterIndex ( + IN EFI_SMM_SAVE_STATE_REGISTER Register + ) +{ + UINTN Index; + UINTN Offset; + + for (Index = 0, Offset = SMM_SAVE_STATE_REGISTER_MAX_INDEX; mSmmCpuRegisterRanges[Index].Length != 0; Index++) { + if (Register >= mSmmCpuRegisterRanges[Index].Start && Register <= mSmmCpuRegisterRanges[Index].End) { + return Register - mSmmCpuRegisterRanges[Index].Start + Offset; + } + Offset += mSmmCpuRegisterRanges[Index].Length; + } + return 0; +} + +/** + Read a CPU Save State register on the target processor. + + This function abstracts the differences that whether the CPU Save State register is in the + IA32 CPU Save State Map or X64 CPU Save State Map. + + This function supports reading a CPU Save State register in SMBase relocation handler. + + @param[in] CpuIndex Specifies the zero-based index of the CPU save state. + @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. + @param[in] Width The number of bytes to read from the CPU save state. + @param[out] 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 +ReadSaveStateRegisterByIndex ( + IN UINTN CpuIndex, + IN UINTN RegisterIndex, + IN UINTN Width, + OUT VOID *Buffer + ) +{ + SMRAM_SAVE_STATE_MAP *CpuSaveState; + + if (RegisterIndex == 0) { + return EFI_NOT_FOUND; + } + + CpuSaveState = gSmst->CpuSaveState[CpuIndex]; + + if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { + // + // If 32-bit mode width is zero, then the specified register can not be accessed + // + if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 32-bit mode width, then the specified register can not be accessed + // + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) { + return EFI_INVALID_PARAMETER; + } + + // + // Write return buffer + // + ASSERT(CpuSaveState != NULL); + CopyMem(Buffer, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset32, Width); + } else { + // + // If 64-bit mode width is zero, then the specified register can not be accessed + // + if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 64-bit mode width, then the specified register can not be accessed + // + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) { + return EFI_INVALID_PARAMETER; + } + + // + // Write lower 32-bits of return buffer + // + CopyMem(Buffer, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, MIN(4, Width)); + if (Width >= 4) { + // + // Write upper 32-bits of return buffer + // + CopyMem((UINT8 *)Buffer + 4, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4); + } + } + return EFI_SUCCESS; +} + +/** + Read a CPU Save State register on the target processor. + + This function abstracts the differences that whether the CPU Save State register is in the + IA32 CPU Save State Map or X64 CPU Save State Map. + + This function supports reading a CPU Save State register in SMBase relocation handler. + + @param[in] CpuIndex Specifies the zero-based index of the CPU save state. + @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. + @param[in] Width The number of bytes to read from the CPU save state. + @param[out] 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 +ReadSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + OUT VOID *Buffer + ) +{ + UINT32 SmmRevId; + SMRAM_SAVE_STATE_IOMISC IoMisc; + EFI_SMM_SAVE_STATE_IO_INFO *IoInfo; + + // + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) { + // + // Only byte access is supported for this register + // + if (Width != 1) { + return EFI_INVALID_PARAMETER; + } + + *(UINT8 *)Buffer = mSmmSaveStateRegisterLma; + + return EFI_SUCCESS; + } + + // + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) { + // + // Get SMM Revision ID + // + ReadSaveStateRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX, sizeof(SmmRevId), &SmmRevId); + + // + // See if the CPU supports the IOMisc register in the save state + // + if (SmmRevId < SMRAM_SAVE_STATE_MIN_REV_ID_IOMISC) { + return EFI_NOT_FOUND; + } + + // + // Get the IOMisc register value + // + ReadSaveStateRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_IOMISC_INDEX, sizeof(IoMisc.Uint32), &IoMisc.Uint32); + + // + // Check for the SMI_FLAG in IOMisc + // + if (IoMisc.Bits.SmiFlag == 0) { + return EFI_NOT_FOUND; + } + + // + // Only support IN/OUT, but not INS/OUTS/REP INS/REP OUTS. + // + if ((mSmmCpuIoType[IoMisc.Bits.Type] != EFI_SMM_SAVE_STATE_IO_TYPE_INPUT) && + (mSmmCpuIoType[IoMisc.Bits.Type] != EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) { + return EFI_NOT_FOUND; + } + + // + // Compute index for the I/O Length and I/O Type lookup tables + // + if (mSmmCpuIoWidth[IoMisc.Bits.Length].Width == 0 || mSmmCpuIoType[IoMisc.Bits.Type] == 0) { + return EFI_NOT_FOUND; + } + + // + // Zero the IoInfo structure that will be returned in Buffer + // + IoInfo = (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer; + ZeroMem (IoInfo, sizeof(EFI_SMM_SAVE_STATE_IO_INFO)); + + // + // Use lookup tables to help fill in all the fields of the IoInfo structure + // + IoInfo->IoPort = (UINT16)IoMisc.Bits.Port; + IoInfo->IoWidth = mSmmCpuIoWidth[IoMisc.Bits.Length].IoWidth; + IoInfo->IoType = mSmmCpuIoType[IoMisc.Bits.Type]; + ReadSaveStateRegister (CpuIndex, EFI_SMM_SAVE_STATE_REGISTER_RAX, mSmmCpuIoWidth[IoMisc.Bits.Length].Width, &IoInfo->IoData); + return EFI_SUCCESS; + } + + // + // Convert Register to a register lookup table index + // + return ReadSaveStateRegisterByIndex (CpuIndex, GetRegisterIndex (Register), Width, Buffer); +} + +/** + Write value to a CPU Save State register on the target processor. + + This function abstracts the differences that whether the CPU Save State register is in the + IA32 CPU Save State Map or X64 CPU Save State Map. + + This function supports writing a CPU Save State register in SMBase relocation handler. + + @param[in] CpuIndex Specifies the zero-based index of the CPU save state. + @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. + @param[in] Width The number of bytes to read from the CPU save state. + @param[in] Buffer Upon entry, this holds the new CPU register value. + + @retval EFI_SUCCESS The register was written to 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 +WriteSaveStateRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + IN CONST VOID *Buffer + ) +{ + UINTN RegisterIndex; + SMRAM_SAVE_STATE_MAP *CpuSaveState; + + // + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) { + return EFI_SUCCESS; + } + + // + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported + // + if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) { + return EFI_NOT_FOUND; + } + + // + // Convert Register to a register lookup table index + // + RegisterIndex = GetRegisterIndex (Register); + if (RegisterIndex == 0) { + return EFI_NOT_FOUND; + } + + CpuSaveState = gSmst->CpuSaveState[CpuIndex]; + + // + // Do not write non-writable SaveState, because it will cause exception. + // + if (!mSmmCpuWidthOffset[RegisterIndex].Writeable) { + return EFI_UNSUPPORTED; + } + + // + // Check CPU mode + // + if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { + // + // If 32-bit mode width is zero, then the specified register can not be accessed + // + if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 32-bit mode width, then the specified register can not be accessed + // + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) { + return EFI_INVALID_PARAMETER; + } + // + // Write SMM State register + // + ASSERT (CpuSaveState != NULL); + CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset32, Buffer, Width); + } else { + // + // If 64-bit mode width is zero, then the specified register can not be accessed + // + if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 64-bit mode width, then the specified register can not be accessed + // + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) { + return EFI_INVALID_PARAMETER; + } + + // + // Write lower 32-bits of SMM State register + // + CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, Buffer, MIN (4, Width)); + if (Width >= 4) { + // + // Write upper 32-bits of SMM State register + // + CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, (UINT8 *)Buffer + 4, Width - 4); + } + } + return EFI_SUCCESS; +} + +/** + Hook the code executed immediately after an RSM instruction on the currently + executing CPU. The mode of code executed immediately after RSM must be + detected, and the appropriate hook must be selected. Always clear the auto + HALT restart flag if it is set. + + @param[in] CpuIndex The processor index for the currently + executing CPU. + @param[in] CpuState Pointer to SMRAM Save State Map for the + currently executing CPU. + @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to + 32-bit mode from 64-bit SMM. + @param[in] NewInstructionPointer Instruction pointer to use if resuming to + same mode as SMM. + + @retval The value of the original instruction pointer before it was hooked. + +**/ +UINT64 +EFIAPI +HookReturnFromSmm ( + IN UINTN CpuIndex, + SMRAM_SAVE_STATE_MAP *CpuState, + UINT64 NewInstructionPointer32, + UINT64 NewInstructionPointer + ) +{ + UINT64 OriginalInstructionPointer; + + OriginalInstructionPointer = SmmCpuFeaturesHookReturnFromSmm ( + CpuIndex, + CpuState, + NewInstructionPointer32, + NewInstructionPointer + ); + if (OriginalInstructionPointer != 0) { + return OriginalInstructionPointer; + } + + if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { + OriginalInstructionPointer = (UINT64)CpuState->x86._EIP; + CpuState->x86._EIP = (UINT32)NewInstructionPointer; + // + // Clear the auto HALT restart flag so the RSM instruction returns + // program control to the instruction following the HLT instruction. + // + if ((CpuState->x86.AutoHALTRestart & BIT0) != 0) { + CpuState->x86.AutoHALTRestart &= ~BIT0; + } + } else { + OriginalInstructionPointer = CpuState->x64._RIP; + if ((CpuState->x64.IA32_EFER & LMA) == 0) { + CpuState->x64._RIP = (UINT32)NewInstructionPointer32; + } else { + CpuState->x64._RIP = (UINT32)NewInstructionPointer; + } + // + // Clear the auto HALT restart flag so the RSM instruction returns + // program control to the instruction following the HLT instruction. + // + if ((CpuState->x64.AutoHALTRestart & BIT0) != 0) { + CpuState->x64.AutoHALTRestart &= ~BIT0; + } + } + return OriginalInstructionPointer; +} + +/** + Get the size of the SMI Handler in bytes. + + @retval The size, in bytes, of the SMI Handler. + +**/ +UINTN +EFIAPI +GetSmiHandlerSize ( + VOID + ) +{ + UINTN Size; + + Size = SmmCpuFeaturesGetSmiHandlerSize (); + if (Size != 0) { + return Size; + } + return gcSmiHandlerSize; +} + +/** + Install the SMI handler for the CPU specified by CpuIndex. This function + is called by the CPU that was elected as monarch during System Management + Mode initialization. + + @param[in] CpuIndex The index of the CPU to install the custom SMI handler. + The value must be between 0 and the NumberOfCpus field + in the System Management System Table (SMST). + @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. + @param[in] SmiStack The stack to use when an SMI is processed by the + the CPU specified by CpuIndex. + @param[in] StackSize The size, in bytes, if the stack used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtBase The base address of the GDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtBase The base address of the IDT to use when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is + processed by the CPU specified by CpuIndex. + @param[in] Cr3 The base address of the page tables to use when an SMI + is processed by the CPU specified by CpuIndex. +**/ +VOID +EFIAPI +InstallSmiHandler ( + IN UINTN CpuIndex, + IN UINT32 SmBase, + IN VOID *SmiStack, + IN UINTN StackSize, + IN UINTN GdtBase, + IN UINTN GdtSize, + IN UINTN IdtBase, + IN UINTN IdtSize, + IN UINT32 Cr3 + ) +{ + PROCESSOR_SMM_DESCRIPTOR *Psd; + UINT32 CpuSmiStack; + + // + // Initialize PROCESSOR_SMM_DESCRIPTOR + // + Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)((UINTN)SmBase + SMM_PSD_OFFSET); + CopyMem (Psd, &gcPsd, sizeof (gcPsd)); + Psd->SmmGdtPtr = (UINT64)GdtBase; + Psd->SmmGdtSize = (UINT32)GdtSize; + + if (SmmCpuFeaturesGetSmiHandlerSize () != 0) { + // + // Install SMI handler provided by library + // + SmmCpuFeaturesInstallSmiHandler ( + CpuIndex, + SmBase, + SmiStack, + StackSize, + GdtBase, + GdtSize, + IdtBase, + IdtSize, + Cr3 + ); + return; + } + + InitShadowStack (CpuIndex, (VOID *)((UINTN)SmiStack + StackSize)); + + // + // Initialize values in template before copy + // + CpuSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN)); + PatchInstructionX86 (gPatchSmiStack, CpuSmiStack, 4); + PatchInstructionX86 (gPatchSmiCr3, Cr3, 4); + PatchInstructionX86 (gPatchSmbase, SmBase, 4); + gSmiHandlerIdtr.Base = IdtBase; + gSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1); + + // + // Set the value at the top of the CPU stack to the CPU Index + // + *(UINTN*)(UINTN)CpuSmiStack = CpuIndex; + + // + // Copy template to CPU specific SMI handler location + // + CopyMem ( + (VOID*)((UINTN)SmBase + SMM_HANDLER_OFFSET), + (VOID*)gcSmiHandlerTemplate, + gcSmiHandlerSize + ); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c new file mode 100644 index 000000000..096ab323b --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -0,0 +1,110 @@ +/** @file +SMM Timer feature support + +Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +UINT64 mTimeoutTicker = 0; +// +// Number of counts in a roll-over cycle of the performance counter. +// +UINT64 mCycle = 0; +// +// Flag to indicate the performance counter is count-up or count-down. +// +BOOLEAN mCountDown; + +/** + Initialize Timer for SMM AP Sync. + +**/ +VOID +InitializeSmmTimer ( + VOID + ) +{ + UINT64 TimerFrequency; + UINT64 Start; + UINT64 End; + + TimerFrequency = GetPerformanceCounterProperties (&Start, &End); + mTimeoutTicker = DivU64x32 ( + MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), + 1000 * 1000 + ); + if (End < Start) { + mCountDown = TRUE; + mCycle = Start - End; + } else { + mCountDown = FALSE; + mCycle = End - Start; + } +} + +/** + Start Timer for SMM AP Sync. + +**/ +UINT64 +EFIAPI +StartSyncTimer ( + VOID + ) +{ + return GetPerformanceCounter (); +} + + +/** + Check if the SMM AP Sync timer is timeout. + + @param Timer The start timer from the begin. + +**/ +BOOLEAN +EFIAPI +IsSyncTimerTimeout ( + IN UINT64 Timer + ) +{ + UINT64 CurrentTimer; + UINT64 Delta; + + CurrentTimer = GetPerformanceCounter (); + // + // We need to consider the case that CurrentTimer is equal to Timer + // when some timer runs too slow and CPU runs fast. We think roll over + // condition does not happen on this case. + // + if (mCountDown) { + // + // The performance counter counts down. Check for roll over condition. + // + if (CurrentTimer <= Timer) { + Delta = Timer - CurrentTimer; + } else { + // + // Handle one roll-over. + // + Delta = mCycle - (CurrentTimer - Timer) + 1; + } + } else { + // + // The performance counter counts up. Check for roll over condition. + // + if (CurrentTimer >= Timer) { + Delta = CurrentTimer - Timer; + } else { + // + // Handle one roll-over. + // + Delta = mCycle - (Timer - CurrentTimer) + 1; + } + } + + return (BOOLEAN) (Delta >= mTimeoutTicker); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Cet.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Cet.nasm new file mode 100644 index 000000000..3240f9d97 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Cet.nasm @@ -0,0 +1,34 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------- + +%include "Nasm.inc" + +DEFAULT REL +SECTION .text + +global ASM_PFX(DisableCet) +ASM_PFX(DisableCet): + + ; Skip the pushed data for call + mov rax, 1 + INCSSP_RAX + + mov rax, cr4 + btr eax, 23 ; clear CET + mov cr4, rax + ret + +global ASM_PFX(EnableCet) +ASM_PFX(EnableCet): + + mov rax, cr4 + bts eax, 23 ; set CET + mov cr4, rax + + ; use jmp to skip the check for ret + pop rax + jmp rax + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm new file mode 100644 index 000000000..a12538f72 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm @@ -0,0 +1,189 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; MpFuncs.nasm +; +; Abstract: +; +; This is the assembly code for Multi-processor S3 support +; +;------------------------------------------------------------------------------- + +%define VacantFlag 0x0 +%define NotVacantFlag 0xff + +%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart +%define StackStartAddressLocation LockLocation + 0x8 +%define StackSizeLocation LockLocation + 0x10 +%define CProcedureLocation LockLocation + 0x18 +%define GdtrLocation LockLocation + 0x20 +%define IdtrLocation LockLocation + 0x2A +%define BufferStartLocation LockLocation + 0x34 +%define Cr3OffsetLocation LockLocation + 0x38 +%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C + +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc procedure follows. All APs execute their procedure. This +;procedure serializes all the AP processors through an Init sequence. It must be +;noted that APs arrive here very raw...ie: real mode, no stack. +;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC +;IS IN MACHINE CODE. +;------------------------------------------------------------------------------------- +;RendezvousFunnelProc (&WakeUpBuffer,MemAddress); + +;text SEGMENT +DEFAULT REL +SECTION .text + +BITS 16 +global ASM_PFX(RendezvousFunnelProc) +ASM_PFX(RendezvousFunnelProc): +RendezvousFunnelProcStart: + +; At this point CS = 0x(vv00) and ip= 0x0. + + mov ax, cs + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + +flat32Start: + + mov si, BufferStartLocation + mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer + + mov si, Cr3OffsetLocation + mov ecx,dword [si] ; ECX is keeping the value of CR3 + + mov si, GdtrLocation +o32 lgdt [cs:si] + + mov si, IdtrLocation +o32 lidt [cs:si] + + xor ax, ax + mov ds, ax + + mov eax, cr0 ; Get control register 0 + or eax, 0x000000001 ; Set PE bit (bit #0) + mov cr0, eax + +FLAT32_JUMP: + +a32 jmp dword 0x20:0x0 + +BITS 32 +PMODE_ENTRY: ; protected mode entry point + + mov ax, 0x18 +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax ; Flat mode setup. + + mov eax, cr4 + bts eax, 5 + mov cr4, eax + + mov cr3, ecx + + mov esi, edx ; Save wakeup buffer address + + mov ecx, 0xc0000080 ; EFER MSR number. + rdmsr ; Read EFER. + bts eax, 8 ; Set LME=1. + wrmsr ; Write EFER. + + mov eax, cr0 ; Read CR0. + bts eax, 31 ; Set PG=1. + mov cr0, eax ; Write CR0. + +LONG_JUMP: + +a16 jmp dword 0x38:0x0 + +BITS 64 +LongModeStart: + + mov ax, 0x30 +o16 mov ds, ax +o16 mov es, ax +o16 mov ss, ax + + mov edi, esi + add edi, LockLocation + mov al, NotVacantFlag +TestLock: + xchg byte [edi], al + cmp al, NotVacantFlag + jz TestLock + +ProgramStack: + + mov edi, esi + add edi, StackSizeLocation + mov rax, qword [edi] + mov edi, esi + add edi, StackStartAddressLocation + add rax, qword [edi] + mov rsp, rax + mov qword [edi], rax + +Releaselock: + + mov al, VacantFlag + mov edi, esi + add edi, LockLocation + xchg byte [edi], al + + ; + ; Call assembly function to initialize FPU. + ; + mov rax, qword [esi + InitializeFloatingPointUnitsAddress] + sub rsp, 0x20 + call rax + add rsp, 0x20 + + ; + ; Call C Function + ; + mov edi, esi + add edi, CProcedureLocation + mov rax, qword [edi] + + test rax, rax + jz GoToSleep + + sub rsp, 0x20 + call rax + add rsp, 0x20 + +GoToSleep: + cli + hlt + jmp $-2 + +RendezvousFunnelProcEnd: + +;------------------------------------------------------------------------------------- +; AsmGetAddressMap (&AddressMap); +;------------------------------------------------------------------------------------- +; comments here for definition of address map +global ASM_PFX(AsmGetAddressMap) +ASM_PFX(AsmGetAddressMap): + lea rax, [RendezvousFunnelProcStart] + mov qword [rcx], rax + mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart + mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart + mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart + mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart + mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart + ret + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c new file mode 100644 index 000000000..810985df2 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c @@ -0,0 +1,1285 @@ +/** @file +Page Fault (#PF) handler for X64 processors + +Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +#define PAGE_TABLE_PAGES 8 +#define ACC_MAX_BIT BIT3 + +LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool); +BOOLEAN m1GPageTableSupport = FALSE; +BOOLEAN mCpuSmmRestrictedMemoryAccess; +BOOLEAN m5LevelPagingNeeded; +X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingNeeded; + +/** + Disable CET. +**/ +VOID +EFIAPI +DisableCet ( + VOID + ); + +/** + Enable CET. +**/ +VOID +EFIAPI +EnableCet ( + VOID + ); + +/** + Check if 1-GByte pages is supported by processor or not. + + @retval TRUE 1-GByte pages is supported. + @retval FALSE 1-GByte pages is not supported. + +**/ +BOOLEAN +Is1GPageSupport ( + VOID + ) +{ + UINT32 RegEax; + UINT32 RegEdx; + + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + return TRUE; + } + } + return FALSE; +} + +/** + The routine returns TRUE when CPU supports it (CPUID[7,0].ECX.BIT[16] is set) and + the max physical address bits is bigger than 48. Because 4-level paging can support + to address physical address up to 2^48 - 1, there is no need to enable 5-level paging + with max physical address bits <= 48. + + @retval TRUE 5-level paging enabling is needed. + @retval FALSE 5-level paging enabling is not needed. +**/ +BOOLEAN +Is5LevelPagingNeeded ( + VOID + ) +{ + CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX ExtFeatureEcx; + UINT32 MaxExtendedFunctionId; + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL); + if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL); + } else { + VirPhyAddressSize.Bits.PhysicalAddressBits = 36; + } + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + NULL, NULL, &ExtFeatureEcx.Uint32, NULL + ); + DEBUG (( + DEBUG_INFO, "PhysicalAddressBits = %d, 5LPageTable = %d.\n", + VirPhyAddressSize.Bits.PhysicalAddressBits, ExtFeatureEcx.Bits.FiveLevelPage + )); + + if (VirPhyAddressSize.Bits.PhysicalAddressBits > 4 * 9 + 12) { + ASSERT (ExtFeatureEcx.Bits.FiveLevelPage == 1); + return TRUE; + } else { + return FALSE; + } +} + +/** + 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 + ) +{ + // + // Sub-entries number is saved in BIT52 to BIT60 (reserved field) in Entry + // + *Entry = BitFieldWrite64 (*Entry, 52, 60, 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 + ) +{ + // + // Sub-entries number is saved in BIT52 to BIT60 (reserved field) in Entry + // + return BitFieldRead64 (*Entry, 52, 60); +} + +/** + Calculate the maximum support address. + + @return the maximum support address. +**/ +UINT8 +CalculateMaximumSupportAddress ( + 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 (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + PhysicalAddressBits = (UINT8) RegEax; + } else { + PhysicalAddressBits = 36; + } + } + return PhysicalAddressBits; +} + +/** + Set static page table. + + @param[in] PageTable Address of page table. +**/ +VOID +SetStaticPageTable ( + IN UINTN PageTable + ) +{ + UINT64 PageAddress; + UINTN NumberOfPml5EntriesNeeded; + UINTN NumberOfPml4EntriesNeeded; + UINTN NumberOfPdpEntriesNeeded; + UINTN IndexOfPml5Entries; + UINTN IndexOfPml4Entries; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + UINT64 *PageMapLevel5Entry; + UINT64 *PageMapLevel4Entry; + UINT64 *PageMap; + UINT64 *PageDirectoryPointerEntry; + UINT64 *PageDirectory1GEntry; + UINT64 *PageDirectoryEntry; + + // + // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses + // when 5-Level Paging is disabled. + // + ASSERT (mPhysicalAddressBits <= 52); + if (!m5LevelPagingNeeded && mPhysicalAddressBits > 48) { + mPhysicalAddressBits = 48; + } + + NumberOfPml5EntriesNeeded = 1; + if (mPhysicalAddressBits > 48) { + NumberOfPml5EntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 48); + mPhysicalAddressBits = 48; + } + + NumberOfPml4EntriesNeeded = 1; + if (mPhysicalAddressBits > 39) { + NumberOfPml4EntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 39); + mPhysicalAddressBits = 39; + } + + NumberOfPdpEntriesNeeded = 1; + ASSERT (mPhysicalAddressBits > 30); + NumberOfPdpEntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 30); + + // + // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. + // + PageMap = (VOID *) PageTable; + + PageMapLevel4Entry = PageMap; + PageMapLevel5Entry = NULL; + if (m5LevelPagingNeeded) { + // + // By architecture only one PageMapLevel5 exists - so lets allocate storage for it. + // + PageMapLevel5Entry = PageMap; + } + PageAddress = 0; + + for ( IndexOfPml5Entries = 0 + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries++, PageMapLevel5Entry++) { + // + // Each PML5 entry points to a page of PML4 entires. + // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop. + // When 5-Level Paging is disabled, below allocation happens only once. + // + if (m5LevelPagingNeeded) { + PageMapLevel4Entry = (UINT64 *) ((*PageMapLevel5Entry) & ~mAddressEncMask & gPhyMask); + if (PageMapLevel4Entry == NULL) { + PageMapLevel4Entry = AllocatePageTableMemory (1); + ASSERT(PageMapLevel4Entry != NULL); + ZeroMem (PageMapLevel4Entry, EFI_PAGES_TO_SIZE(1)); + + *PageMapLevel5Entry = (UINT64)(UINTN)PageMapLevel4Entry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + } + + for (IndexOfPml4Entries = 0; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512); IndexOfPml4Entries++, PageMapLevel4Entry++) { + // + // Each PML4 entry points to a page of Page Directory Pointer entries. + // + PageDirectoryPointerEntry = (UINT64 *) ((*PageMapLevel4Entry) & ~mAddressEncMask & gPhyMask); + if (PageDirectoryPointerEntry == NULL) { + PageDirectoryPointerEntry = AllocatePageTableMemory (1); + ASSERT(PageDirectoryPointerEntry != NULL); + ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1)); + + *PageMapLevel4Entry = (UINT64)(UINTN)PageDirectoryPointerEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + + if (m1GPageTableSupport) { + PageDirectory1GEntry = PageDirectoryPointerEntry; + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { + if (IndexOfPml4Entries == 0 && IndexOfPageDirectoryEntries < 4) { + // + // Skip the < 4G entries + // + continue; + } + // + // Fill in the Page Directory entries + // + *PageDirectory1GEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS; + } + } else { + PageAddress = BASE_4GB; + for (IndexOfPdpEntries = 0; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512); IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + if (IndexOfPml4Entries == 0 && IndexOfPdpEntries < 4) { + // + // Skip the < 4G entries + // + continue; + } + // + // 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 = (UINT64 *) ((*PageDirectoryPointerEntry) & ~mAddressEncMask & gPhyMask); + if (PageDirectoryEntry == NULL) { + PageDirectoryEntry = AllocatePageTableMemory (1); + ASSERT(PageDirectoryEntry != NULL); + ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1)); + + // + // Fill in a Page Directory Pointer Entries + // + *PageDirectoryPointerEntry = (UINT64)(UINTN)PageDirectoryEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { + // + // Fill in the Page Directory entries + // + *PageDirectoryEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS; + } + } + } + } + } +} + +/** + Create PageTable for SMM use. + + @return The address of PML4 (to set CR3). + +**/ +UINT32 +SmmInitPageTable ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS Pages; + UINT64 *PTEntry; + LIST_ENTRY *FreePage; + UINTN Index; + UINTN PageFaultHandlerHookAddress; + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + EFI_STATUS Status; + UINT64 *Pml4Entry; + UINT64 *Pml5Entry; + + // + // Initialize spin lock + // + InitializeSpinLock (mPFLock); + + mCpuSmmRestrictedMemoryAccess = PcdGetBool (PcdCpuSmmRestrictedMemoryAccess); + m1GPageTableSupport = Is1GPageSupport (); + m5LevelPagingNeeded = Is5LevelPagingNeeded (); + mPhysicalAddressBits = CalculateMaximumSupportAddress (); + PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, 1); + 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 PAE page table for the first 4GB memory space + // + Pages = Gen4GPageTable (FALSE); + + // + // Set IA32_PG_PMNT bit to mask this entry + // + PTEntry = (UINT64*)(UINTN)Pages; + for (Index = 0; Index < 4; Index++) { + PTEntry[Index] |= IA32_PG_PMNT; + } + + // + // Fill Page-Table-Level4 (PML4) entry + // + Pml4Entry = (UINT64*)AllocatePageTableMemory (1); + ASSERT (Pml4Entry != NULL); + *Pml4Entry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + ZeroMem (Pml4Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml4Entry)); + + // + // Set sub-entries number + // + SetSubEntriesNum (Pml4Entry, 3); + PTEntry = Pml4Entry; + + if (m5LevelPagingNeeded) { + // + // Fill PML5 entry + // + Pml5Entry = (UINT64*)AllocatePageTableMemory (1); + ASSERT (Pml5Entry != NULL); + *Pml5Entry = (UINTN) Pml4Entry | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + ZeroMem (Pml5Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml5Entry)); + // + // Set sub-entries number + // + SetSubEntriesNum (Pml5Entry, 1); + PTEntry = Pml5Entry; + } + + if (mCpuSmmRestrictedMemoryAccess) { + // + // When access to non-SMRAM memory is restricted, create page table + // that covers all memory space. + // + SetStaticPageTable ((UINTN)PTEntry); + } else { + // + // Add pages to page pool + // + FreePage = (LIST_ENTRY*)AllocatePageTableMemory (PAGE_TABLE_PAGES); + ASSERT (FreePage != NULL); + for (Index = 0; Index < PAGE_TABLE_PAGES; Index++) { + InsertTailList (&mPagePool, FreePage); + FreePage += EFI_PAGE_SIZE / sizeof (*FreePage); + } + } + + if (FeaturePcdGet (PcdCpuSmmProfileEnable) || + HEAP_GUARD_NONSTOP_MODE || + NULL_DETECTION_NONSTOP_MODE) { + // + // Set own Page Fault entry instead of the default one, because SMM Profile + // feature depends on IRET instruction to do Single Step + // + PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile; + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base; + IdtEntry += EXCEPT_IA32_PAGE_FAULT; + IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress; + IdtEntry->Bits.Reserved_0 = 0; + IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; + IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16); + IdtEntry->Bits.OffsetUpper = (UINT32)(PageFaultHandlerHookAddress >> 32); + IdtEntry->Bits.Reserved_1 = 0; + } else { + // + // Register Smm Page Fault Handler + // + Status = SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler); + ASSERT_EFI_ERROR (Status); + } + + // + // Additional SMM IDT initialization for SMM stack guard + // + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + InitializeIDTSmmStackGuard (); + } + + // + // Return the address of PML4/PML5 (to set CR3) + // + return (UINT32)(UINTN)PTEntry; +} + +/** + 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 + ) +{ + // + // Access record is saved in BIT9 to BIT11 (reserved field) in Entry + // + *Entry = BitFieldWrite64 (*Entry, 9, 11, Acc); +} + +/** + Return access record in entry. + + @param[in] Entry Pointer to entry + + @return Access record value. + +**/ +UINT64 +GetAccNum ( + IN UINT64 *Entry + ) +{ + // + // Access record is saved in BIT9 to BIT11 (reserved field) in Entry + // + return BitFieldRead64 (*Entry, 9, 11); +} + +/** + Return and update the access record in entry. + + @param[in, out] Entry Pointer to entry + + @return Access record value. + +**/ +UINT64 +GetAndUpdateAccNum ( + IN OUT UINT64 *Entry + ) +{ + UINT64 Acc; + + Acc = GetAccNum (Entry); + if ((*Entry & IA32_PG_A) != 0) { + // + // If this entry has been accessed, clear access flag in Entry and update access record + // to the initial value 7, adding ACC_MAX_BIT is to make it larger than others + // + *Entry &= ~(UINT64)(UINTN)IA32_PG_A; + SetAccNum (Entry, 0x7); + return (0x7 + ACC_MAX_BIT); + } else { + if (Acc != 0) { + // + // If the access record is not the smallest value 0, minus 1 and update the access record field + // + SetAccNum (Entry, Acc - 1); + } + } + return Acc; +} + +/** + Reclaim free pages for PageFault handler. + + Search the whole entries tree to find the leaf entry that has the smallest + access record value. Insert the page pointed by this leaf entry into the + page pool. And check its upper entries if need to be inserted into the page + pool or not. + +**/ +VOID +ReclaimPages ( + VOID + ) +{ + UINT64 Pml5Entry; + UINT64 *Pml5; + UINT64 *Pml4; + UINT64 *Pdpt; + UINT64 *Pdt; + UINTN Pml5Index; + UINTN Pml4Index; + UINTN PdptIndex; + UINTN PdtIndex; + UINTN MinPml5; + UINTN MinPml4; + UINTN MinPdpt; + UINTN MinPdt; + UINT64 MinAcc; + UINT64 Acc; + UINT64 SubEntriesNum; + BOOLEAN PML4EIgnore; + BOOLEAN PDPTEIgnore; + UINT64 *ReleasePageAddress; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + UINT64 PFAddress; + UINT64 PFAddressPml5Index; + UINT64 PFAddressPml4Index; + UINT64 PFAddressPdptIndex; + UINT64 PFAddressPdtIndex; + + Pml4 = NULL; + Pdpt = NULL; + Pdt = NULL; + MinAcc = (UINT64)-1; + MinPml4 = (UINTN)-1; + MinPml5 = (UINTN)-1; + MinPdpt = (UINTN)-1; + MinPdt = (UINTN)-1; + Acc = 0; + ReleasePageAddress = 0; + PFAddress = AsmReadCr2 (); + PFAddressPml5Index = BitFieldRead64 (PFAddress, 48, 48 + 8); + PFAddressPml4Index = BitFieldRead64 (PFAddress, 39, 39 + 8); + PFAddressPdptIndex = BitFieldRead64 (PFAddress, 30, 30 + 8); + PFAddressPdtIndex = BitFieldRead64 (PFAddress, 21, 21 + 8); + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + Pml5 = (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask); + + if (!Enable5LevelPaging) { + // + // Create one fake PML5 entry for 4-Level Paging + // so that the page table parsing logic only handles 5-Level page structure. + // + Pml5Entry = (UINTN) Pml5 | IA32_PG_P; + Pml5 = &Pml5Entry; + } + + // + // First, find the leaf entry has the smallest access record value + // + for (Pml5Index = 0; Pml5Index < (Enable5LevelPaging ? (EFI_PAGE_SIZE / sizeof (*Pml4)) : 1); Pml5Index++) { + if ((Pml5[Pml5Index] & IA32_PG_P) == 0 || (Pml5[Pml5Index] & IA32_PG_PMNT) != 0) { + // + // If the PML5 entry is not present or is masked, skip it + // + continue; + } + Pml4 = (UINT64*)(UINTN)(Pml5[Pml5Index] & gPhyMask); + for (Pml4Index = 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); Pml4Index++) { + if ((Pml4[Pml4Index] & IA32_PG_P) == 0 || (Pml4[Pml4Index] & IA32_PG_PMNT) != 0) { + // + // If the PML4 entry is not present or is masked, skip it + // + continue; + } + Pdpt = (UINT64*)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & gPhyMask); + PML4EIgnore = FALSE; + for (PdptIndex = 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt); PdptIndex++) { + if ((Pdpt[PdptIndex] & IA32_PG_P) == 0 || (Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) { + // + // If the PDPT entry is not present or is masked, skip it + // + if ((Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) { + // + // If the PDPT entry is masked, we will ignore checking the PML4 entry + // + PML4EIgnore = TRUE; + } + continue; + } + if ((Pdpt[PdptIndex] & IA32_PG_PS) == 0) { + // + // It's not 1-GByte pages entry, it should be a PDPT entry, + // we will not check PML4 entry more + // + PML4EIgnore = TRUE; + Pdt = (UINT64*)(UINTN)(Pdpt[PdptIndex] & ~mAddressEncMask & gPhyMask); + PDPTEIgnore = FALSE; + for (PdtIndex = 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt); PdtIndex++) { + if ((Pdt[PdtIndex] & IA32_PG_P) == 0 || (Pdt[PdtIndex] & IA32_PG_PMNT) != 0) { + // + // If the PD entry is not present or is masked, skip it + // + if ((Pdt[PdtIndex] & IA32_PG_PMNT) != 0) { + // + // If the PD entry is masked, we will not PDPT entry more + // + PDPTEIgnore = TRUE; + } + continue; + } + if ((Pdt[PdtIndex] & IA32_PG_PS) == 0) { + // + // It's not 2 MByte page table entry, it should be PD entry + // we will find the entry has the smallest access record value + // + PDPTEIgnore = TRUE; + if (PdtIndex != PFAddressPdtIndex || PdptIndex != PFAddressPdptIndex || + Pml4Index != PFAddressPml4Index || Pml5Index != PFAddressPml5Index) { + Acc = GetAndUpdateAccNum (Pdt + PdtIndex); + if (Acc < MinAcc) { + // + // If the PD entry has the smallest access record value, + // save the Page address to be released + // + MinAcc = Acc; + MinPml5 = Pml5Index; + MinPml4 = Pml4Index; + MinPdpt = PdptIndex; + MinPdt = PdtIndex; + ReleasePageAddress = Pdt + PdtIndex; + } + } + } + } + if (!PDPTEIgnore) { + // + // If this PDPT entry has no PDT entries pointer to 4 KByte pages, + // it should only has the entries point to 2 MByte Pages + // + if (PdptIndex != PFAddressPdptIndex || Pml4Index != PFAddressPml4Index || + Pml5Index != PFAddressPml5Index) { + Acc = GetAndUpdateAccNum (Pdpt + PdptIndex); + if (Acc < MinAcc) { + // + // If the PDPT entry has the smallest access record value, + // save the Page address to be released + // + MinAcc = Acc; + MinPml5 = Pml5Index; + MinPml4 = Pml4Index; + MinPdpt = PdptIndex; + MinPdt = (UINTN)-1; + ReleasePageAddress = Pdpt + PdptIndex; + } + } + } + } + } + if (!PML4EIgnore) { + // + // If PML4 entry has no the PDPT entry pointer to 2 MByte pages, + // it should only has the entries point to 1 GByte Pages + // + if (Pml4Index != PFAddressPml4Index || Pml5Index != PFAddressPml5Index) { + Acc = GetAndUpdateAccNum (Pml4 + Pml4Index); + if (Acc < MinAcc) { + // + // If the PML4 entry has the smallest access record value, + // save the Page address to be released + // + MinAcc = Acc; + MinPml5 = Pml5Index; + MinPml4 = Pml4Index; + MinPdpt = (UINTN)-1; + MinPdt = (UINTN)-1; + ReleasePageAddress = Pml4 + Pml4Index; + } + } + } + } + } + // + // Make sure one PML4/PDPT/PD entry is selected + // + ASSERT (MinAcc != (UINT64)-1); + + // + // Secondly, insert the page pointed by this entry into page pool and clear this entry + // + InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(*ReleasePageAddress & ~mAddressEncMask & gPhyMask)); + *ReleasePageAddress = 0; + + // + // Lastly, check this entry's upper entries if need to be inserted into page pool + // or not + // + while (TRUE) { + if (MinPdt != (UINTN)-1) { + // + // If 4 KByte Page Table is released, check the PDPT entry + // + Pml4 = (UINT64 *) (UINTN) (Pml5[MinPml5] & gPhyMask); + Pdpt = (UINT64*)(UINTN)(Pml4[MinPml4] & ~mAddressEncMask & gPhyMask); + SubEntriesNum = GetSubEntriesNum(Pdpt + MinPdpt); + if (SubEntriesNum == 0 && + (MinPdpt != PFAddressPdptIndex || MinPml4 != PFAddressPml4Index || MinPml5 != PFAddressPml5Index)) { + // + // Release the empty Page Directory table if there was no more 4 KByte Page Table entry + // clear the Page directory entry + // + InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(Pdpt[MinPdpt] & ~mAddressEncMask & gPhyMask)); + Pdpt[MinPdpt] = 0; + // + // Go on checking the PML4 table + // + MinPdt = (UINTN)-1; + continue; + } + // + // Update the sub-entries filed in PDPT entry and exit + // + SetSubEntriesNum (Pdpt + MinPdpt, (SubEntriesNum - 1) & 0x1FF); + break; + } + if (MinPdpt != (UINTN)-1) { + // + // One 2MB Page Table is released or Page Directory table is released, check the PML4 entry + // + SubEntriesNum = GetSubEntriesNum (Pml4 + MinPml4); + if (SubEntriesNum == 0 && (MinPml4 != PFAddressPml4Index || MinPml5 != PFAddressPml5Index)) { + // + // Release the empty PML4 table if there was no more 1G KByte Page Table entry + // clear the Page directory entry + // + InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(Pml4[MinPml4] & ~mAddressEncMask & gPhyMask)); + Pml4[MinPml4] = 0; + MinPdpt = (UINTN)-1; + continue; + } + // + // Update the sub-entries filed in PML4 entry and exit + // + SetSubEntriesNum (Pml4 + MinPml4, (SubEntriesNum - 1) & 0x1FF); + break; + } + // + // PLM4 table has been released before, exit it + // + break; + } +} + +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ) +{ + UINT64 RetVal; + + if (IsListEmpty (&mPagePool)) { + // + // If page pool is empty, reclaim the used pages and insert one into page pool + // + ReclaimPages (); + } + + // + // Get one free page and remove it from page pool + // + RetVal = (UINT64)(UINTN)mPagePool.ForwardLink; + RemoveEntryList (mPagePool.ForwardLink); + // + // Clean this page and return + // + ZeroMem ((VOID*)(UINTN)RetVal, EFI_PAGE_SIZE); + return RetVal; +} + +/** + 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 + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. +**/ +VOID +EFIAPI +SmiPFHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINTN PFAddress; + UINTN GuardPageAddress; + UINTN CpuIndex; + + ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT); + + AcquireSpinLock (mPFLock); + + PFAddress = AsmReadCr2 (); + + if (mCpuSmmRestrictedMemoryAccess && (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1)))) { + DumpCpuContext (InterruptType, SystemContext); + DEBUG ((DEBUG_ERROR, "Do not support address 0x%lx by processor!\n", PFAddress)); + CpuDeadLoop (); + goto Exit; + } + + // + // If a page fault occurs in SMRAM range, it might be in a SMM stack guard page, + // or SMM page protection violation. + // + if ((PFAddress >= mCpuHotPlugData.SmrrBase) && + (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) { + DumpCpuContext (InterruptType, SystemContext); + CpuIndex = GetCpuIndex (); + GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize); + if ((FeaturePcdGet (PcdCpuSmmStackGuard)) && + (PFAddress >= GuardPageAddress) && + (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) { + DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n")); + } else { + if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) { + DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%lx)\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp); + ); + } else { + DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%lx)\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip); + ); + } + + if (HEAP_GUARD_NONSTOP_MODE) { + GuardPagePFHandler (SystemContext.SystemContextX64->ExceptionData); + goto Exit; + } + } + CpuDeadLoop (); + goto Exit; + } + + // + // If a page fault occurs in non-SMRAM range. + // + if ((PFAddress < mCpuHotPlugData.SmrrBase) || + (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) { + if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) { + DumpCpuContext (InterruptType, SystemContext); + DEBUG ((DEBUG_ERROR, "Code executed on IP(0x%lx) out of SMM range after SMM is locked!\n", PFAddress)); + DEBUG_CODE ( + DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp); + ); + CpuDeadLoop (); + goto Exit; + } + + // + // If NULL pointer was just accessed + // + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0 && + (PFAddress < EFI_PAGE_SIZE)) { + DumpCpuContext (InterruptType, SystemContext); + DEBUG ((DEBUG_ERROR, "!!! NULL pointer access !!!\n")); + DEBUG_CODE ( + DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip); + ); + + if (NULL_DETECTION_NONSTOP_MODE) { + GuardPagePFHandler (SystemContext.SystemContextX64->ExceptionData); + goto Exit; + } + + CpuDeadLoop (); + goto Exit; + } + + if (mCpuSmmRestrictedMemoryAccess && IsSmmCommBufferForbiddenAddress (PFAddress)) { + DumpCpuContext (InterruptType, SystemContext); + 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)) { + SmmProfilePFHandler ( + SystemContext.SystemContextX64->Rip, + SystemContext.SystemContextX64->ExceptionData + ); + } else { + SmiDefaultPFHandler (); + } + +Exit: + ReleaseSpinLock (mPFLock); +} + +/** + This function sets memory attribute for page table. +**/ +VOID +SetPageTableAttributes ( + VOID + ) +{ + UINTN Index2; + UINTN Index3; + UINTN Index4; + UINTN Index5; + UINT64 *L1PageTable; + UINT64 *L2PageTable; + UINT64 *L3PageTable; + UINT64 *L4PageTable; + UINT64 *L5PageTable; + BOOLEAN IsSplitted; + BOOLEAN PageTableSplitted; + BOOLEAN CetEnabled; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + + // + // 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 (!mCpuSmmRestrictedMemoryAccess || + ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) || + FeaturePcdGet (PcdCpuSmmProfileEnable)) { + // + // Restriction on access to non-SMRAM memory and heap guard could not be enabled at the same time. + // + ASSERT (!(mCpuSmmRestrictedMemoryAccess && + (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0)); + + // + // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time. + // + ASSERT (!(mCpuSmmRestrictedMemoryAccess && FeaturePcdGet (PcdCpuSmmProfileEnable))); + return ; + } + + DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); + + // + // Disable write protection, because we need mark page table to be write protected. + // We need *write* page table memory, to mark itself to be *read only*. + // + CetEnabled = ((AsmReadCr4() & CR4_CET_ENABLE) != 0) ? TRUE : FALSE; + if (CetEnabled) { + // + // CET must be disabled if WP is disabled. + // + DisableCet(); + } + AsmWriteCr0 (AsmReadCr0() & ~CR0_WP); + + do { + DEBUG ((DEBUG_INFO, "Start...\n")); + PageTableSplitted = FALSE; + L5PageTable = NULL; + if (Enable5LevelPaging) { + L5PageTable = (UINT64 *)GetPageTableBase (); + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L5PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + } + + for (Index5 = 0; Index5 < (Enable5LevelPaging ? SIZE_4KB/sizeof(UINT64) : 1); Index5++) { + if (Enable5LevelPaging) { + L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L4PageTable == NULL) { + continue; + } + } else { + L4PageTable = (UINT64 *)GetPageTableBase (); + } + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + + for (Index4 = 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) { + L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L3PageTable == NULL) { + continue; + } + + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + + for (Index3 = 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++) { + if ((L3PageTable[Index3] & IA32_PG_PS) != 0) { + // 1G + continue; + } + L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L2PageTable == NULL) { + continue; + } + + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + + for (Index2 = 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++) { + if ((L2PageTable[Index2] & IA32_PG_PS) != 0) { + // 2M + continue; + } + L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); + if (L1PageTable == NULL) { + continue; + } + SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted); + PageTableSplitted = (PageTableSplitted || IsSplitted); + } + } + } + } + } while (PageTableSplitted); + + // + // Enable write protection, after page table updated. + // + AsmWriteCr0 (AsmReadCr0() | CR0_WP); + if (CetEnabled) { + // + // re-enable CET. + // + EnableCet(); + } + + return ; +} + +/** + This function reads CR2 register when on-demand paging is enabled. + + @param[out] *Cr2 Pointer to variable to hold CR2 register value. +**/ +VOID +SaveCr2 ( + OUT UINTN *Cr2 + ) +{ + if (!mCpuSmmRestrictedMemoryAccess) { + // + // On-demand paging is enabled when access to non-SMRAM is not restricted. + // + *Cr2 = AsmReadCr2 (); + } +} + +/** + This function restores CR2 register when on-demand paging is enabled. + + @param[in] Cr2 Value to write into CR2 register. +**/ +VOID +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; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c new file mode 100644 index 000000000..8c9de1fda --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c @@ -0,0 +1,69 @@ +/** @file +Semaphore mechanism to indicate to the BSP that an AP has exited SMM +after SMBASE relocation. + +Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +X86_ASSEMBLY_PATCH_LABEL gPatchSmmRelocationOriginalAddressPtr32; +X86_ASSEMBLY_PATCH_LABEL gPatchRebasedFlagAddr32; + +UINTN mSmmRelocationOriginalAddress; +volatile BOOLEAN *mRebasedFlag; + +/** +AP Semaphore operation in 32-bit mode while BSP runs in 64-bit mode. +**/ +VOID +SmmRelocationSemaphoreComplete32 ( + VOID + ); + +/** + Hook return address of SMM Save State so that semaphore code + can be executed immediately after AP exits SMM to indicate to + the BSP that an AP has exited SMM after SMBASE relocation. + + @param[in] CpuIndex The processor index. + @param[in] RebasedFlag A pointer to a flag that is set to TRUE + immediately after AP exits SMM. + +**/ +VOID +SemaphoreHook ( + IN UINTN CpuIndex, + IN volatile BOOLEAN *RebasedFlag + ) +{ + SMRAM_SAVE_STATE_MAP *CpuState; + UINTN TempValue; + + mRebasedFlag = RebasedFlag; + PatchInstructionX86 ( + gPatchRebasedFlagAddr32, + (UINT32)(UINTN)mRebasedFlag, + 4 + ); + + CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET); + mSmmRelocationOriginalAddress = HookReturnFromSmm ( + CpuIndex, + CpuState, + (UINT64)(UINTN)&SmmRelocationSemaphoreComplete32, + (UINT64)(UINTN)&SmmRelocationSemaphoreComplete + ); + + // + // Use temp value to fix ICC compiler warning + // + TempValue = (UINTN)&mSmmRelocationOriginalAddress; + PatchInstructionX86 ( + gPatchSmmRelocationOriginalAddressPtr32, + (UINT32)TempValue, + 4 + ); +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm new file mode 100644 index 000000000..8bfba55b5 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm @@ -0,0 +1,380 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiEntry.nasm +; +; Abstract: +; +; Code template of the SMI handler for a particular processor +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" +%include "Nasm.inc" + +; +; Variables referenced by C code +; + +%define MSR_IA32_S_CET 0x6A2 +%define MSR_IA32_CET_SH_STK_EN 0x1 +%define MSR_IA32_CET_WR_SHSTK_EN 0x2 +%define MSR_IA32_CET_ENDBR_EN 0x4 +%define MSR_IA32_CET_LEG_IW_EN 0x8 +%define MSR_IA32_CET_NO_TRACK_EN 0x10 +%define MSR_IA32_CET_SUPPRESS_DIS 0x20 +%define MSR_IA32_CET_SUPPRESS 0x400 +%define MSR_IA32_CET_TRACKER 0x800 +%define MSR_IA32_PL0_SSP 0x6A4 +%define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8 + +%define CR4_CET 0x800000 + +%define MSR_IA32_MISC_ENABLE 0x1A0 +%define MSR_EFER 0xc0000080 +%define MSR_EFER_XD 0x800 + +; +; Constants relating to PROCESSOR_SMM_DESCRIPTOR +; +%define DSC_OFFSET 0xfb00 +%define DSC_GDTPTR 0x30 +%define DSC_GDTSIZ 0x38 +%define DSC_CS 14 +%define DSC_DS 16 +%define DSC_SS 18 +%define DSC_OTHERSEG 20 +; +; Constants relating to CPU State Save Area +; +%define SSM_DR6 0xffd0 +%define SSM_DR7 0xffc8 + +%define PROTECT_MODE_CS 0x8 +%define PROTECT_MODE_DS 0x20 +%define LONG_MODE_CS 0x38 +%define TSS_SEGMENT 0x40 +%define GDT_SIZE 0x50 + +extern ASM_PFX(SmiRendezvous) +extern ASM_PFX(gSmiHandlerIdtr) +extern ASM_PFX(CpuSmmDebugEntry) +extern ASM_PFX(CpuSmmDebugExit) + +global ASM_PFX(gPatchSmbase) +extern ASM_PFX(mXdSupported) +global ASM_PFX(gPatchXdSupported) +global ASM_PFX(gPatchSmiStack) +global ASM_PFX(gPatchSmiCr3) +global ASM_PFX(gPatch5LevelPagingNeeded) +global ASM_PFX(gcSmiHandlerTemplate) +global ASM_PFX(gcSmiHandlerSize) + +extern ASM_PFX(mCetSupported) +global ASM_PFX(mPatchCetSupported) +global ASM_PFX(mPatchCetPl0Ssp) +global ASM_PFX(mPatchCetInterruptSsp) +global ASM_PFX(mPatchCetInterruptSspTable) + + DEFAULT REL + SECTION .text + +BITS 16 +ASM_PFX(gcSmiHandlerTemplate): +_SmiEntryPoint: + mov bx, _GdtDesc - _SmiEntryPoint + 0x8000 + mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ] + dec ax + mov [cs:bx], ax + mov eax, [cs:DSC_OFFSET + DSC_GDTPTR] + mov [cs:bx + 2], eax +o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx] + mov ax, PROTECT_MODE_CS + mov [cs:bx-0x2],ax + mov edi, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmbase): + lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000] + mov [cs:bx-0x6],eax + mov ebx, cr0 + and ebx, 0x9ffafff3 + or ebx, 0x23 + mov cr0, ebx + jmp dword 0x0:0x0 +_GdtDesc: + DW 0 + DD 0 + +BITS 32 +@ProtectedMode: + mov ax, PROTECT_MODE_DS +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax + mov esp, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmiStack): + jmp ProtFlatMode + +BITS 64 +ProtFlatMode: + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmiCr3): + mov cr3, rax + mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3 + + mov cl, strict byte 0 ; source operand will be patched +ASM_PFX(gPatch5LevelPagingNeeded): + cmp cl, 0 + je SkipEnable5LevelPaging + ; + ; Enable 5-Level Paging bit + ; + bts eax, 12 ; Set LA57 bit (bit #12) +SkipEnable5LevelPaging: + + mov cr4, rax ; in PreModifyMtrrs() to flush TLB. +; Load TSS + sub esp, 8 ; reserve room in stack + sgdt [rsp] + mov eax, [rsp + 2] ; eax = GDT base + add esp, 8 + mov dl, 0x89 + mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag + mov eax, TSS_SEGMENT + ltr ax + +; enable NXE if supported + mov al, strict byte 1 ; source operand may be patched +ASM_PFX(gPatchXdSupported): + cmp al, 0 + jz @SkipXd +; +; Check XD disable bit +; + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + sub esp, 4 + push rdx ; save MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] + jz .0 + and dx, 0xFFFB ; clear XD Disable bit if it is set + wrmsr +.0: + mov ecx, MSR_EFER + rdmsr + or ax, MSR_EFER_XD ; enable NXE + wrmsr + jmp @XdDone +@SkipXd: + sub esp, 8 +@XdDone: + +; Switch into @LongMode + push LONG_MODE_CS ; push cs hardcore here + call Base ; push return address for retf later +Base: + add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg + + mov ecx, MSR_EFER + rdmsr + or ah, 1 ; enable LME + wrmsr + mov rbx, cr0 + or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE + mov cr0, rbx + retf +@LongMode: ; long mode (64-bit code) starts here + mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr) +SmiHandlerIdtrAbsAddr: + lidt [rax] + lea ebx, [rdi + DSC_OFFSET] + mov ax, [rbx + DSC_DS] + mov ds, eax + mov ax, [rbx + DSC_OTHERSEG] + mov es, eax + mov fs, eax + mov gs, eax + mov ax, [rbx + DSC_SS] + mov ss, eax + + mov rbx, [rsp + 0x8] ; rbx <- CpuIndex + +; enable CET if supported + mov al, strict byte 1 ; source operand may be patched +ASM_PFX(mPatchCetSupported): + cmp al, 0 + jz CetDone + + mov ecx, MSR_IA32_S_CET + rdmsr + push rdx + push rax + + mov ecx, MSR_IA32_PL0_SSP + rdmsr + push rdx + push rax + + mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR + rdmsr + push rdx + push rax + + mov ecx, MSR_IA32_S_CET + mov eax, MSR_IA32_CET_SH_STK_EN + xor edx, edx + wrmsr + + mov ecx, MSR_IA32_PL0_SSP + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(mPatchCetPl0Ssp): + xor edx, edx + wrmsr + mov rcx, cr0 + btr ecx, 16 ; clear WP + mov cr0, rcx + mov [eax], eax ; reload SSP, and clear busyflag. + xor ecx, ecx + mov [eax + 4], ecx + + mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(mPatchCetInterruptSspTable): + xor edx, edx + wrmsr + + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(mPatchCetInterruptSsp): + cmp eax, 0 + jz CetInterruptDone + mov [eax], eax ; reload SSP, and clear busyflag. + xor ecx, ecx + mov [eax + 4], ecx +CetInterruptDone: + + mov rcx, cr0 + bts ecx, 16 ; set WP + mov cr0, rcx + + mov eax, 0x668 | CR4_CET + mov cr4, rax + + SETSSBSY + +CetDone: + + ; + ; Save FP registers + ; + sub rsp, 0x200 + fxsave64 [rsp] + + add rsp, -0x20 + + mov rcx, rbx + mov rax, strict qword 0 ; call ASM_PFX(CpuSmmDebugEntry) +CpuSmmDebugEntryAbsAddr: + call rax + + mov rcx, rbx + mov rax, strict qword 0 ; call ASM_PFX(SmiRendezvous) +SmiRendezvousAbsAddr: + call rax + + mov rcx, rbx + mov rax, strict qword 0 ; call ASM_PFX(CpuSmmDebugExit) +CpuSmmDebugExitAbsAddr: + call rax + + add rsp, 0x20 + + ; + ; Restore FP registers + ; + fxrstor64 [rsp] + + add rsp, 0x200 + + mov rax, strict qword 0 ; mov rax, ASM_PFX(mCetSupported) +mCetSupportedAbsAddr: + mov al, [rax] + cmp al, 0 + jz CetDone2 + + mov eax, 0x668 + mov cr4, rax ; disable CET + + mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR + pop rax + pop rdx + wrmsr + + mov ecx, MSR_IA32_PL0_SSP + pop rax + pop rdx + wrmsr + + mov ecx, MSR_IA32_S_CET + pop rax + pop rdx + wrmsr +CetDone2: + + mov rax, strict qword 0 ; lea rax, [ASM_PFX(mXdSupported)] +mXdSupportedAbsAddr: + mov al, [rax] + cmp al, 0 + jz .1 + pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32] + test edx, BIT2 + jz .1 + mov ecx, MSR_IA32_MISC_ENABLE + rdmsr + or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM + wrmsr + +.1: + + StuffRsb64 + rsm + +ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint + +; +; Retrieve the address and fill it into mov opcode. +; +; It is called in the driver entry point first. +; It is used to fix up the real address in mov opcode. +; Then, after the code logic is copied to the different location, +; the code can also run. +; +global ASM_PFX(PiSmmCpuSmiEntryFixupAddress) +ASM_PFX(PiSmmCpuSmiEntryFixupAddress): + lea rax, [ASM_PFX(gSmiHandlerIdtr)] + lea rcx, [SmiHandlerIdtrAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [ASM_PFX(CpuSmmDebugEntry)] + lea rcx, [CpuSmmDebugEntryAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [ASM_PFX(SmiRendezvous)] + lea rcx, [SmiRendezvousAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [ASM_PFX(CpuSmmDebugExit)] + lea rcx, [CpuSmmDebugExitAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [ASM_PFX(mXdSupported)] + lea rcx, [mXdSupportedAbsAddr] + mov qword [rcx - 8], rax + + lea rax, [ASM_PFX(mCetSupported)] + lea rcx, [mCetSupportedAbsAddr] + mov qword [rcx - 8], rax + ret diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm new file mode 100644 index 000000000..f329a988f --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm @@ -0,0 +1,378 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmiException.nasm +; +; Abstract: +; +; Exception handlers used in SM mode +; +;------------------------------------------------------------------------------- + +extern ASM_PFX(SmiPFHandler) + +global ASM_PFX(gcSmiIdtr) +global ASM_PFX(gcSmiGdtr) +global ASM_PFX(gcPsd) + + SECTION .data + +NullSeg: DQ 0 ; reserved by architecture +CodeSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +ProtModeCodeSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +ProtModeSsSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x93 + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +DataSeg32: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x93 + DB 0xcf ; LimitHigh + DB 0 ; BaseHigh +CodeSeg16: + DW -1 + DW 0 + DB 0 + DB 0x9b + DB 0x8f + DB 0 +DataSeg16: + DW -1 + DW 0 + DB 0 + DB 0x93 + DB 0x8f + DB 0 +CodeSeg64: + DW -1 ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x9b + DB 0xaf ; LimitHigh + DB 0 ; BaseHigh +; TSS Segment for X64 specially +TssSeg: + DW TSS_DESC_SIZE ; LimitLow + DW 0 ; BaseLow + DB 0 ; BaseMid + DB 0x89 + DB 0x80 ; LimitHigh + DB 0 ; BaseHigh + DD 0 ; BaseUpper + DD 0 ; Reserved +GDT_SIZE equ $ - NullSeg + +; Create TSS Descriptor just after GDT +TssDescriptor: + DD 0 ; Reserved + DQ 0 ; RSP0 + DQ 0 ; RSP1 + DQ 0 ; RSP2 + DD 0 ; Reserved + DD 0 ; Reserved + DQ 0 ; IST1 + DQ 0 ; IST2 + DQ 0 ; IST3 + DQ 0 ; IST4 + DQ 0 ; IST5 + DQ 0 ; IST6 + DQ 0 ; IST7 + DD 0 ; Reserved + DD 0 ; Reserved + DW 0 ; Reserved + DW 0 ; I/O Map Base Address +TSS_DESC_SIZE equ $ - TssDescriptor + +; +; This structure serves as a template for all processors. +; +ASM_PFX(gcPsd): + DB 'PSDSIG ' + DW PSD_SIZE + DW 2 + DW 1 << 2 + DW CODE_SEL + DW DATA_SEL + DW DATA_SEL + DW DATA_SEL + DW 0 + DQ 0 + DQ 0 + DQ 0 ; fixed in InitializeMpServiceData() + DQ NullSeg + DD GDT_SIZE + DD 0 + times 24 DB 0 + DQ 0 +PSD_SIZE equ $ - ASM_PFX(gcPsd) + +; +; CODE & DATA segments for SMM runtime +; +CODE_SEL equ CodeSeg64 - NullSeg +DATA_SEL equ DataSeg32 - NullSeg +CODE32_SEL equ CodeSeg32 - NullSeg + +ASM_PFX(gcSmiGdtr): + DW GDT_SIZE - 1 + DQ NullSeg + +ASM_PFX(gcSmiIdtr): + DW 0 + DQ 0 + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; _SmiExceptionEntryPoints is the collection of exception entrypoints followed +; by a common exception handler. +; +; Stack frame would be as follows as specified in IA32 manuals: +; +; +---------------------+ <-- 16-byte aligned ensured by processor +; + Old SS + +; +---------------------+ +; + Old RSP + +; +---------------------+ +; + RFlags + +; +---------------------+ +; + CS + +; +---------------------+ +; + RIP + +; +---------------------+ +; + Error Code + +; +---------------------+ +; + Vector Number + +; +---------------------+ +; + RBP + +; +---------------------+ <-- RBP, 16-byte aligned +; +; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT +;------------------------------------------------------------------------------ +global ASM_PFX(PageFaultIdtHandlerSmmProfile) +ASM_PFX(PageFaultIdtHandlerSmmProfile): + push 0xe ; Page Fault + test spl, 8 ; odd multiple of 8 => ErrCode present + jnz .0 + push qword [rsp] ; duplicate INT# if no ErrCode + mov qword [rsp + 8], 0 +.0: + push rbp + mov rbp, rsp + + ; + ; Since here the stack pointer is 16-byte aligned, so + ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 + ; is 16-byte aligned + ; + +;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; +;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rax + push rcx + push rdx + push rbx + push qword [rbp + 48] ; RSP + push qword [rbp] ; RBP + push rsi + push rdi + +;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero + movzx rax, word [rbp + 56] + push rax ; for ss + movzx rax, word [rbp + 32] + push rax ; for cs + mov rax, ds + push rax + mov rax, es + push rax + mov rax, fs + push rax + mov rax, gs + push rax + +;; UINT64 Rip; + push qword [rbp + 24] + +;; UINT64 Gdtr[2], Idtr[2]; + sub rsp, 16 + sidt [rsp] + sub rsp, 16 + sgdt [rsp] + +;; UINT64 Ldtr, Tr; + xor rax, rax + str ax + push rax + sldt ax + push rax + +;; UINT64 RFlags; + push qword [rbp + 40] + +;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; + mov rax, cr8 + push rax + mov rax, cr4 + or rax, 0x208 + mov cr4, rax + push rax + mov rax, cr3 + push rax + mov rax, cr2 + push rax + xor rax, rax + push rax + mov rax, cr0 + push rax + +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov rax, dr7 + push rax + mov rax, dr6 + push rax + mov rax, dr3 + push rax + mov rax, dr2 + push rax + mov rax, dr1 + push rax + mov rax, dr0 + push rax + +;; FX_SAVE_STATE_X64 FxSaveState; + + sub rsp, 512 + mov rdi, rsp + fxsave [rdi] + +; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear + cld + +;; UINT32 ExceptionData; + push qword [rbp + 16] + +;; call into exception handler + mov rcx, [rbp + 8] + lea rax, [ASM_PFX(SmiPFHandler)] + +;; Prepare parameter and call + mov rdx, rsp + ; + ; Per X64 calling convention, allocate maximum parameter stack space + ; and make sure RSP is 16-byte aligned + ; + sub rsp, 4 * 8 + 8 + call rax + add rsp, 4 * 8 + 8 + jmp .1 + +.1: +;; UINT64 ExceptionData; + add rsp, 8 + +;; FX_SAVE_STATE_X64 FxSaveState; + + mov rsi, rsp + fxrstor [rsi] + add rsp, 512 + +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; Skip restoration of DRx registers to support debuggers +;; that set breakpoints in interrupt/exception context + add rsp, 8 * 6 + +;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; + pop rax + mov cr0, rax + add rsp, 8 ; not for Cr1 + pop rax + mov cr2, rax + pop rax + mov cr3, rax + pop rax + mov cr4, rax + pop rax + mov cr8, rax + +;; UINT64 RFlags; + pop qword [rbp + 40] + +;; UINT64 Ldtr, Tr; +;; UINT64 Gdtr[2], Idtr[2]; +;; Best not let anyone mess with these particular registers... + add rsp, 48 + +;; UINT64 Rip; + pop qword [rbp + 24] + +;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; + pop rax + ; mov gs, rax ; not for gs + pop rax + ; mov fs, rax ; not for fs + ; (X64 will not use fs and gs, so we do not restore it) + pop rax + mov es, rax + pop rax + mov ds, rax + pop qword [rbp + 32] ; for cs + pop qword [rbp + 56] ; for ss + +;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; +;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; + pop rdi + pop rsi + add rsp, 8 ; not for rbp + pop qword [rbp + 48] ; for rsp + pop rbx + pop rdx + pop rcx + pop rax + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + + mov rsp, rbp + +; Enable TF bit after page fault handler runs + bts dword [rsp + 40], 8 ;RFLAGS + + pop rbp + add rsp, 16 ; skip INT# & ErrCode + iretq + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c new file mode 100644 index 000000000..6298571e2 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c @@ -0,0 +1,205 @@ +/** @file + SMM CPU misc functions for x64 arch specific. + +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" + +EFI_PHYSICAL_ADDRESS mGdtBuffer; +UINTN mGdtBufferSize; + +extern BOOLEAN mCetSupported; +extern UINTN mSmmShadowStackSize; + +X86_ASSEMBLY_PATCH_LABEL mPatchCetPl0Ssp; +X86_ASSEMBLY_PATCH_LABEL mPatchCetInterruptSsp; +X86_ASSEMBLY_PATCH_LABEL mPatchCetInterruptSspTable; +UINT32 mCetPl0Ssp; +UINT32 mCetInterruptSsp; +UINT32 mCetInterruptSspTable; + +UINTN mSmmInterruptSspTables; + +/** + Initialize IDT for SMM Stack Guard. + +**/ +VOID +EFIAPI +InitializeIDTSmmStackGuard ( + VOID + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtGate; + + // + // If SMM Stack Guard feature is enabled, set the IST field of + // the interrupt gate for Page Fault Exception to be 1 + // + IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base; + IdtGate += EXCEPT_IA32_PAGE_FAULT; + IdtGate->Bits.Reserved_0 = 1; +} + +/** + Initialize Gdt for all processors. + + @param[in] Cr3 CR3 value. + @param[out] GdtStepSize The step size for GDT table. + + @return GdtBase for processor 0. + GdtBase for processor X is: GdtBase + (GdtStepSize * X) +**/ +VOID * +InitGdt ( + IN UINTN Cr3, + OUT UINTN *GdtStepSize + ) +{ + UINTN Index; + IA32_SEGMENT_DESCRIPTOR *GdtDescriptor; + UINTN TssBase; + UINTN GdtTssTableSize; + UINT8 *GdtTssTables; + UINTN GdtTableStepSize; + + // + // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention + // on each SMI entry. + // + GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned + mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; + GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize)); + ASSERT (GdtTssTables != NULL); + mGdtBuffer = (UINTN)GdtTssTables; + GdtTableStepSize = GdtTssTableSize; + + for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { + CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE); + + // + // Fixup TSS descriptors + // + TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1); + GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2; + GdtDescriptor->Bits.BaseLow = (UINT16)(UINTN)TssBase; + GdtDescriptor->Bits.BaseMid = (UINT8)((UINTN)TssBase >> 16); + GdtDescriptor->Bits.BaseHigh = (UINT8)((UINTN)TssBase >> 24); + + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // Setup top of known good stack as IST1 for each processor. + // + *(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize); + } + } + + *GdtStepSize = GdtTableStepSize; + return GdtTssTables; +} + +/** + Get Protected mode code segment from current GDT table. + + @return Protected mode code segment value. +**/ +UINT16 +GetProtectedModeCS ( + VOID + ) +{ + IA32_DESCRIPTOR GdtrDesc; + IA32_SEGMENT_DESCRIPTOR *GdtEntry; + UINTN GdtEntryCount; + UINT16 Index; + + AsmReadGdtr (&GdtrDesc); + GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR); + GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base; + for (Index = 0; Index < GdtEntryCount; Index++) { + if (GdtEntry->Bits.L == 0) { + if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) { + break; + } + } + GdtEntry++; + } + ASSERT (Index != GdtEntryCount); + return Index * 8; +} + +/** + Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. + + @param[in] ApHltLoopCode The address of the safe hlt-loop function. + @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. + @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. + +**/ +VOID +TransferApToSafeState ( + IN UINTN ApHltLoopCode, + IN UINTN TopOfStack, + IN UINTN NumberToFinishAddress + ) +{ + AsmDisablePaging64 ( + GetProtectedModeCS (), + (UINT32)ApHltLoopCode, + (UINT32)NumberToFinishAddress, + 0, + (UINT32)TopOfStack + ); + // + // It should never reach here + // + ASSERT (FALSE); +} + +/** + Initialize the shadow stack related data structure. + + @param CpuIndex The index of CPU. + @param ShadowStack The bottom of the shadow stack for this CPU. +**/ +VOID +InitShadowStack ( + IN UINTN CpuIndex, + IN VOID *ShadowStack + ) +{ + UINTN SmmShadowStackSize; + UINT64 *InterruptSspTable; + + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) { + SmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize))); + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + SmmShadowStackSize += EFI_PAGES_TO_SIZE (2); + } + mCetPl0Ssp = (UINT32)((UINTN)ShadowStack + SmmShadowStackSize - sizeof(UINT64)); + PatchInstructionX86 (mPatchCetPl0Ssp, mCetPl0Ssp, 4); + DEBUG ((DEBUG_INFO, "mCetPl0Ssp - 0x%x\n", mCetPl0Ssp)); + DEBUG ((DEBUG_INFO, "ShadowStack - 0x%x\n", ShadowStack)); + DEBUG ((DEBUG_INFO, " SmmShadowStackSize - 0x%x\n", SmmShadowStackSize)); + + if (FeaturePcdGet (PcdCpuSmmStackGuard)) { + if (mSmmInterruptSspTables == 0) { + mSmmInterruptSspTables = (UINTN)AllocateZeroPool(sizeof(UINT64) * 8 * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus); + ASSERT (mSmmInterruptSspTables != 0); + DEBUG ((DEBUG_INFO, "mSmmInterruptSspTables - 0x%x\n", mSmmInterruptSspTables)); + } + mCetInterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64)); + mCetInterruptSspTable = (UINT32)(UINTN)(mSmmInterruptSspTables + sizeof(UINT64) * 8 * CpuIndex); + InterruptSspTable = (UINT64 *)(UINTN)mCetInterruptSspTable; + InterruptSspTable[1] = mCetInterruptSsp; + PatchInstructionX86 (mPatchCetInterruptSsp, mCetInterruptSsp, 4); + PatchInstructionX86 (mPatchCetInterruptSspTable, mCetInterruptSspTable, 4); + DEBUG ((DEBUG_INFO, "mCetInterruptSsp - 0x%x\n", mCetInterruptSsp)); + DEBUG ((DEBUG_INFO, "mCetInterruptSspTable - 0x%x\n", mCetInterruptSspTable)); + } + } +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm new file mode 100644 index 000000000..9cf3a6dcf --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm @@ -0,0 +1,146 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; SmmInit.nasm +; +; Abstract: +; +; Functions for relocating SMBASE's for all processors +; +;------------------------------------------------------------------------------- + +%include "StuffRsbNasm.inc" + +extern ASM_PFX(SmmInitHandler) +extern ASM_PFX(mRebasedFlag) +extern ASM_PFX(mSmmRelocationOriginalAddress) + +global ASM_PFX(gPatchSmmCr3) +global ASM_PFX(gPatchSmmCr4) +global ASM_PFX(gPatchSmmCr0) +global ASM_PFX(gPatchSmmInitStack) +global ASM_PFX(gcSmiInitGdtr) +global ASM_PFX(gcSmmInitSize) +global ASM_PFX(gcSmmInitTemplate) +global ASM_PFX(gPatchRebasedFlagAddr32) +global ASM_PFX(gPatchSmmRelocationOriginalAddressPtr32) + +%define LONG_MODE_CS 0x38 + + DEFAULT REL + SECTION .text + +ASM_PFX(gcSmiInitGdtr): + DW 0 + DQ 0 + +global ASM_PFX(SmmStartup) + +BITS 16 +ASM_PFX(SmmStartup): + mov eax, 0x80000001 ; read capability + cpuid + mov ebx, edx ; rdmsr will change edx. keep it in ebx. + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr3): + mov cr3, eax +o32 lgdt [cs:ebp + (ASM_PFX(gcSmiInitGdtr) - ASM_PFX(SmmStartup))] + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr4): + or ah, 2 ; enable XMM registers access + mov cr4, eax + mov ecx, 0xc0000080 ; IA32_EFER MSR + rdmsr + or ah, BIT0 ; set LME bit + test ebx, BIT20 ; check NXE capability + jz .1 + or ah, BIT3 ; set NXE bit +.1: + wrmsr + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchSmmCr0): + mov cr0, eax ; enable protected mode & paging + jmp LONG_MODE_CS : dword 0 ; offset will be patched to @LongMode +@PatchLongModeOffset: + +BITS 64 +@LongMode: ; long-mode starts here + mov rsp, strict qword 0 ; source operand will be patched +ASM_PFX(gPatchSmmInitStack): + and sp, 0xfff0 ; make sure RSP is 16-byte aligned + ; + ; According to X64 calling convention, XMM0~5 are volatile, we need to save + ; them before calling C-function. + ; + sub rsp, 0x60 + movdqa [rsp], xmm0 + movdqa [rsp + 0x10], xmm1 + movdqa [rsp + 0x20], xmm2 + movdqa [rsp + 0x30], xmm3 + movdqa [rsp + 0x40], xmm4 + movdqa [rsp + 0x50], xmm5 + + add rsp, -0x20 + call ASM_PFX(SmmInitHandler) + add rsp, 0x20 + + ; + ; Restore XMM0~5 after calling C-function. + ; + movdqa xmm0, [rsp] + movdqa xmm1, [rsp + 0x10] + movdqa xmm2, [rsp + 0x20] + movdqa xmm3, [rsp + 0x30] + movdqa xmm4, [rsp + 0x40] + movdqa xmm5, [rsp + 0x50] + + StuffRsb64 + rsm + +BITS 16 +ASM_PFX(gcSmmInitTemplate): + mov ebp, [cs:@L1 - ASM_PFX(gcSmmInitTemplate) + 0x8000] + sub ebp, 0x30000 + jmp ebp +@L1: + DQ 0; ASM_PFX(SmmStartup) + +ASM_PFX(gcSmmInitSize): DW $ - ASM_PFX(gcSmmInitTemplate) + +BITS 64 +global ASM_PFX(SmmRelocationSemaphoreComplete) +ASM_PFX(SmmRelocationSemaphoreComplete): + push rax + mov rax, [ASM_PFX(mRebasedFlag)] + mov byte [rax], 1 + pop rax + jmp [ASM_PFX(mSmmRelocationOriginalAddress)] + +; +; Semaphore code running in 32-bit mode +; +BITS 32 +global ASM_PFX(SmmRelocationSemaphoreComplete32) +ASM_PFX(SmmRelocationSemaphoreComplete32): + push eax + mov eax, strict dword 0 ; source operand will be patched +ASM_PFX(gPatchRebasedFlagAddr32): + mov byte [eax], 1 + pop eax + jmp dword [dword 0] ; destination will be patched +ASM_PFX(gPatchSmmRelocationOriginalAddressPtr32): + +BITS 64 +global ASM_PFX(PiSmmCpuSmmInitFixupAddress) +ASM_PFX(PiSmmCpuSmmInitFixupAddress): + lea rax, [@LongMode] + lea rcx, [@PatchLongModeOffset - 6] + mov dword [rcx], eax + + lea rax, [ASM_PFX(SmmStartup)] + lea rcx, [@L1] + mov qword [rcx], rax + ret diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c new file mode 100644 index 000000000..63bae5a91 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c @@ -0,0 +1,333 @@ +/** @file +X64 processor specific functions to enable SMM profile. + +Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCpuDxeSmm.h" +#include "SmmProfileInternal.h" + +// +// Current page index. +// +UINTN mPFPageIndex; + +// +// Pool for dynamically creating page table in page fault handler. +// +UINT64 mPFPageBuffer; + +// +// Store the uplink information for each page being used. +// +UINT64 *mPFPageUplink[MAX_PF_PAGE_COUNT]; + +/** + Create SMM page table for S3 path. + +**/ +VOID +InitSmmS3Cr3 ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS Pages; + UINT64 *PTEntry; + + // + // Generate PAE page table for the first 4GB memory space + // + Pages = Gen4GPageTable (FALSE); + + // + // Fill Page-Table-Level4 (PML4) entry + // + PTEntry = (UINT64*)AllocatePageTableMemory (1); + ASSERT (PTEntry != NULL); + *PTEntry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); + + // + // Return the address of PML4 (to set CR3) + // + mSmmS3ResumeState->SmmS3Cr3 = (UINT32)(UINTN)PTEntry; + + return ; +} + +/** + Allocate pages for creating 4KB-page based on 2MB-page when page fault happens. + +**/ +VOID +InitPagesForPFHandler ( + VOID + ) +{ + VOID *Address; + + // + // Pre-Allocate memory for page fault handler + // + Address = NULL; + Address = AllocatePages (MAX_PF_PAGE_COUNT); + ASSERT (Address != NULL); + + mPFPageBuffer = (UINT64)(UINTN) Address; + mPFPageIndex = 0; + ZeroMem ((VOID *) (UINTN) mPFPageBuffer, EFI_PAGE_SIZE * MAX_PF_PAGE_COUNT); + ZeroMem (mPFPageUplink, sizeof (mPFPageUplink)); + + return; +} + +/** + Allocate one page for creating 4KB-page based on 2MB-page. + + @param Uplink The address of Page-Directory entry. + +**/ +VOID +AcquirePage ( + UINT64 *Uplink + ) +{ + UINT64 Address; + + // + // Get the buffer + // + Address = mPFPageBuffer + EFI_PAGES_TO_SIZE (mPFPageIndex); + ZeroMem ((VOID *) (UINTN) Address, EFI_PAGE_SIZE); + + // + // Cut the previous uplink if it exists and wasn't overwritten + // + if ((mPFPageUplink[mPFPageIndex] != NULL) && ((*mPFPageUplink[mPFPageIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK) == Address)) { + *mPFPageUplink[mPFPageIndex] = 0; + } + + // + // Link & Record the current uplink + // + *Uplink = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + mPFPageUplink[mPFPageIndex] = Uplink; + + mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT; +} + +/** + 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. + + @param PageTable PageTable Address. + @param PFAddress The memory address which caused page fault exception. + @param CpuIndex The index of the processor. + @param ErrorCode The Error code of exception. + @param IsValidPFAddress The flag indicates if SMM profile data need be added. + +**/ +VOID +RestorePageTableAbove4G ( + UINT64 *PageTable, + UINT64 PFAddress, + UINTN CpuIndex, + UINTN ErrorCode, + BOOLEAN *IsValidPFAddress + ) +{ + UINTN PTIndex; + UINT64 Address; + BOOLEAN Nx; + BOOLEAN Existed; + UINTN Index; + UINTN PFIndex; + IA32_CR4 Cr4; + BOOLEAN Enable5LevelPaging; + + ASSERT ((PageTable != NULL) && (IsValidPFAddress != NULL)); + + Cr4.UintN = AsmReadCr4 (); + Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); + + // + // If page fault address is 4GB above. + // + + // + // Check if page fault address has existed in page table. + // If it exists in page table but page fault is generated, + // there are 2 possible reasons: 1. present flag is set to 0; 2. instruction fetch in protected memory range. + // + Existed = FALSE; + PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK); + PTIndex = 0; + if (Enable5LevelPaging) { + PTIndex = BitFieldRead64 (PFAddress, 48, 56); + } + if ((!Enable5LevelPaging) || ((PageTable[PTIndex] & IA32_PG_P) != 0)) { + // PML5E + if (Enable5LevelPaging) { + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + } + PTIndex = BitFieldRead64 (PFAddress, 39, 47); + if ((PageTable[PTIndex] & IA32_PG_P) != 0) { + // PML4E + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + PTIndex = BitFieldRead64 (PFAddress, 30, 38); + if ((PageTable[PTIndex] & IA32_PG_P) != 0) { + // PDPTE + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + PTIndex = BitFieldRead64 (PFAddress, 21, 29); + // PD + if ((PageTable[PTIndex] & IA32_PG_PS) != 0) { + // + // 2MB page + // + Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + if ((Address & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) { + Existed = TRUE; + } + } else { + // + // 4KB page + // + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask& PHYSICAL_ADDRESS_MASK); + if (PageTable != 0) { + // + // When there is a valid entry to map to 4KB page, need not create a new entry to map 2MB. + // + PTIndex = BitFieldRead64 (PFAddress, 12, 20); + Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + if ((Address & ~((1ull << 12) - 1)) == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) { + Existed = TRUE; + } + } + } + } + } + } + + // + // If page entry does not existed in page table at all, create a new entry. + // + if (!Existed) { + + if (IsAddressValid (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. + // this access is not saved into SMM profile data. + // + *IsValidPFAddress = TRUE; + } + + // + // Create one entry in page table for page fault address. + // + SmiDefaultPFHandler (); + // + // Find the page table entry created just now. + // + PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK); + PFAddress = AsmReadCr2 (); + // PML5E + if (Enable5LevelPaging) { + PTIndex = BitFieldRead64 (PFAddress, 48, 56); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + } + // PML4E + PTIndex = BitFieldRead64 (PFAddress, 39, 47); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + // PDPTE + PTIndex = BitFieldRead64 (PFAddress, 30, 38); + PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); + // PD + PTIndex = BitFieldRead64 (PFAddress, 21, 29); + Address = PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK; + // + // Check if 2MB-page entry need be changed to 4KB-page entry. + // + if (IsAddressSplit (Address)) { + AcquirePage (&PageTable[PTIndex]); + + // PTE + 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)) { + PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); + } + if (Nx && mXdSupported) { + PageTable[Index] = PageTable[Index] | IA32_PG_NX; + } + if (Address == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) { + PTIndex = Index; + } + Address += SIZE_4KB; + } // end for PT + } else { + // + // Update 2MB page entry. + // + if (!IsAddressValid (Address, &Nx)) { + // + // Patch to remove present flag and rw flag. + // + PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); + } + // + // Set XD bit to 1 + // + if (Nx && mXdSupported) { + PageTable[PTIndex] = PageTable[PTIndex] | IA32_PG_NX; + } + } + } + + // + // Record old entries with non-present status + // Old entries include the memory which instruction is at and the memory which instruction access. + // + // + ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT); + if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) { + PFIndex = mPFEntryCount[CpuIndex]; + mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex]; + mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex]; + mPFEntryCount[CpuIndex]++; + } + + // + // Add present flag or clear XD flag to make page fault handler succeed. + // + PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS); + if ((ErrorCode & IA32_PF_EC_ID) != 0) { + // + // If page fault is caused by instruction fetch, clear XD bit in the entry. + // + PageTable[PTIndex] &= ~IA32_PG_NX; + } + + return; +} + +/** + Clear TF in FLAGS. + + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. + +**/ +VOID +ClearTrapFlag ( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ) +{ + SystemContext.SystemContextX64->Rflags &= (UINTN) ~BIT8; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h new file mode 100644 index 000000000..a857f587e --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h @@ -0,0 +1,99 @@ +/** @file +X64 processor specific header file to enable SMM profile. + +Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_PROFILE_ARCH_H_ +#define _SMM_PROFILE_ARCH_H_ + +#pragma pack (1) + +typedef struct _MSR_DS_AREA_STRUCT { + UINT64 BTSBufferBase; + UINT64 BTSIndex; + UINT64 BTSAbsoluteMaximum; + UINT64 BTSInterruptThreshold; + UINT64 PEBSBufferBase; + UINT64 PEBSIndex; + UINT64 PEBSAbsoluteMaximum; + UINT64 PEBSInterruptThreshold; + UINT64 PEBSCounterReset[2]; + UINT64 Reserved; +} MSR_DS_AREA_STRUCT; + +typedef struct _BRANCH_TRACE_RECORD { + UINT64 LastBranchFrom; + UINT64 LastBranchTo; + UINT64 Rsvd0 : 4; + UINT64 BranchPredicted : 1; + UINT64 Rsvd1 : 59; +} BRANCH_TRACE_RECORD; + +typedef struct _PEBS_RECORD { + UINT64 Rflags; + UINT64 LinearIP; + UINT64 Rax; + UINT64 Rbx; + UINT64 Rcx; + UINT64 Rdx; + UINT64 Rsi; + UINT64 Rdi; + UINT64 Rbp; + UINT64 Rsp; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; +} PEBS_RECORD; + +#pragma pack () + +#define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB) + +/** + 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. + + @param PageTable PageTable Address. + @param PFAddress The memory address which caused page fault exception. + @param CpuIndex The index of the processor. + @param ErrorCode The Error code of exception. + @param IsValidPFAddress The flag indicates if SMM profile data need be added. + +**/ +VOID +RestorePageTableAbove4G ( + UINT64 *PageTable, + UINT64 PFAddress, + UINTN CpuIndex, + UINTN ErrorCode, + BOOLEAN *IsValidPFAddress + ); + +/** + Create SMM page table for S3 path. + +**/ +VOID +InitSmmS3Cr3 ( + VOID + ); + +/** + Allocate pages for creating 4KB-page based on 2MB-page when page fault happens. + +**/ +VOID +InitPagesForPFHandler ( + VOID + ); + +#endif // _SMM_PROFILE_ARCH_H_ diff --git a/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni b/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni new file mode 100644 index 000000000..d4f74fd72 --- /dev/null +++ b/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni @@ -0,0 +1,16 @@ +// /** @file +// Reset Vector +// +// This VTF requires build time fixups in order to find the SEC entry point. +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Reset Vector" + +#string STR_MODULE_DESCRIPTION #language en-US "This VTF requires build time fixups in order to find the SEC entry point" + diff --git a/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni b/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni new file mode 100644 index 000000000..7d2d57939 --- /dev/null +++ b/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// ResetVector Localized Strings and Content +// +// Copyright (c) 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module" + + diff --git a/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf b/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf new file mode 100644 index 000000000..02645d868 --- /dev/null +++ b/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf @@ -0,0 +1,33 @@ +## @file +# Reset Vector +# +# This VTF requires build time fixups in order to find the SEC entry point. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ResetVector + FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 + MODULE_TYPE = SEC + VERSION_STRING = 1.1 + MODULE_UNI_FILE = ResetVector.uni + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Vtf.nasmb + +[Packages] + MdePkg/MdePkg.dec + +[UserExtensions.TianoCore."ExtraFiles"] + ResetVectorExtra.uni diff --git a/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb b/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb new file mode 100644 index 000000000..34ae5fb1f --- /dev/null +++ b/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb @@ -0,0 +1,54 @@ +;------------------------------------------------------------------------------ +; @file +; First code exectuted by processor after resetting. +; +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 16 + +ALIGN 16 ; 0xffffffd0 + +applicationProcessorEntryPoint: +; +; Application Processors entry point +; +; GenFv generates code aligned on a 4k boundary which will jump to this +; location. (0xffffffd0) This allows the Local APIC Startup IPI to be +; used to wake up the application processors. +; + jmp short resetVector + +ALIGN 16 ; 0xffffffe0 + +peiCoreEntryPoint: +; +; PEI Core entry point +; +; GenFv fills the address of the PEI Core into this location +; + DD 0x12345678 + +ALIGN 16 ; 0xfffffff0 + +resetVector: +; +; Reset Vector +; +; This is where the processor will begin execution +; + nop + nop + jmp near $ + +ALIGN 8 + +ApStartupSegment: + DD 0x12345678 + +BootFvBaseAddress: + DD 0x12345678 + +ALIGN 16 ; 0x100000000 diff --git a/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw new file mode 100644 index 000000000..2c6ff655d Binary files /dev/null and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw differ diff --git a/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw new file mode 100644 index 000000000..e34780a3a Binary files /dev/null and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw similarity index 57% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw rename to UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw index 58542ad9d..6dfa68eab 100644 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf similarity index 50% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf rename to UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf index 63e1e2cf5..8fc9564eb 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf +++ b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf @@ -1,20 +1,16 @@ ## @file # Reset Vector binary # -# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# SPDX-License-Identifier: BSD-2-Clause-Patent # ## [Defines] INF_VERSION = 0x00010005 BASE_NAME = ResetVector + MODULE_UNI_FILE = ResetVector.uni FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 MODULE_TYPE = SEC VERSION_STRING = 1.1 @@ -31,3 +27,5 @@ [Binaries.X64] RAW|ResetVector.x64.raw|* +[UserExtensions.TianoCore."ExtraFiles"] + ResetVectorExtra.uni diff --git a/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni new file mode 100644 index 000000000..3e7bcdafe --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni @@ -0,0 +1,16 @@ +// /** @file +// Reset Vector binary +// +// Reset Vector binary +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Reset Vector binary" + +#string STR_MODULE_DESCRIPTION #language en-US "Reset Vector binary" + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw similarity index 98% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw rename to UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw index 393b6ef2c..6c0bcc47e 100644 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw similarity index 97% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw rename to UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw index 7ab1161a2..a78d5b407 100644 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw differ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw similarity index 97% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw rename to UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw index f32e81ac1..61c71349a 100644 Binary files a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw and b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw differ diff --git a/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni new file mode 100644 index 000000000..7d2d57939 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// ResetVector Localized Strings and Content +// +// Copyright (c) 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module" + + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Build.py b/UefiCpuPkg/ResetVector/Vtf0/Build.py similarity index 71% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Build.py rename to UefiCpuPkg/ResetVector/Vtf0/Build.py index dad257c16..343c53b5f 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Build.py +++ b/UefiCpuPkg/ResetVector/Vtf0/Build.py @@ -1,53 +1,47 @@ -## @file -# Automate the process of building the various reset vector types -# -# Copyright (c) 2009, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# - -import glob -import os -import subprocess -import sys - -def RunCommand(commandLine): - #print ' '.join(commandLine) - return subprocess.call(commandLine) - -for filename in glob.glob(os.path.join('Bin', '*.raw')): - os.remove(filename) - -for arch in ('ia32', 'x64'): - for debugType in (None, 'port80', 'serial'): - output = os.path.join('Bin', 'ResetVector') - output += '.' + arch - if debugType is not None: - output += '.' + debugType - output += '.raw' - commandLine = ( - 'nasm', - '-D', 'ARCH_%s' % arch.upper(), - '-D', 'DEBUG_%s' % str(debugType).upper(), - '-o', output, - 'ResetVectorCode.asm', - ) - ret = RunCommand(commandLine) - print '\tASM\t' + output - if ret != 0: sys.exit(ret) - - commandLine = ( - 'python', - 'Tools/FixupForRawSection.py', - output, - ) - print '\tFIXUP\t' + output - ret = RunCommand(commandLine) - if ret != 0: sys.exit(ret) - +## @file +# Automate the process of building the various reset vector types +# +# Copyright (c) 2009, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import glob +import os +import subprocess +import sys + +def RunCommand(commandLine): + #print ' '.join(commandLine) + return subprocess.call(commandLine) + +for filename in glob.glob(os.path.join('Bin', '*.raw')): + os.remove(filename) + +for arch in ('ia32', 'x64'): + for debugType in (None, 'port80', 'serial'): + output = os.path.join('Bin', 'ResetVector') + output += '.' + arch + if debugType is not None: + output += '.' + debugType + output += '.raw' + commandLine = ( + 'nasm', + '-D', 'ARCH_%s' % arch.upper(), + '-D', 'DEBUG_%s' % str(debugType).upper(), + '-o', output, + 'Vtf0.nasmb', + ) + ret = RunCommand(commandLine) + print '\tASM\t' + output + if ret != 0: sys.exit(ret) + + commandLine = ( + 'python', + 'Tools/FixupForRawSection.py', + output, + ) + print '\tFIXUP\t' + output + ret = RunCommand(commandLine) + if ret != 0: sys.exit(ret) + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc b/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc similarity index 58% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc rename to UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc index b46da2768..7deee8b6a 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc +++ b/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc @@ -3,13 +3,7 @@ ; Common macros used in the ResetVector VTF module. ; ; Copyright (c) 2008, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ diff --git a/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm b/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm new file mode 100644 index 000000000..97f604ad0 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm @@ -0,0 +1,20 @@ +;------------------------------------------------------------------------------ +; @file +; Debug disabled +; +; Copyright (c) 2009, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 16 + +%macro debugInitialize 0 + ; + ; No initialization is required + ; +%endmacro + +%macro debugShowPostCode 1 +%endmacro + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm similarity index 66% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm index 226c49f22..cbdadee16 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm @@ -3,13 +3,7 @@ ; 16-bit initialization code ; ; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm similarity index 85% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm index 146df600a..ce4ebfffb 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm @@ -3,13 +3,7 @@ ; Transition from 16 bit real mode into 32 bit flat protected mode ; ; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -21,6 +15,12 @@ BITS 16 ; ; Modified: EAX, EBX ; +; @param[out] DS Selector allowing flat access to all addresses +; @param[out] ES Selector allowing flat access to all addresses +; @param[out] FS Selector allowing flat access to all addresses +; @param[out] GS Selector allowing flat access to all addresses +; @param[out] SS Selector allowing flat access to all addresses +; TransitionFromReal16To32BitFlat: debugShowPostCode POSTCODE_16BIT_MODE diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm similarity index 52% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm index d0830ec87..753819287 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm @@ -1,15 +1,9 @@ ;------------------------------------------------------------------------------ ; @file -; First code exectuted by processor after resetting. +; First code executed by processor after resetting. ; -; Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -17,6 +11,19 @@ BITS 16 ALIGN 16 +; +; Pad the image size to 4k when page tables are in VTF0 +; +; If the VTF0 image has page tables built in, then we need to make +; sure the end of VTF0 is 4k above where the page tables end. +; +; This is required so the page tables will be 4k aligned when VTF0 is +; located just below 0x100000000 (4GB) in the firmware device. +; +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING + TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0 +%endif + applicationProcessorEntryPoint: ; ; Application Processors entry point @@ -25,7 +32,7 @@ applicationProcessorEntryPoint: ; location. (0xffffffe0) This allows the Local APIC Startup IPI to be ; used to wake up the application processors. ; - jmp short EarlyApInitReal16 + jmp EarlyApInitReal16 ALIGN 8 @@ -50,7 +57,7 @@ resetVector: ; nop nop - jmp short EarlyBspInitReal16 + jmp EarlyBspInitReal16 ALIGN 16 diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm similarity index 55% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm index 9eba864c2..6891397c2 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm @@ -2,14 +2,8 @@ ; @file ; Transition from 32 bit flat protected mode into 64 bit flat protected mode ; -; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -20,12 +14,11 @@ BITS 32 ; Transition32FlatTo64Flat: - mov eax, ((ADDR_OF_START_OF_RESET_CODE & ~0xfff) - 0x1000) - mov cr3, eax + OneTimeCall SetCr3ForPageTables64 mov eax, cr4 bts eax, 5 ; enable PAE - mov cr4, eax + mov cr4, eax mov ecx, 0xc0000080 rdmsr diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm new file mode 100644 index 000000000..87a4125d4 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm @@ -0,0 +1,24 @@ +;------------------------------------------------------------------------------ +; @file +; Sets the CR3 register for 64-bit paging +; +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 32 + +; +; Modified: EAX +; +SetCr3ForPageTables64: + + ; + ; These pages are built into the ROM image in X64/PageTables.asm + ; + mov eax, ADDR_OF(TopLevelPageDirectory) + mov cr3, eax + + OneTimeCallRet SetCr3ForPageTables64 + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm similarity index 80% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm index d0c2d8c39..10f8e3e8b 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm @@ -3,13 +3,7 @@ ; Search for the Boot Firmware Volume (BFV) base address ; ; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm similarity index 83% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm rename to UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm index 9558b9d35..904c22df2 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm @@ -2,14 +2,8 @@ ; @file ; Search for the SEC Core entry point ; -; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -115,6 +109,7 @@ secCoreEntryPointWasFound: OneTimeCallRet Flat32SearchForSecEntryPoint %define EFI_SECTION_PE32 0x10 +%define EFI_SECTION_TE 0x12 ; ; Input: @@ -139,8 +134,11 @@ getEntryPointOfFfsFileLoopForSections: cmp byte [eax + 3], EFI_SECTION_PE32 je getEntryPointOfFfsFileFoundPe32Section + cmp byte [eax + 3], EFI_SECTION_TE + je getEntryPointOfFfsFileFoundTeSection + ; - ; The section type was not PE32, so move to next section + ; The section type was not PE32 or TE, so move to next section ; mov ebx, dword [eax] and ebx, 0x00ffffff @@ -158,26 +156,10 @@ getEntryPointOfFfsFileLoopForSections: getEntryPointOfFfsFileFoundPe32Section: add eax, 4 ; EAX = Start of PE32 image - mov ebx, eax cmp word [eax], 'MZ' - jne thereIsNotAnMzSignature + jne getEntryPointOfFfsFileErrorReturn movzx ebx, word [eax + 0x3c] add ebx, eax -thereIsNotAnMzSignature: - - ; if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) - cmp word [ebx], 'VZ' - jne thereIsNoVzSignature - ; *EntryPoint = (VOID *)((UINTN)Pe32Data + - ; (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + - ; sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - add eax, [ebx + 0x8] - add eax, 0x28 - movzx ebx, word [ebx + 0x6] - sub eax, ebx - jmp getEntryPointOfFfsFileReturn - -thereIsNoVzSignature: ; if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) cmp dword [ebx], `PE\x00\x00` @@ -188,6 +170,22 @@ thereIsNoVzSignature: add eax, [ebx + 0x4 + 0x14 + 0x10] jmp getEntryPointOfFfsFileReturn +getEntryPointOfFfsFileFoundTeSection: + add eax, 4 ; EAX = Start of TE image + mov ebx, eax + + ; if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) + cmp word [ebx], 'VZ' + jne getEntryPointOfFfsFileErrorReturn + ; *EntryPoint = (VOID *)((UINTN)Pe32Data + + ; (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + + ; sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); + add eax, [ebx + 0x8] + add eax, 0x28 + movzx ebx, word [ebx + 0x6] + sub eax, ebx + jmp getEntryPointOfFfsFileReturn + getEntryPointOfFfsFileErrorReturn: mov eax, 0 diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Main.asm b/UefiCpuPkg/ResetVector/Vtf0/Main.asm similarity index 79% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Main.asm rename to UefiCpuPkg/ResetVector/Vtf0/Main.asm index ebfb9015d..19d08482f 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Main.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Main.asm @@ -3,13 +3,7 @@ ; Main routine of the pre-SEC code up through the jump into SEC ; ; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -24,6 +18,11 @@ BITS 16 ; @param[in,out] DI 'BP': boot-strap processor, or ; 'AP': application processor ; @param[out] RBP/EBP Address of Boot Firmware Volume (BFV) +; @param[out] DS Selector allowing flat access to all addresses +; @param[out] ES Selector allowing flat access to all addresses +; @param[out] FS Selector allowing flat access to all addresses +; @param[out] GS Selector allowing flat access to all addresses +; @param[out] SS Selector allowing flat access to all addresses ; ; @return None This routine jumps to SEC and does not return ; diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm b/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm similarity index 50% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm rename to UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm index 4b13c4860..c2f43a002 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm @@ -3,13 +3,7 @@ ; Port 0x80 debug support macros ; ; Copyright (c) 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc b/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc similarity index 55% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc rename to UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc index 62eda5d99..ef74e6b71 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc +++ b/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc @@ -3,13 +3,7 @@ ; Definitions of POST CODES for the reset vector module ; ; Copyright (c) 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt b/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt similarity index 88% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt rename to UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt index 1b3d6643e..e6e5b5424 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt +++ b/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt @@ -2,7 +2,7 @@ === HOW TO USE VTF0 === Add this line to your FDF FV section: -INF RuleOverride=RESET_VECTOR USE = IA32 CloverEFI/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf +INF RuleOverride=RESET_VECTOR USE = IA32 UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf (For X64 SEC/PEI change IA32 to X64 => 'USE = X64') In your FDF FFS file rules sections add: diff --git a/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni b/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni new file mode 100644 index 000000000..afdb5de68 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni @@ -0,0 +1,16 @@ +// /** @file +// Reset Vector +// +// Reset Vector +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Reset Vector" + +#string STR_MODULE_DESCRIPTION #language en-US "Reset Vector" + diff --git a/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni b/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni new file mode 100644 index 000000000..7d2d57939 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// ResetVector Localized Strings and Content +// +// Copyright (c) 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module" + + diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm b/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm similarity index 82% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm rename to UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm index ebd0910f4..7d7b9c125 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm @@ -2,14 +2,8 @@ ; @file ; Serial port debug support macros ; -; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -107,7 +101,7 @@ BITS 16 %macro debugInitialize 0 - jmp real16InitDebug + jmp real16InitDebug real16InitDebugReturn: %endmacro diff --git a/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py b/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py new file mode 100644 index 000000000..c77438a0c --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py @@ -0,0 +1,20 @@ +## @file +# Apply fixup to VTF binary image for FFS Raw section +# +# Copyright (c) 2008, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import sys + +filename = sys.argv[1] + +d = open(sys.argv[1], 'rb').read() +c = ((len(d) + 4 + 7) & ~7) - 4 +if c > len(d): + c -= len(d) + f = open(sys.argv[1], 'wb') + f.write('\x90' * c) + f.write(d) + f.close() diff --git a/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf new file mode 100644 index 000000000..9922cb275 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf @@ -0,0 +1,31 @@ +## @file +# Reset Vector +# +# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ResetVector + FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 + MODULE_TYPE = SEC + VERSION_STRING = 1.1 + MODULE_UNI_FILE = ResetVector.uni + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Vtf0.nasmb + +[Packages] + MdePkg/MdePkg.dec + +[UserExtensions.TianoCore."ExtraFiles"] + ResetVectorExtra.uni diff --git a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ResetVectorCode.asm b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb similarity index 59% rename from CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ResetVectorCode.asm rename to UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb index 96f686b0e..493738c79 100644 --- a/CloverEFI/UefiCpuPkg/ResetVector/Vtf0/ResetVectorCode.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb @@ -2,17 +2,26 @@ ; @file ; This file includes all other code files to assemble the reset vector code ; -; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ +; +; If neither ARCH_IA32 nor ARCH_X64 are defined, then try to include +; Base.h to use the C pre-processor to determine the architecture. +; +%ifndef ARCH_IA32 + %ifndef ARCH_X64 + #include + #if defined (MDE_CPU_IA32) + %define ARCH_IA32 + #elif defined (MDE_CPU_X64) + %define ARCH_X64 + #endif + %endif +%endif + %ifdef ARCH_IA32 %ifdef ARCH_X64 %error "Only one of ARCH_IA32 or ARCH_X64 can be defined." @@ -26,14 +35,16 @@ %include "PostCodes.inc" -%ifdef DEBUG_NONE - %include "DebugDisabled.asm" -%elifdef DEBUG_PORT80 +%ifdef ARCH_X64 +%include "X64/PageTables.asm" +%endif + +%ifdef DEBUG_PORT80 %include "Port80Debug.asm" %elifdef DEBUG_SERIAL %include "SerialDebug.asm" %else - %error "No debug type was specified." + %include "DebugDisabled.asm" %endif %include "Ia32/SearchForBfvBase.asm" @@ -41,6 +52,7 @@ %ifdef ARCH_X64 %include "Ia32/Flat32ToFlat64.asm" +%include "Ia32/PageTables64.asm" %endif %include "Ia16/Real16ToFlat32.asm" diff --git a/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm b/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm new file mode 100644 index 000000000..5bc3093f9 --- /dev/null +++ b/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm @@ -0,0 +1,72 @@ +;------------------------------------------------------------------------------ +; @file +; Emits Page Tables for 1:1 mapping of the addresses 0 - 0x100000000 (4GB) +; +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 64 + +%define ALIGN_TOP_TO_4K_FOR_PAGING + +%define PAGE_PRESENT 0x01 +%define PAGE_READ_WRITE 0x02 +%define PAGE_USER_SUPERVISOR 0x04 +%define PAGE_WRITE_THROUGH 0x08 +%define PAGE_CACHE_DISABLE 0x010 +%define PAGE_ACCESSED 0x020 +%define PAGE_DIRTY 0x040 +%define PAGE_PAT 0x080 +%define PAGE_GLOBAL 0x0100 +%define PAGE_2M_MBO 0x080 +%define PAGE_2M_PAT 0x01000 + +%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \ + PAGE_ACCESSED + \ + PAGE_DIRTY + \ + PAGE_READ_WRITE + \ + PAGE_PRESENT) + +%define PAGE_PDP_ATTR (PAGE_ACCESSED + \ + PAGE_READ_WRITE + \ + PAGE_PRESENT) + +%define PGTBLS_OFFSET(x) ((x) - TopLevelPageDirectory) +%define PGTBLS_ADDR(x) (ADDR_OF(TopLevelPageDirectory) + (x)) + +%define PDP(offset) (ADDR_OF(TopLevelPageDirectory) + (offset) + \ + PAGE_PDP_ATTR) +%define PTE_2MB(x) ((x << 21) + PAGE_2M_PDE_ATTR) + +TopLevelPageDirectory: + + ; + ; Top level Page Directory Pointers (1 * 512GB entry) + ; + DQ PDP(0x1000) + + + ; + ; Next level Page Directory Pointers (4 * 1GB entries => 4GB) + ; + TIMES 0x1000-PGTBLS_OFFSET($) DB 0 + + DQ PDP(0x2000) + DQ PDP(0x3000) + DQ PDP(0x4000) + DQ PDP(0x5000) + + ; + ; Page Table Entries (2048 * 2MB entries => 4GB) + ; + TIMES 0x2000-PGTBLS_OFFSET($) DB 0 + +%assign i 0 +%rep 0x800 + DQ PTE_2MB(i) + %assign i i+1 +%endrep + +EndOfPageTables: diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c new file mode 100644 index 000000000..ee063a102 --- /dev/null +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -0,0 +1,190 @@ +/** @file + Locate the entry point for the PEI Core + + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include "SecMain.h" + +/** + Find core image base. + + @param FirmwareVolumePtr Point to the firmware volume for finding core image. + @param FileType The FileType for searching, either SecCore or PeiCore. + @param CoreImageBase The base address of the core image. + +**/ +EFI_STATUS +EFIAPI +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumePtr, + IN EFI_FV_FILETYPE FileType, + OUT EFI_PHYSICAL_ADDRESS *CoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *CoreImageBase = 0; + + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) FirmwareVolumePtr; + EndOfFirmwareVolume = CurrentAddress + FirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile = CurrentAddress + FirmwareVolumePtr->HeaderLength; ; ) { + + CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; + if (IS_FFS_FILE2 (File)) { + Size = FFS_FILE2_SIZE (File); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = FFS_FILE_SIZE (File); + if (Size < sizeof (EFI_FFS_FILE_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfFile = CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for particular Core file (either SEC Core or PEI Core) + // + if (File->Type != FileType) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + if (IS_FFS_FILE2 (File)) { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER)); + } + for (;;) { + CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + + if (IS_SECTION2 (Section)) { + Size = SECTION2_SIZE (Section); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = SECTION_SIZE (Section); + if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfSection = CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) { + if (File->Type == FileType) { + if (IS_SECTION2 (Section)) { + *CoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *CoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } + break; + } + } + + // + // Either SEC Core or PEI Core images found + // + if (*CoreImageBase != 0) { + return EFI_SUCCESS; + } + } +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report them if + remote debug is enabled. + + @param SecCoreFirmwareVolumePtr Point to the firmware volume for finding SecCore. + @param PeiCoreFirmwareVolumePtr Point to the firmware volume for finding PeiCore. + @param PeiCoreEntryPoint The entry point of the PEI core. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *SecCoreFirmwareVolumePtr, + IN EFI_FIRMWARE_VOLUME_HEADER *PeiCoreFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core image base + // + Status = FindImageBase (SecCoreFirmwareVolumePtr, EFI_FV_FILETYPE_SECURITY_CORE, &SecCoreImageBase); + ASSERT_EFI_ERROR (Status); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + // + // Report SEC Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = SecCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core image base + // + Status = FindImageBase (PeiCoreFirmwareVolumePtr, EFI_FV_FILETYPE_PEI_CORE, &PeiCoreImageBase); + ASSERT_EFI_ERROR (Status); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = PeiCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint = 0; + } + + return; +} diff --git a/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb b/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb new file mode 100644 index 000000000..f41b9669d --- /dev/null +++ b/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb @@ -0,0 +1,97 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; ResetVec.nasmb +; +; Abstract: +; +; Reset Vector Data structure +; This structure is located at 0xFFFFFFC0 +; +;------------------------------------------------------------------------------ + +; .stack 0x0 +; SECTION .text +USE16 + +; +; The layout of this file is fixed. The build tool makes assumption of the layout. +; + + ORG 0h +; +; Reserved +; +ReservedData: DD 0eeeeeeeeh, 0eeeeeeeeh + + TIMES 0x10-($-$$) DB 0 +; +; This is located at 0xFFFFFFD0h +; + mov di, "PA" + jmp ApStartup + + TIMES 0x20-($-$$) DB 0 +; +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint: DD 87654321h + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a dead loop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +global ASM_PFX(InterruptHandler) +ASM_PFX(InterruptHandler): + jmp $ + iret + + TIMES 0x30-($-$$) DB 0 +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: + nop + nop +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relative address will be fixed up by some build tool. + ; + ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in + ; SecEntry.asm + ; + DB 0e9h + DW -3 + + + TIMES 0x38-($-$$) DB 0 +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress: dd 12345678h + + TIMES 0x3c-($-$$) DB 0 +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase: DD 12345678h + +; +; Nothing can go here, otherwise the layout of this file would change. +; diff --git a/UefiCpuPkg/SecCore/SecBist.c b/UefiCpuPkg/SecCore/SecBist.c new file mode 100644 index 000000000..440140f56 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecBist.c @@ -0,0 +1,264 @@ +/** @file + Get SEC platform information(2) PPI and reinstall it. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SecMain.h" + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = { + SecPlatformInformationBist +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformation +}; + +EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2 = { + SecPlatformInformation2Bist +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2 = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformation2PpiGuid, + &mSecPlatformInformation2 +}; + +/** + Worker function to parse CPU BIST information from Guided HOB. + + @param[in, out] StructureSize Pointer to the variable describing size of the input buffer. + @param[in, out] StructureBuffer Pointer to the buffer save CPU BIST information. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +GetBistFromHob ( + IN OUT UINT64 *StructureSize, + IN OUT VOID *StructureBuffer + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + VOID *DataInHob; + UINTN DataSize; + + GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); + if (GuidHob == NULL) { + *StructureSize = 0; + return EFI_SUCCESS; + } + + DataInHob = GET_GUID_HOB_DATA (GuidHob); + DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + + // + // return the information from BistHob + // + if ((*StructureSize) < (UINT64) DataSize) { + *StructureSize = (UINT64) DataSize; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = (UINT64) DataSize; + CopyMem (StructureBuffer, DataInHob, DataSize); + return EFI_SUCCESS; +} + +/** + Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in, out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformationBist ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + return GetBistFromHob (StructureSize, PlatformInformationRecord); +} + +/** + Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in, out] StructureSize The pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to + hold the record is returned in StructureSize. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation2Bist ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 + ) +{ + return GetBistFromHob (StructureSize, PlatformInformationRecord2); +} + +/** + Worker function to get CPUs' BIST by calling SecPlatformInformationPpi + or SecPlatformInformation2Ppi. + + @param[in] PeiServices Pointer to PEI Services Table + @param[in] Guid PPI Guid + @param[out] PpiDescriptor Return a pointer to instance of the + EFI_PEI_PPI_DESCRIPTOR + @param[out] BistInformationData Pointer to BIST information data + @param[out] BistInformationSize Return the size in bytes of BIST information + + @retval EFI_SUCCESS Retrieve of the BIST data successfully + @retval EFI_NOT_FOUND No sec platform information(2) ppi export + @retval EFI_DEVICE_ERROR Failed to get CPU Information + +**/ +EFI_STATUS +GetBistInfoFromPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_GUID *Guid, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + OUT VOID **BistInformationData, + OUT UINT64 *BistInformationSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi; + EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; + UINT64 InformationSize; + + Status = PeiServicesLocatePpi ( + Guid, // GUID + 0, // INSTANCE + PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&SecPlatformInformation2Ppi // PPI + ); + if (Status == EFI_NOT_FOUND) { + return EFI_NOT_FOUND; + } + + if (Status == EFI_SUCCESS) { + // + // Get the size of the sec platform information2(BSP/APs' BIST data) + // + InformationSize = 0; + SecPlatformInformation2 = NULL; + Status = SecPlatformInformation2Ppi->PlatformInformation2 ( + PeiServices, + &InformationSize, + SecPlatformInformation2 + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Status = PeiServicesAllocatePool ( + (UINTN) InformationSize, + (VOID **) &SecPlatformInformation2 + ); + if (Status == EFI_SUCCESS) { + // + // Retrieve BIST data + // + Status = SecPlatformInformation2Ppi->PlatformInformation2 ( + PeiServices, + &InformationSize, + SecPlatformInformation2 + ); + if (Status == EFI_SUCCESS) { + *BistInformationData = SecPlatformInformation2; + if (BistInformationSize != NULL) { + *BistInformationSize = InformationSize; + } + return EFI_SUCCESS; + } + } + } + } + + return EFI_DEVICE_ERROR; +} + +/** + Get CPUs' BIST by calling SecPlatformInformationPpi/SecPlatformInformation2Ppi. + +**/ +VOID +RepublishSecPlatformInformationPpi ( + VOID + ) +{ + EFI_STATUS Status; + CONST EFI_PEI_SERVICES **PeiServices; + UINT64 BistInformationSize; + VOID *BistInformationData; + EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor; + + PeiServices = GetPeiServicesTablePointer (); + Status = GetBistInfoFromPpi ( + PeiServices, + &gEfiSecPlatformInformation2PpiGuid, + &SecInformationDescriptor, + &BistInformationData, + &BistInformationSize + ); + if (Status == EFI_SUCCESS) { + BuildGuidDataHob ( + &gEfiCallerIdGuid, + BistInformationData, + (UINTN) BistInformationSize + ); + // + // The old SecPlatformInformation2 data is on temporary memory. + // After memory discovered, we should never get it from temporary memory, + // or the data will be crashed. So, we reinstall SecPlatformInformation2 PPI here. + // + Status = PeiServicesReInstallPpi ( + SecInformationDescriptor, + &mPeiSecPlatformInformation2 + ); + } if (Status == EFI_NOT_FOUND) { + Status = GetBistInfoFromPpi ( + PeiServices, + &gEfiSecPlatformInformationPpiGuid, + &SecInformationDescriptor, + &BistInformationData, + &BistInformationSize + ); + if (Status == EFI_SUCCESS) { + BuildGuidDataHob ( + &gEfiCallerIdGuid, + BistInformationData, + (UINTN) BistInformationSize + ); + // + // The old SecPlatformInformation data is on temporary memory. + // After memory discovered, we should never get it from temporary memory, + // or the data will be crashed. So, we reinstall SecPlatformInformation PPI here. + // + Status = PeiServicesReInstallPpi ( + SecInformationDescriptor, + &mPeiSecPlatformInformation + ); + } else if (Status == EFI_NOT_FOUND) { + return; + } + } + + ASSERT_EFI_ERROR(Status); +} diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf new file mode 100644 index 000000000..0562820c9 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecCore.inf @@ -0,0 +1,80 @@ +## @file +# SecCore module that implements the SEC phase. +# +# This is the first module taking control of the platform upon power-on/reset. +# It implements the first phase of the security phase. The entry point function is +# _ModuleEntryPoint in PlatformSecLib. The entry point function will switch to +# protected mode, setup flat memory model, enable temporary memory and +# call into SecStartup(). +# +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecCore + MODULE_UNI_FILE = SecCore.uni + FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 + 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 EBC +# + +[Sources] + SecMain.c + SecMain.h + FindPeiCore.c + SecBist.c + +[Sources.IA32] + Ia32/ResetVec.nasmb + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + PlatformSecLib + PcdLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + CpuExceptionHandlerLib + ReportStatusCodeLib + PeiServicesLib + PeiServicesTablePointerLib + HobLib + +[Ppis] + ## SOMETIMES_CONSUMES + ## PRODUCES + gEfiSecPlatformInformationPpiGuid + ## SOMETIMES_CONSUMES + ## SOMETIMES_PRODUCES + gEfiSecPlatformInformation2PpiGuid + gEfiTemporaryRamDonePpiGuid ## PRODUCES + ## NOTIFY + ## SOMETIMES_CONSUMES + gPeiSecPerformancePpiGuid + gEfiPeiCoreFvLocationPpiGuid + +[Guids] + ## SOMETIMES_PRODUCES ## HOB + gEfiFirmwarePerformanceGuid + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + +[UserExtensions.TianoCore."ExtraFiles"] + SecCoreExtra.uni diff --git a/UefiCpuPkg/SecCore/SecCore.uni b/UefiCpuPkg/SecCore/SecCore.uni new file mode 100644 index 000000000..1ecf928b9 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecCore.uni @@ -0,0 +1,18 @@ +// /** @file +// SecCore module that implements the SEC phase. +// +// This is the first module taking control of the platform upon power-on/reset. +// It implements the first phase of the security phase. The entry point function is +// _ModuleEntryPoint in PlatformSecLib. The entry point function will switch to +// protected mode, setup flat memory model, enable temporary memory and +// call into SecStartup(). +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "SecCore module that implements the SEC phase" + +#string STR_MODULE_DESCRIPTION #language en-US "This is the first module taking control of the platform upon power-on/reset. It implements the first phase of the security phase. The entry point function is _ModuleEntryPoint in PlatformSecLib. The entry point function will switch to protected mode, will setup flat memory model, will enable temporary memory and will call into SecStartup()." diff --git a/UefiCpuPkg/SecCore/SecCoreExtra.uni b/UefiCpuPkg/SecCore/SecCoreExtra.uni new file mode 100644 index 000000000..4b582f1d6 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecCoreExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// SecCore Localized Strings and Content +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"SEC Core Module" diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c new file mode 100644 index 000000000..5d5e7f17d --- /dev/null +++ b/UefiCpuPkg/SecCore/SecMain.c @@ -0,0 +1,401 @@ +/** @file + C functions in SEC + + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SecMain.h" + +EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = { + SecTemporaryRamDone +}; + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation }; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { + { + // + // SecPerformance PPI notify descriptor. + // + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + &gPeiSecPerformancePpiGuid, + (VOID *) (UINTN) SecPerformancePpiCallBack + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiTemporaryRamDonePpiGuid, + &gSecTemporaryRamDonePpi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformationPpi + } +}; + +// +// These are IDT entries pointing to 10:FFFFFFE4h. +// +UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL; + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +NORETURN +EFIAPI +SecStartupPhase2( + IN VOID *Context + ); + +/** + Entry point of the notification callback function itself within the PEIM. + It is to get SEC performance data and build HOB to convey the SEC performance + data to DXE phase. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @return Status of the notification. + The status code returned from this function is ignored. +**/ +EFI_STATUS +EFIAPI +SecPerformancePpiCallBack ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + PEI_SEC_PERFORMANCE_PPI *SecPerf; + FIRMWARE_SEC_PERFORMANCE Performance; + + SecPerf = (PEI_SEC_PERFORMANCE_PPI *) Ppi; + Status = SecPerf->GetPerformance ((CONST EFI_PEI_SERVICES **) PeiServices, SecPerf, &Performance); + if (!EFI_ERROR (Status)) { + BuildGuidDataHob ( + &gEfiFirmwarePerformanceGuid, + &Performance, + sizeof (FIRMWARE_SEC_PERFORMANCE) + ); + DEBUG ((DEBUG_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd)); + } + + return Status; +} + +/** + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + + @param SizeOfRam Size of the temporary memory available for use. + @param TempRamBase Base address of temporary ram + @param BootFirmwareVolume Base address of the Boot Firmware Volume. +**/ +VOID +NORETURN +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + IA32_DESCRIPTOR IdtDescriptor; + SEC_IDT_TABLE IdtTableInStack; + UINT32 Index; + UINT32 PeiStackSize; + EFI_STATUS Status; + + // + // Report Status Code to indicate entering SEC core + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_ENTRY_POINT + ); + + PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (SizeOfRam >> 1); + } + + ASSERT (PeiStackSize < SizeOfRam); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + // |-------------------|----> + // |IDT Table | + // |-------------------| + // |PeiService Pointer | PeiStackSize + // |-------------------| + // | | + // | Stack | + // |-------------------|----> + // | | + // | | + // | Heap | PeiTemporayRamSize + // | | + // | | + // |-------------------|----> TempRamBase + + IdtTableInStack.PeiService = 0; + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64)); + } + + IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; + IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + + // + // Setup the default exception handlers + // + Status = InitializeCpuExceptionHandlers (NULL); + ASSERT_EFI_ERROR (Status); + + // + // Update the base address and length of Pei temporary memory + // + SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; + SecCoreData.BootFirmwareVolumeSize = (UINTN)((EFI_FIRMWARE_VOLUME_HEADER *) BootFirmwareVolume)->FvLength; + SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase; + SecCoreData.TemporaryRamSize = SizeOfRam; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize; + SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = PeiStackSize; + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2); + + // + // Should not come here. + // + UNREACHABLE (); +} + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +NORETURN +EFIAPI +SecStartupPhase2( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINT32 Index; + EFI_PEI_PPI_DESCRIPTOR *AllSecPpiList; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + PeiCoreEntryPoint = NULL; + SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context; + + // + // Perform platform specific initialization before entering PeiCore. + // + PpiList = SecPlatformMain (SecCoreData); + // + // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug + // is enabled. + // + if (PpiList != NULL) { + Index = 0; + do { + if (CompareGuid (PpiList[Index].Guid, &gEfiPeiCoreFvLocationPpiGuid) && + (((EFI_PEI_CORE_FV_LOCATION_PPI *) PpiList[Index].Ppi)->PeiCoreFvLocation != 0) + ) { + // + // In this case, SecCore is in BFV but PeiCore is in another FV reported by PPI. + // + FindAndReportEntryPoints ( + (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, + (EFI_FIRMWARE_VOLUME_HEADER *) ((EFI_PEI_CORE_FV_LOCATION_PPI *) PpiList[Index].Ppi)->PeiCoreFvLocation, + &PeiCoreEntryPoint + ); + if (PeiCoreEntryPoint != NULL) { + break; + } else { + // + // Invalid PeiCore FV provided by platform + // + CpuDeadLoop (); + } + } + } while ((PpiList[Index++].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + } + // + // If EFI_PEI_CORE_FV_LOCATION_PPI not found, try to locate PeiCore from BFV. + // + if (PeiCoreEntryPoint == NULL) { + // + // Both SecCore and PeiCore are in BFV. + // + FindAndReportEntryPoints ( + (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, + (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, + &PeiCoreEntryPoint + ); + if (PeiCoreEntryPoint == NULL) { + CpuDeadLoop (); + } + } + + if (PpiList != NULL) { + AllSecPpiList = (EFI_PEI_PPI_DESCRIPTOR *) SecCoreData->PeiTemporaryRamBase; + + // + // Remove the terminal flag from the terminal PPI + // + CopyMem (AllSecPpiList, mPeiSecPlatformInformationPpi, sizeof (mPeiSecPlatformInformationPpi)); + Index = sizeof (mPeiSecPlatformInformationPpi) / sizeof (EFI_PEI_PPI_DESCRIPTOR) - 1; + AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + + // + // Append the platform additional PPI list + // + Index += 1; + while (((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) { + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + Index++; + PpiList++; + } + + // + // Add the terminal PPI + // + CopyMem (&AllSecPpiList[Index ++], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + + // + // Set PpiList to the total PPI + // + PpiList = AllSecPpiList; + + // + // Adjust PEI TEMP RAM Range. + // + ASSERT (SecCoreData->PeiTemporaryRamSize > Index * sizeof (EFI_PEI_PPI_DESCRIPTOR)); + SecCoreData->PeiTemporaryRamBase = (VOID *)((UINTN) SecCoreData->PeiTemporaryRamBase + Index * sizeof (EFI_PEI_PPI_DESCRIPTOR)); + SecCoreData->PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize - Index * sizeof (EFI_PEI_PPI_DESCRIPTOR); + // + // Adjust the Base and Size to be 8-byte aligned as HOB which has 8byte aligned requirement + // will be built based on them in PEI phase. + // + SecCoreData->PeiTemporaryRamBase = (VOID *)(((UINTN)SecCoreData->PeiTemporaryRamBase + 7) & ~0x07); + SecCoreData->PeiTemporaryRamSize &= ~(UINTN)0x07; + } else { + // + // No addition PPI, PpiList directly point to the common PPI list. + // + PpiList = &mPeiSecPlatformInformationPpi[0]; + } + + DEBUG (( + DEBUG_INFO, + "%a() Stack Base: 0x%p, Stack Size: 0x%x\n", + __FUNCTION__, + SecCoreData->StackBase, + (UINT32) SecCoreData->StackSize + )); + + // + // Report Status Code to indicate transferring to PEI core + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_SOFTWARE_SEC | EFI_SW_SEC_PC_HANDOFF_TO_NEXT + ); + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint != NULL); + (*PeiCoreEntryPoint) (SecCoreData, PpiList); + + // + // Should not come here. + // + UNREACHABLE (); +} + +/** + TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked + by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed. + + @retval EFI_SUCCESS Use of Temporary RAM was disabled. + @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamDone ( + VOID + ) +{ + BOOLEAN State; + + // + // Republish Sec Platform Information(2) PPI + // + RepublishSecPlatformInformationPpi (); + + // + // Migrate DebugAgentContext. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + + // + // Disable interrupts and save current interrupt state + // + State = SaveAndDisableInterrupts(); + + // + // Disable Temporary RAM after Stack and Heap have been migrated at this point. + // + SecPlatformDisableTemporaryMemory (); + + // + // Restore original interrupt state + // + SetInterruptState (State); + + return EFI_SUCCESS; +} diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h new file mode 100644 index 000000000..e8c05d713 --- /dev/null +++ b/UefiCpuPkg/SecCore/SecMain.h @@ -0,0 +1,179 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + // + // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base + // address should be 8-byte alignment. + // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store + // EFI_PEI_SERVICES** + // + UINT64 PeiService; + UINT64 IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +/** + TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked + by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed. + + @retval EFI_SUCCESS Use of Temporary RAM was disabled. + @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamDone ( + VOID + ); + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param SizeOfRam Size of the temporary memory available for use. + @param TempRamBase Base address of temporary ram + @param BootFirmwareVolume Base address of the Boot Firmware Volume. +**/ +VOID +NORETURN +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ); + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report them if + remote debug is enabled. + + @param SecCoreFirmwareVolumePtr Point to the firmware volume for finding SecCore. + @param PeiCoreFirmwareVolumePtr Point to the firmware volume for finding PeiCore. + @param PeiCoreEntryPoint The entry point of the PEI core. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *SecCoreFirmwareVolumePtr, + IN EFI_FIRMWARE_VOLUME_HEADER *PeiCoreFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ); + +/** + Auto-generated function that calls the library constructors for all of the module's + dependent libraries. This function must be called by the SEC Core once a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +/** + Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI. + + @param PeiServices Pointer to the PEI Services Table. + @param StructureSize Pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformationBist ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. + + @param PeiServices The pointer to the PEI Services Table. + @param StructureSize The pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to + hold the record is returned in StructureSize. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation2Bist ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 + ); + +/** + Republish SecPlatformInformationPpi/SecPlatformInformation2Ppi. + +**/ +VOID +RepublishSecPlatformInformationPpi ( + VOID + ); + +/** + Entry point of the notification callback function itself within the PEIM. + It is to get SEC performance data and build HOB to convey the SEC performance + data to DXE phase. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @return Status of the notification. + The status code returned from this function is ignored. +**/ +EFI_STATUS +EFIAPI +SecPerformancePpiCallBack ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +#endif diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml new file mode 100644 index 000000000..99e460a8b --- /dev/null +++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml @@ -0,0 +1,51 @@ +## @file +# CI configuration for UefiCpuPkg +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "CompilerPlugin": { + "DscPath": "UefiCpuPkg.dsc" + }, + "CharEncodingCheck": { + "IgnoreFiles": [] + }, + "DependencyCheck": { + "AcceptableDependencies": [ + "MdePkg/MdePkg.dec", + "MdeModulePkg/MdeModulePkg.dec", + "UefiCpuPkg/UefiCpuPkg.dec" + ], + # For host based unit tests + "AcceptableDependencies-HOST_APPLICATION":[], + # For UEFI shell based apps + "AcceptableDependencies-UEFI_APPLICATION":[], + "IgnoreInf": [] + }, + "DscCompleteCheck": { + "DscPath": "UefiCpuPkg.dsc", + "IgnoreInf": [ + "UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf", + "UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf" + ] + }, + "GuidCheck": { + "IgnoreGuidName": ["SecCore", "ResetVector"], # Expected duplication for gEfiFirmwareVolumeTopFileGuid + "IgnoreGuidValue": [], + "IgnoreFoldersAndFiles": [], + "IgnoreDuplicates": [] + }, + "LibraryClassCheck": { + "IgnoreHeaderFile": [] + }, + + ## options defined ci/Plugin/SpellCheck + "SpellCheck": { + "AuditOnly": True, # Fails test but run in AuditOnly mode to collect log + "IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files + "ExtendWords": [], # words to extend to the dictionary for this package + "IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore + "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported) + } +} diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec new file mode 100644 index 000000000..762badf5d --- /dev/null +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -0,0 +1,374 @@ +## @file UefiCpuPkg.dec +# This Package provides UEFI compatible CPU modules and libraries. +# +# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = UefiCpuPkg + PACKAGE_UNI_FILE = UefiCpuPkg.uni + PACKAGE_GUID = 2171df9b-0d39-45aa-ac37-2de190010d23 + PACKAGE_VERSION = 0.90 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Defines some routines that are generic for IA32 family CPU + ## to be UEFI specification compliant. + ## + UefiCpuLib|Include/Library/UefiCpuLib.h + + ## @libraryclass Defines some routines that are used to register/manage/program + ## CPU features. + ## + RegisterCpuFeaturesLib|Include/Library/RegisterCpuFeaturesLib.h + +[LibraryClasses.IA32, LibraryClasses.X64] + ## @libraryclass Provides functions to manage MTRR settings on IA32 and X64 CPUs. + ## + MtrrLib|Include/Library/MtrrLib.h + + ## @libraryclass Provides functions to manage the Local APIC on IA32 and X64 CPUs. + ## + LocalApicLib|Include/Library/LocalApicLib.h + + ## @libraryclass Provides platform specific initialization functions in the SEC phase. + ## + PlatformSecLib|Include/Library/PlatformSecLib.h + + ## @libraryclass Public include file for the SMM CPU Platform Hook Library. + ## + SmmCpuPlatformHookLib|Include/Library/SmmCpuPlatformHookLib.h + + ## @libraryclass Provides the CPU specific programming for PiSmmCpuDxeSmm module. + ## + SmmCpuFeaturesLib|Include/Library/SmmCpuFeaturesLib.h + + ## @libraryclass Provides functions to support MP services on CpuMpPei and CpuDxe module. + ## + MpInitLib|Include/Library/MpInitLib.h + +[Guids] + gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} + gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} + + ## Include/Guid/CpuFeaturesSetDone.h + gEdkiiCpuFeaturesSetDoneGuid = { 0xa82485ce, 0xad6b, 0x4101, { 0x99, 0xd3, 0xe1, 0x35, 0x8c, 0x9e, 0x7e, 0x37 }} + + ## Include/Guid/CpuFeaturesInitDone.h + gEdkiiCpuFeaturesInitDoneGuid = { 0xc77c3a41, 0x61ab, 0x4143, { 0x98, 0x3e, 0x33, 0x39, 0x28, 0x6, 0x28, 0xe5 }} + + ## Include/Guid/MicrocodePatchHob.h + gEdkiiMicrocodePatchHobGuid = { 0xd178f11d, 0x8716, 0x418e, { 0xa1, 0x31, 0x96, 0x7d, 0x2a, 0xc4, 0x28, 0x43 }} + +[Protocols] + ## Include/Protocol/SmmCpuService.h + gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }} + + ## Include/Protocol/SmMonitorInit.h + gEfiSmMonitorInitProtocolGuid = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }} + +# +# [Error.gUefiCpuPkgTokenSpaceGuid] +# 0x80000001 | Invalid value provided. +# + +[Ppis] + gEdkiiPeiMpServices2PpiGuid = { 0x5cb9cb3d, 0x31a4, 0x480c, { 0x94, 0x98, 0x29, 0xd2, 0x69, 0xba, 0xcf, 0xba}} + + ## Include/Ppi/ShadowMicrocode.h + gEdkiiPeiShadowMicrocodePpiGuid = { 0x430f6965, 0x9a69, 0x41c5, { 0x93, 0xed, 0x8b, 0xf0, 0x64, 0x35, 0xc1, 0xc6 }} + +[PcdsFeatureFlag] + ## Indicates if SMM Profile will be enabled. + # If enabled, instruction executions in and data accesses to memory outside of SMRAM will be logged. + # In X64 build, it could not be enabled when PcdCpuSmmRestrictedMemoryAccess is TRUE. + # In IA32 build, the page table memory is not marked as read-only when it is enabled. + # This PCD is only for validation purpose. It should be set to false in production.

+ # TRUE - SMM Profile will be enabled.
+ # FALSE - SMM Profile will be disabled.
+ # @Prompt Enable SMM Profile. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable|FALSE|BOOLEAN|0x32132109 + + ## Indicates if the SMM profile log buffer is a ring buffer. + # If disabled, no additional log can be done when the buffer is full.

+ # TRUE - the SMM profile log buffer is a ring buffer.
+ # FALSE - the SMM profile log buffer is a normal buffer.
+ # @Prompt The SMM profile log buffer is a ring buffer. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileRingBuffer|FALSE|BOOLEAN|0x3213210a + + ## Indicates if SMM Startup AP in a blocking fashion. + # TRUE - SMM Startup AP in a blocking fashion.
+ # FALSE - SMM Startup AP in a non-blocking fashion.
+ # @Prompt SMM Startup AP in a blocking fashion. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|FALSE|BOOLEAN|0x32132108 + + ## Indicates if SMM Stack Guard will be enabled. + # If enabled, stack overflow in SMM can be caught, preventing chaotic consequences.

+ # TRUE - SMM Stack Guard will be enabled.
+ # FALSE - SMM Stack Guard will be disabled.
+ # @Prompt Enable SMM Stack Guard. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard|TRUE|BOOLEAN|0x1000001C + + ## Indicates if BSP election in SMM will be enabled. + # If enabled, a BSP will be dynamically elected among all processors in each SMI. + # Otherwise, processor 0 is always as BSP in each SMI.

+ # TRUE - BSP election in SMM will be enabled.
+ # FALSE - BSP election in SMM will be disabled.
+ # @Prompt Enable BSP election in SMM. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|TRUE|BOOLEAN|0x32132106 + + ## Indicates if CPU SMM hot-plug will be enabled.

+ # TRUE - SMM CPU hot-plug will be enabled.
+ # FALSE - SMM CPU hot-plug will be disabled.
+ # @Prompt SMM CPU hot-plug. + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport|FALSE|BOOLEAN|0x3213210C + + ## Indicates if SMM Debug will be enabled. + # If enabled, hardware breakpoints in SMRAM can be set outside of SMM mode and take effect in SMM.

+ # TRUE - SMM Debug will be enabled.
+ # FALSE - SMM Debug will be disabled.
+ # @Prompt Enable SMM Debug. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|FALSE|BOOLEAN|0x1000001B + + ## Indicates if lock SMM Feature Control MSR.

+ # TRUE - SMM Feature Control MSR will be locked.
+ # FALSE - SMM Feature Control MSR will not be locked.
+ # @Prompt Lock SMM Feature Control MSR. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock|TRUE|BOOLEAN|0x3213210B + +[PcdsFixedAtBuild] + ## List of exception vectors which need switching stack. + # This PCD will only take into effect if PcdCpuStackGuard is enabled. + # By default exception #DD(8), #PF(14) are supported. + # @Prompt Specify exception vectors which need switching stack. + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList|{0x08, 0x0E}|VOID*|0x30002000 + + ## Size of good stack for an exception. + # This PCD will only take into effect if PcdCpuStackGuard is enabled. + # @Prompt Specify size of good stack of exception which need switching stack. + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize|2048|UINT32|0x30002001 + + ## Count of pre allocated SMM MP tokens per chunk. + # @Prompt Specify the count of pre allocated SMM MP tokens per chunk. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk|64|UINT32|0x30002002 + +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## This value is the CPU Local APIC base address, which aligns the address on a 4-KByte boundary. + # @Prompt Configure base address of CPU Local APIC + # @Expression 0x80000001 | (gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress & 0xfff) == 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress|0xfee00000|UINT32|0x00000001 + + ## Specifies delay value in microseconds after sending out an INIT IPI. + # @Prompt Configure delay value after send an INIT IPI + gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|10000|UINT32|0x30000002 + + ## This value specifies the Application Processor (AP) stack size, used for Mp Service, which must + ## aligns the address on a 4-KByte boundary. + # @Prompt Configure stack size for Application Processor (AP) + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize|0x8000|UINT32|0x00000003 + + ## Specifies stack size in the temporary RAM. 0 means half of TemporaryRamSize. + # @Prompt Stack size in the temporary RAM. + gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x10001003 + + ## 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 + + ## Specifies stack size in bytes for each processor in SMM. + # @Prompt Processor stack size in SMM. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x2000|UINT32|0x32132105 + + ## Specifies shadow stack size in bytes for each processor in SMM. + # @Prompt Processor shadow stack size in SMM. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize|0x2000|UINT32|0x3213210E + + ## Indicates if SMM Code Access Check is enabled. + # If enabled, the SMM handler cannot execute the code outside SMM regions. + # This PCD is suggested to TRUE in production image.

+ # TRUE - SMM Code Access Check will be enabled.
+ # FALSE - SMM Code Access Check will be disabled.
+ # @Prompt SMM Code Access Check. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable|TRUE|BOOLEAN|0x60000013 + + ## Specifies the number of variable MTRRs reserved for OS use. The default number of + # MTRRs reserved for OS use is 2. + # @Prompt Number of reserved variable MTRRs. + gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0x2|UINT32|0x00000015 + + ## Specifies buffer size in bytes for STM exception stack. The value should be a multiple of 4KB. + # @Prompt STM exception stack size. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStmExceptionStackSize|0x1000|UINT32|0x32132111 + + ## Specifies buffer size in bytes of MSEG. The value should be a multiple of 4KB. + # @Prompt MSEG size. + gUefiCpuPkgTokenSpaceGuid.PcdCpuMsegSize|0x200000|UINT32|0x32132112 + + ## Specifies the supported CPU features bit in array. + # @Prompt Supported CPU features. + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSupport|{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}|VOID*|0x00000016 + + ## Specifies if CPU features will be initialized after SMM relocation. + # @Prompt If CPU features will be initialized after SMM relocation. + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitAfterSmmRelocation|FALSE|BOOLEAN|0x0000001C + + ## Specifies if CPU features will be initialized during S3 resume. + # @Prompt If CPU features will be initialized during S3 resume. + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|FALSE|BOOLEAN|0x0000001D + + ## Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency. + # TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX. + # Intel Xeon Processor Scalable Family with CPUID signature 06_55H = 25000000 (25MHz) + # 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family = 24000000 (24MHz) + # Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH = 19200000 (19.2MHz) + # @Prompt This PCD is the nominal frequency of the core crystal clock in Hz as is CPUID Leaf 0x15:ECX + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency|24000000|UINT64|0x32132113 + + ## Specifies the periodic interval value in microseconds for the status check + # of APs for StartupAllAPs() and StartupThisAP() executed in non-blocking + # mode in DXE phase. + # @Prompt Periodic interval value in microseconds for AP status check in DXE. + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds|100000|UINT32|0x0000001E + +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] + ## Specifies max supported number of Logical Processors. + # @Prompt Configure max supported number of Logical Processors + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64|UINT32|0x00000002 + ## Specifies timeout value in microseconds for the BSP to detect all APs for the first time. + # @Prompt Timeout for the BSP to detect all APs for the first time. + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000|UINT32|0x00000004 + ## Specifies the number of Logical Processors that are available in the + # preboot environment after platform reset, including BSP and APs. Possible + # values:

+ # zero (default) - PcdCpuBootLogicalProcessorNumber is ignored, and + # PcdCpuApInitTimeOutInMicroSeconds limits the initial AP + # detection by the BSP.
+ # nonzero - PcdCpuApInitTimeOutInMicroSeconds is ignored. The initial + # AP detection finishes only when the detected CPU count + # (BSP plus APs) reaches the value of + # PcdCpuBootLogicalProcessorNumber, regardless of how long + # that takes.
+ # @Prompt Number of Logical Processors available after platform reset. + gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber|0|UINT32|0x00000008 + ## Specifies the base address of the first microcode Patch in the microcode Region. + # @Prompt Microcode Region base address. + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x00000005 + ## Specifies the size of the microcode Region. + # @Prompt Microcode Region size. + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x00000006 + ## Specifies the AP wait loop state during POST phase. + # The value is defined as below.

+ # 1: Place AP in the Hlt-Loop state.
+ # 2: Place AP in the Mwait-Loop state.
+ # 3: Place AP in the Run-Loop state.
+ # @Prompt The AP wait loop state. + # @ValidRange 0x80000001 | 1 - 3 + gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode|1|UINT8|0x60008006 + ## Specifies the AP target C-state for Mwait during POST phase. + # The default value 0 means C1 state. + # The value is defined as below.

+ # @Prompt The specified AP target C-state for Mwait. + gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0|UINT8|0x00000007 + + ## Specifies timeout value in microseconds for the BSP in SMM to wait for all APs to come into SMM. + # @Prompt AP synchronization timeout value in SMM. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000000|UINT64|0x32132104 + + ## Indicates the CPU synchronization method used when processing an SMI. + # 0x00 - Traditional CPU synchronization method.
+ # 0x01 - Relaxed CPU synchronization method.
+ # @Prompt SMM CPU Synchronization Method. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x00|UINT8|0x60000014 + + ## Specifies the On-demand clock modulation duty cycle when ACPI feature is enabled. + # @Prompt The encoded values for target duty cycle modulation. + # @ValidRange 0x80000001 | 0 - 15 + gUefiCpuPkgTokenSpaceGuid.PcdCpuClockModulationDutyCycle|0x0|UINT8|0x0000001A + + ## Indicates if the current boot is a power-on reset.

+ # TRUE - Current boot is a power-on reset.
+ # FALSE - Current boot is not a power-on reset.
+ # @Prompt Current boot is a power-on reset. + gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset|FALSE|BOOLEAN|0x0000001B + +[PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, PcdsDynamicEx.X64] + ## Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock. + # MMIO access is always allowed regardless of the value of this PCD. + # Loose of such restriction is only required by RAS components in X64 platforms. + # The PCD value is considered as constantly TRUE in IA32 platforms. + # When the PCD value is TRUE, page table is initialized to cover all memory spaces + # and the memory occupied by page table is protected by page table itself as read-only. + # In X64 build, it cannot be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable). + # In X64 build, it could not be enabled also at the same time with heap guard feature for SMM + # (PcdHeapGuardPropertyMask in MdeModulePkg). + # In IA32 build, page table memory is not marked as read-only when either SMM profile feature (PcdCpuSmmProfileEnable) + # or heap guard feature for SMM (PcdHeapGuardPropertyMask in MdeModulePkg) is enabled. + # TRUE - Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
+ # FALSE - Access to any type of non-SMRAM memory after SmmReadyToLock is allowed.
+ # @Prompt Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock. + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess|TRUE|BOOLEAN|0x3213210F + +[PcdsDynamic, PcdsDynamicEx] + ## Contains the pointer to a CPU S3 data buffer of structure ACPI_CPU_DATA. + # @Prompt The pointer to a CPU S3 data buffer. + # @ValidList 0x80000001 | 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0x0|UINT64|0x60000010 + + ## Contains the pointer to a CPU Hot Plug Data structure if CPU hot-plug is supported. + # @Prompt The pointer to CPU Hot Plug Data. + # @ValidList 0x80000001 | 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress|0x0|UINT64|0x60000011 + + ## Indicates processor feature capabilities, each bit corresponding to a specific feature. + # @Prompt Processor feature capabilities. + # @ValidList 0x80000001 | 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesCapability|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}|VOID*|0x00000018 + + ## As input, specifies user's desired settings for enabling/disabling processor features. + ## As output, specifies actual settings for processor features, each bit corresponding to a specific feature. + # @Prompt As input, specifies user's desired processor feature settings. As output, specifies actual processor feature settings. + # @ValidList 0x80000001 | 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesSetting|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}|VOID*|0x00000019 + + ## Contains the size of memory required when CPU processor trace is enabled.

+ # Processor trace is enabled through set BIT44(CPU_FEATURE_PROC_TRACE) in PcdCpuFeaturesSetting.

+ # This PCD is ignored if CPU processor trace is disabled.

+ # Default value is 0x00 which means 4KB of memory is allocated if CPU processor trace is enabled.
+ # 0x0 - 4K.
+ # 0x1 - 8K.
+ # 0x2 - 16K.
+ # 0x3 - 32K.
+ # 0x4 - 64K.
+ # 0x5 - 128K.
+ # 0x6 - 256K.
+ # 0x7 - 512K.
+ # 0x8 - 1M.
+ # 0x9 - 2M.
+ # 0xA - 4M.
+ # 0xB - 8M.
+ # 0xC - 16M.
+ # 0xD - 32M.
+ # 0xE - 64M.
+ # 0xF - 128M.
+ # @Prompt The memory size used for processor trace if processor trace is enabled. + # @ValidRange 0x80000001 | 0 - 0xF + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize|0x0|UINT32|0x60000012 + + ## Contains the processor trace output scheme when CPU processor trace is enabled.

+ # Processor trace is enabled through set BIT44(CPU_FEATURE_PROC_TRACE) in PcdCpuFeaturesSetting.

+ # This PCD is ignored if CPU processor trace is disabled.

+ # Default value is 0 which means single range output scheme will be used if CPU processor trace is enabled.
+ # 0 - Single Range output scheme.
+ # 1 - ToPA(Table of physical address) scheme.
+ # @Prompt The processor trace output scheme used when processor trace is enabled. + # @ValidRange 0x80000001 | 0 - 1 + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme|0x0|UINT8|0x60000015 + +[UserExtensions.TianoCore."ExtraFiles"] + UefiCpuPkgExtra.uni diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc new file mode 100644 index 000000000..afa304128 --- /dev/null +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -0,0 +1,160 @@ +## @file +# UefiCpuPkg Package +# +# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME = UefiCpu + PLATFORM_GUID = a1b7be22-78b3-4260-9569-8649e8c17d49 + PLATFORM_VERSION = 0.90 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/UefiCpu + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +# +# External libraries to build package +# + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf + PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf + SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf + SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + +[LibraryClasses.common.SEC] + PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf +!if $(TOOL_CHAIN_TAG) == "XCODE5" + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf +!else + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +!endif + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + +[LibraryClasses.common.PEIM] + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf + RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf + +[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf + +[LibraryClasses.common.DXE_DRIVER] + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf + MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +# +# Drivers/Libraries within this package +# + +[Components] + UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + UefiCpuPkg/CpuIoPei/CpuIoPei.inf + UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf + UefiCpuPkg/Application/Cpuid/Cpuid.inf + UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf + UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf + UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf + +[Components.IA32, Components.X64] + UefiCpuPkg/CpuDxe/CpuDxe.inf + UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf { + + NULL|UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf + } + UefiCpuPkg/CpuFeatures/CpuFeaturesDxe.inf { + + NULL|UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf + } + UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf + UefiCpuPkg/CpuMpPei/CpuMpPei.inf + UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf + UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf + UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +!if $(TOOL_CHAIN_TAG) != "XCODE5" + UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +!endif + UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf + UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf + UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf + UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf + UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf + UefiCpuPkg/Library/MtrrLib/MtrrLib.inf + UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf + UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf + UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf + UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf + UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf + UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf + UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf + UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf + UefiCpuPkg/SecCore/SecCore.inf + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { + + FILE_GUID = D1D74FE9-7A4E-41D3-A0B3-67F13AD34D94 + + SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf + } + UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf + UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf + +[BuildOptions] + *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni new file mode 100644 index 000000000..1780dfdc1 --- /dev/null +++ b/UefiCpuPkg/UefiCpuPkg.uni @@ -0,0 +1,280 @@ +// /** @file +// This Package provides UEFI compatible CPU modules and libraries. +// +// This Package provides UEFI compatible CPU modules and libraries. +// +// Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PACKAGE_ABSTRACT #language en-US "Provides UEFI compatible CPU modules and libraries" + +#string STR_PACKAGE_DESCRIPTION #language en-US "This Package provides UEFI compatible CPU modules and libraries." + + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuLocalApicBaseAddress_PROMPT #language en-US "Configure base address of CPU Local APIC" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuLocalApicBaseAddress_HELP #language en-US "This value is the CPU Local APIC base address, which aligns the address on a 4-KByte boundary." + +#string STR_gUefiCpuPkgTokenSpaceGuid_ERR_80000001 #language en-US "Invalid value provided." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuInitIpiDelayInMicroSeconds_PROMPT #language en-US "Configure delay value after send an INIT IPI" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuInitIpiDelayInMicroSeconds_HELP #language en-US "Specifies delay value in microseconds after sending out an INIT IPI." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMaxLogicalProcessorNumber_PROMPT #language en-US "Configure max supported number of Logical Processors" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMaxLogicalProcessorNumber_HELP #language en-US "Specifies max supported number of Logical Processors." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStackSize_PROMPT #language en-US "Configure stack size for Application Processor (AP)" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStackSize_HELP #language en-US "This value specifies the Application Processor (AP) stack size, used for Mp Service, which must\n" + "aligns the address on a 4-KByte boundary." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApInitTimeOutInMicroSeconds_PROMPT #language en-US "Timeout for the BSP to detect all APs for the first time." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApInitTimeOutInMicroSeconds_HELP #language en-US "Specifies timeout value in microseconds for the BSP to detect all APs for the first time." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuBootLogicalProcessorNumber_PROMPT #language en-US "Number of Logical Processors available after platform reset." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuBootLogicalProcessorNumber_HELP #language en-US "Specifies the number of Logical Processors that are available in the preboot environment after platform reset, including BSP and APs." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMicrocodePatchAddress_PROMPT #language en-US "Microcode Region base address." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMicrocodePatchAddress_HELP #language en-US "Specifies the base address of the first microcode Patch in the microcode Region." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMicrocodePatchRegionSize_PROMPT #language en-US "Microcode Region size." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMicrocodePatchRegionSize_HELP #language en-US "Specifies the size of the microcode Region." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileEnable_PROMPT #language en-US "Enable SMM Profile" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileEnable_HELP #language en-US "Indicates if SMM Profile will be enabled.\n" + "If enabled, instruction executions in and data accesses to memory outside of SMRAM will be logged.\n" + "It could not be enabled at the same time with SMM static page table feature (PcdCpuSmmStaticPageTable).\n" + "This PCD is only for validation purpose. It should be set to false in production.

\n" + "TRUE - SMM Profile will be enabled.
\n" + "FALSE - SMM Profile will be disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileRingBuffer_PROMPT #language en-US "The SMM profile log buffer is a ring buffer" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileRingBuffer_HELP #language en-US "Indicates if the SMM profile log buffer is a ring buffer. If disabled, no additional log can be done when the buffer is full.

\n" + "TRUE - the SMM profile log buffer is a ring buffer.
\n" + "FALSE - the SMM profile log buffer is a normal buffer.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmBlockStartupThisAp_PROMPT #language en-US "SMM Startup AP in a blocking fashion" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmBlockStartupThisAp_HELP #language en-US "Indicates if SMM Startup AP in a blocking fashion.\n" + "TRUE - SMM Startup AP in a blocking fashion.
\n" + "FALSE - SMM Startup AP in a non-blocking fashion.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStackGuard_PROMPT #language en-US "Enable SMM Stack Guard" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStackGuard_HELP #language en-US "Indicates if SMM Stack Guard will be enabled. If enabled, stack overflow in SMM can be caught, which eases debugging.

\n" + "TRUE - SMM Stack Guard will be enabled.
\n" + "FALSE - SMM Stack Guard will be disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmEnableBspElection_PROMPT #language en-US "Enable BSP election in SMM" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmEnableBspElection_HELP #language en-US "Indicates if BSP election in SMM will be enabled. If enabled, a BSP will be dynamically elected among all processors in each SMI. Otherwise, processor 0 is always as BSP in each SMI.

\n" + "TRUE - BSP election in SMM will be enabled.
\n" + "FALSE - BSP election in SMM will be disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuHotPlugSupport_PROMPT #language en-US "SMM CPU hot-plug" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuHotPlugSupport_HELP #language en-US "Enable CPU SMM hot-plug?

\n" + "TRUE - enabled.
\n" + "FALSE - disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmDebug_PROMPT #language en-US "Enable SMM Debug" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmDebug_HELP #language en-US "Indicates if SMM Debug will be enabled. If enabled, hardware breakpoints in SMRAM can be set outside of SMM mode and take effect in SMM.

\n" + "TRUE - SMM Debug will be enabled.
\n" + "FALSE - SMM Debug will be disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmFeatureControlMsrLock_PROMPT #language en-US "Lock SMM Feature Control MSR" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmFeatureControlMsrLock_HELP #language en-US "Lock SMM Feature Control MSR?

\n" + "TRUE - locked.
\n" + "FALSE - unlocked.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdPeiTemporaryRamStackSize_PROMPT #language en-US "Stack size in the temporary RAM" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdPeiTemporaryRamStackSize_HELP #language en-US "Specifies stack size in the temporary RAM. 0 means half of TemporaryRamSize." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileSize_PROMPT #language en-US "SMM profile data buffer size" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmProfileSize_HELP #language en-US "Specifies buffer size in bytes to save SMM profile data. The value should be a multiple of 4KB." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStackSize_PROMPT #language en-US "Processor stack size in SMM" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStackSize_HELP #language en-US "Specifies stack size in bytes for each processor in SMM." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmShadowStackSize_PROMPT #language en-US "Processor shadow stack size in SMM." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmShadowStackSize_HELP #language en-US "Specifies shadow stack size in bytes for each processor in SMM." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_PROMPT #language en-US "AP synchronization timeout value in SMM" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmApSyncTimeout_HELP #language en-US "Specifies timeout value in microseconds for the BSP in SMM to wait for all APs to come into SMM." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmCodeAccessCheckEnable_PROMPT #language en-US "SMM Code Access Check" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmCodeAccessCheckEnable_HELP #language en-US "Enable SMM Code Access Check? If enabled, the SMM handler cannot execute the code outside SMM regions. This PCD is suggested to TRUE in production image.

\n" + "TRUE - SMM Code Access Check will be enabled.
\n" + "FALSE - SMM Code Access Check will be disabled.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmSyncMode_PROMPT #language en-US "SMM CPU Synchronization Method" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmSyncMode_HELP #language en-US "Indicates the CPU synchronization method used when processing an SMI.

\n" + "0x00 - Traditional CPU synchronization method.
\n" + "0x01 - Relaxed CPU synchronization method.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuS3DataAddress_PROMPT #language en-US "The pointer to a CPU S3 data buffer" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuS3DataAddress_HELP #language en-US "Contains the pointer to a CPU S3 data buffer of structure ACPI_CPU_DATA." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuHotPlugDataAddress_PROMPT #language en-US "The pointer to CPU Hot Plug Data" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuHotPlugDataAddress_HELP #language en-US "Contains the pointer to a CPU Hot Plug Data structure if CPU hot-plug is supported." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_PROMPT #language en-US "Number of reserved variable MTRRs" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuNumberOfReservedVariableMtrrs_HELP #language en-US "Specifies the number of variable MTRRs reserved for OS use." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApLoopMode_PROMPT #language en-US "The AP wait loop state" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApLoopMode_HELP #language en-US "Specifies the AP wait loop state during POST phase." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApTargetCstate_PROMPT #language en-US "The specified AP target C-state for Mwait" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApTargetCstate_HELP #language en-US "Specifies the AP target C-state for Mwait during POST phase." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStaticPageTable_PROMPT #language en-US "Use static page table for all memory in SMM." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStaticPageTable_HELP #language en-US "Indicates if SMM uses static page table.\n" + "If enabled, SMM will not use on-demand paging. SMM will build static page table for all memory.\n" + "This flag only impacts X64 build, because SMM always builds static page table for IA32.\n" + "It could not be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable).\n" + "It could not be enabled also at the same time with heap guard feature for SMM\n" + "(PcdHeapGuardPropertyMask in MdeModulePkg).

\n" + "TRUE - SMM uses static page table for all memory.
\n" + "FALSE - SMM uses static page table for below 4G memory and use on-demand paging for above 4G memory.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStmExceptionStackSize_PROMPT #language en-US "STM exception stack size." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmStmExceptionStackSize_HELP #language en-US "Specifies buffer size in bytes for STM exception stack. The value should be a multiple of 4KB." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMsegSize_PROMPT #language en-US "MSEG size." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuMsegSize_HELP #language en-US "Specifies buffer size in bytes of MSEG. The value should be a multiple of 4KB." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesSupport_PROMPT #language en-US "Supported CPU features." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesSupport_HELP #language en-US "Specifies the supported CPU features bit in array." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesInitAfterSmmRelocation_PROMPT #language en-US "If CPU features will be initialized after SMM relocation." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesInitAfterSmmRelocation_HELP #language en-US "Specifies if CPU features will be initialized after SMM relocation." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesInitOnS3Resume_PROMPT #language en-US "If CPU features will be initialized during S3 resume." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesInitOnS3Resume_HELP #language en-US "Specifies if CPU features will be initialized during S3 resume." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesUserConfiguration_PROMPT #language en-US "User settings for enabling/disabling processor features." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesUserConfiguration_HELP #language en-US "Specifies user's desired settings for enabling/disabling processor features." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuClockModulationDutyCycle_PROMPT #language en-US "The encoded values for target duty cycle modulation." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuClockModulationDutyCycle_HELP #language en-US "Specifies the On-demand clock modulation duty cycle when ACPI feature is enabled." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdIsPowerOnReset_PROMPT #language en-US "Current boot is a power-on reset." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdIsPowerOnReset_HELP #language en-US "Indicates if the current boot is a power-on reset." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmRestrictedMemoryAccess_PROMPT #language en-US "Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmRestrictedMemoryAccess_HELP #language en-US "Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.

\n" + "MMIO access is always allowed regardless of the value of this PCD.
\n" + "Loose of such restriction is only required by RAS components in X64 platforms.
\n" + "The PCD value is considered as constantly TRUE in IA32 platforms.
\n" + "When the PCD value is TRUE, page table is initialized to cover all memory spaces
\n" + "and the memory occupied by page table is protected by page table itself as read-only.
\n" + "In X64 build, it cannot be enabled at the same time with SMM profile feature (PcdCpuSmmProfileEnable).
\n" + "In X64 build, it could not be enabled also at the same time with heap guard feature for SMM
\n" + "(PcdHeapGuardPropertyMask in MdeModulePkg).
\n" + "In IA32 build, page table memory is not marked as read-only when either SMM profile feature (PcdCpuSmmProfileEnable)
\n" + "or heap guard feature for SMM (PcdHeapGuardPropertyMask in MdeModulePkg) is enabled.
\n" + "TRUE - Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
\n" + "FALSE - Access to any type of non-SMRAM memory after SmmReadyToLock is allowed.
" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesCapability_PROMPT #language en-US "Processor feature capabilities." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesCapability_HELP #language en-US "Indicates processor feature capabilities, each bit corresponding to a specific feature." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesSetting_PROMPT #language en-US "Actual processor feature settings." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuFeaturesSetting_HELP #language en-US "Specifies actual settings for processor features, each bit corresponding to a specific feature." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuProcTraceMemSize_PROMPT #language en-US "Memory size used by Processor Trace feature." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuProcTraceMemSize_HELP #language en-US "User input the size of memory required when CPU processor trace is enabled.

\n" + "Processor trace is enabled through set BIT44(CPU_FEATURE_PROC_TRACE) in PcdCpuFeaturesSetting.

\n" + "This PCD is ignored if CPU processor trace is disabled.

\n" + "Default value is 0x00 which means 4KB of memory is allocated if CPU processor trace is enabled.
\n" + "0x0 - 4K.
\n" + "0x1 - 8K.
\n" + "0x2 - 16K.
\n" + "0x3 - 32K.
\n" + "0x4 - 64K.
\n" + "0x5 - 128K.
\n" + "0x6 - 256K.
\n" + "0x7 - 512K.
\n" + "0x8 - 1M.
\n" + "0x9 - 2M.
\n" + "0xA - 4M.
\n" + "0xB - 8M.
\n" + "0xC - 16M.
\n" + "0xD - 32M.
\n" + "0xE - 64M.
\n" + "0xF - 128M.
\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuProcTraceOutputScheme_PROMPT #language en-US "Processor Trace output scheme type." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuProcTraceOutputScheme_HELP #language en-US "User input the processor trace output scheme when CPU processor trace is enabled.

\n" + "Processor trace is enabled through set BIT44(CPU_FEATURE_PROC_TRACE) in PcdCpuFeaturesSetting.

\n" + "This PCD is ignored if CPU processor trace is disabled.

\n" + "Default value is 0 which means single range output scheme will be used if CPU processor trace is enabled.
\n" + "0 - Single Range output scheme.
\n" + "1 - ToPA(Table of physical address) scheme.
\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuStackSwitchExceptionList_PROMPT #language en-US "Specify exception vectors which need switching stack." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuStackSwitchExceptionList_HELP #language en-US "List of exception vectors which need switching stack.\n" + "This PCD will only take into effect if PcdCpuStackGuard is enabled.n" + "By default exception #DD(8), #PF(14) are supported.n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuKnownGoodStackSize_PROMPT #language en-US "Specify size of good stack of exception which need switching stack." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuKnownGoodStackSize_HELP #language en-US "Size of good stack for an exception.\n" + "This PCD will only take into effect if PcdCpuStackGuard is enabled.\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuCoreCrystalClockFrequency_PROMPT #language en-US "Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuCoreCrystalClockFrequency_HELP #language en-US "Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency.

\n" + "TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX.

\n" + "This PCD is the nominal frequency of the core crystal clock in Hz as is CPUID Leaf 0x15:ECX.

\n" + "Default value is 24000000 for 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family.
\n" + "25000000 - Intel Xeon Processor Scalable Family with CPUID signature 06_55H(25MHz).
\n" + "24000000 - 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family(24MHz).
\n" + "19200000 - Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH(19.2MHz).
\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmMpTokenCountPerChunk_PROMPT #language en-US "Specify the count of pre allocated SMM MP tokens per chunk.\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuSmmMpTokenCountPerChunk_HELP #language en-US "This value used to specify the count of pre allocated SMM MP tokens per chunk.\n" + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSeconds_PROMPT #language en-US "Periodic interval value in microseconds for AP status check in DXE.\n" +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSeconds_HELP #language en-US "Periodic interval value in microseconds for the status check of APs for StartupAllAPs() and StartupThisAP() executed in non-blocking mode in DXE phase.\n" diff --git a/UefiCpuPkg/UefiCpuPkgExtra.uni b/UefiCpuPkg/UefiCpuPkgExtra.uni new file mode 100644 index 000000000..953f2933b --- /dev/null +++ b/UefiCpuPkg/UefiCpuPkgExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// UefiCpu Package Localized Strings and Content. +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_PACKAGE_NAME +#language en-US +"UefiCpu package" + + diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.nasm b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.nasm new file mode 100644 index 000000000..32a0ead3b --- /dev/null +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.nasm @@ -0,0 +1,35 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; AsmFuncs.Asm +; +; Abstract: +; +; Assembly function to set segment selectors. +; +; Notes: +; +;------------------------------------------------------------------------------ + +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmSetDataSelectors ( +; IN UINT16 SelectorValue +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmSetDataSelectors) +ASM_PFX(AsmSetDataSelectors): + mov eax, [esp + 4] +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax +o16 mov ss, ax + ret + diff --git a/CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c similarity index 61% rename from CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c rename to UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c index c405e3912..83ce1c403 100644 --- a/CloverEFI/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c @@ -1,19 +1,13 @@ /** @file - This module produces the EFI_PEI_S3_RESUME_PPI. + This module produces the EFI_PEI_S3_RESUME2_PPI. This module works with StandAloneBootScriptExecutor to S3 resume to OS. - This module will excute the boot script saved during last boot and after that, + This module will execute the boot script saved during last boot and after that, control is passed to OS waking up handler. - Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions - of the BSD License which accompanies this distribution. The - full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -21,16 +15,17 @@ #include #include -#include -#include +#include +#include +#include #include #include #include #include +#include #include #include -#include #include #include #include @@ -43,11 +38,23 @@ #include #include #include -#include + #include #include #include +/** + This macro aligns the address of a variable with auto storage + duration down to CPU_STACK_ALIGNMENT. + + Since the stack grows downward, the result preserves more of the + stack than the original address (or the same amount), not less. +**/ +#define STACK_ALIGN_DOWN(Ptr) \ + ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1)) + +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull + #pragma pack(1) typedef union { struct { @@ -102,7 +109,7 @@ typedef union { UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 MustBe1:1; // Must be 1 + UINT64 MustBe1:1; // Must be 1 UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write UINT64 Available:3; // Available for use by system software UINT64 PAT:1; // @@ -126,7 +133,7 @@ typedef union { UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 MustBe1:1; // Must be 1 + UINT64 MustBe1:1; // Must be 1 UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write UINT64 Available:3; // Available for use by system software UINT64 PAT:1; // @@ -138,6 +145,22 @@ typedef union { UINT64 Uint64; } PAGE_TABLE_1G_ENTRY; +// +// Define two type of smm communicate headers. +// One for 32 bits PEI + 64 bits DXE, the other for 32 bits PEI + 32 bits DXE case. +// +typedef struct { + EFI_GUID HeaderGuid; + UINT32 MessageLength; + UINT8 Data[1]; +} SMM_COMMUNICATE_HEADER_32; + +typedef struct { + EFI_GUID HeaderGuid; + UINT64 MessageLength; + UINT8 Data[1]; +} SMM_COMMUNICATE_HEADER_64; + #pragma pack() // @@ -145,9 +168,9 @@ typedef union { // /** a ASM function to transfer control to OS. - + @param S3WakingVector The S3 waking up vector saved in ACPI Facs table - @param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer + @param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer **/ typedef VOID @@ -193,6 +216,18 @@ S3RestoreConfig2 ( IN EFI_PEI_S3_RESUME2_PPI *This ); +/** + Set data segment selectors value including DS/ES/FS/GS/SS. + + @param[in] SelectorValue Segment selector value to be set. + +**/ +VOID +EFIAPI +AsmSetDataSelectors ( + IN UINT16 SelectorValue + ); + // // Globals // @@ -216,6 +251,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfPeiTable = { 0 }; +EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiS3SmmInitDoneGuid, + 0 +}; + // // Global Descriptor Table (GDT) // @@ -232,6 +273,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = { /* 0x40 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, }; +#define DATA_SEGEMENT_SELECTOR 0x18 + // // IA32 Gdt register // @@ -240,129 +283,101 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = { (UINTN) mGdtEntries }; -/** - Performance measure function to get S3 detailed performance data. - This function will getS3 detailed performance data and saved in pre-reserved ACPI memory. +/** + The function will check if current waking vector is long mode. + + @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT + + @retval TRUE Current context need long mode waking vector. + @retval FALSE Current context need not long mode waking vector. **/ -VOID -WriteToOsS3PerformanceData ( - VOID +BOOLEAN +IsLongModeWakingVector ( + IN ACPI_S3_CONTEXT *AcpiS3Context ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase; - PERF_HEADER *PerfHeader; - PERF_DATA *PerfData; - UINT64 Ticker; - UINTN Index; - EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; - UINTN VarSize; - UINTN LogEntryKey; - CONST VOID *Handle; - CONST CHAR8 *Token; - CONST CHAR8 *Module; - UINT64 StartTicker; - UINT64 EndTicker; - UINT64 StartValue; - UINT64 EndValue; - BOOLEAN CountUp; - UINT64 Freq; + EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; - // - // Retrive time stamp count as early as possilbe - // - Ticker = GetPerformanceCounter (); - - Freq = GetPerformanceCounterProperties (&StartValue, &EndValue); - - Freq = DivU64x32 (Freq, 1000); - - Status = PeiServicesLocatePpi ( - &gEfiPeiReadOnlyVariable2PpiGuid, - 0, - NULL, - (VOID **) &VariableServices - ); - ASSERT_EFI_ERROR(Status); - - VarSize = sizeof (EFI_PHYSICAL_ADDRESS); - Status = VariableServices->GetVariable ( - VariableServices, - L"PerfDataMemAddr", - &gPerformanceProtocolGuid, - NULL, - &VarSize, - &mAcpiLowMemoryBase - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "Fail to retrieve variable to log S3 performance data \n")); - return; + Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)); + if ((Facs == NULL) || + (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || + ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) { + // Something wrong with FACS + return FALSE; } - - PerfHeader = (PERF_HEADER *) (UINTN) mAcpiLowMemoryBase; - - if (PerfHeader->Signiture != PERFORMANCE_SIGNATURE) { - DEBUG ((EFI_D_ERROR, "Performance data in ACPI memory get corrupted! \n")); - return; - } - - // - // Record total S3 resume time. - // - if (EndValue >= StartValue) { - PerfHeader->S3Resume = Ticker - StartValue; - CountUp = TRUE; - } else { - PerfHeader->S3Resume = StartValue - Ticker; - CountUp = FALSE; - } - - // - // Get S3 detailed performance data - // - Index = 0; - LogEntryKey = 0; - while ((LogEntryKey = GetPerformanceMeasurement ( - LogEntryKey, - &Handle, - &Token, - &Module, - &StartTicker, - &EndTicker)) != 0) { - if (EndTicker != 0) { - PerfData = &PerfHeader->S3Entry[Index]; - - // - // Use File Handle to specify the different performance log for PEIM. - // File Handle is the base address of PEIM FFS file. - // - if ((AsciiStrnCmp (Token, "PEIM", PEI_PERFORMANCE_STRING_SIZE) == 0) && (Handle != NULL)) { - AsciiSPrint (PerfData->Token, PERF_TOKEN_LENGTH, "0x%11p", Handle); - } else { - AsciiStrnCpyS (PerfData->Token, PERF_TOKEN_LENGTH+1, Token, PERF_TOKEN_LENGTH); - } - if (StartTicker == 1) { - StartTicker = StartValue; - } - if (EndTicker == 1) { - EndTicker = StartValue; - } - Ticker = CountUp? (EndTicker - StartTicker) : (StartTicker - EndTicker); - PerfData->Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); - - // - // Only Record > 1ms performance data so that more big performance can be recorded. - // - if ((Ticker > Freq) && (++Index >= PERF_PEI_ENTRY_MAX_NUM)) { - // - // Reach the maximum number of PEI performance log entries. - // - break; + if (Facs->XFirmwareWakingVector != 0) { + if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) && + ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) && + ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) { + // Both BIOS and OS wants 64bit vector + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + return TRUE; } } } - PerfHeader->S3EntryNum = (UINT32) Index; + return FALSE; +} + +/** + Signal to SMM through communication buffer way. + + @param[in] HandlerType SMI handler type to be signaled. + +**/ +VOID +SignalToSmmByCommunication ( + IN EFI_GUID *HandlerType + ) +{ + EFI_STATUS Status; + EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi; + UINTN CommSize; + SMM_COMMUNICATE_HEADER_32 Header32; + SMM_COMMUNICATE_HEADER_64 Header64; + VOID *CommBuffer; + + DEBUG ((DEBUG_INFO, "Signal %g to SMM - Enter\n", HandlerType)); + + // + // This buffer consumed in DXE phase, so base on DXE mode to prepare communicate buffer. + // Detect whether DXE is 64 bits mode. + // if (sizeof(UINTN) == sizeof(UINT64), PEI already 64 bits, assume DXE also 64 bits. + // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), DXE will switch to 64 bits. + // + if ((sizeof(UINTN) == sizeof(UINT64)) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) { + CommBuffer = &Header64; + Header64.MessageLength = 0; + CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_64, Data); + } else { + CommBuffer = &Header32; + Header32.MessageLength = 0; + CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_32, Data); + } + CopyGuid (CommBuffer, HandlerType); + + Status = PeiServicesLocatePpi ( + &gEfiPeiSmmCommunicationPpiGuid, + 0, + NULL, + (VOID **)&SmmCommunicationPpi + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Locate Smm Communicate Ppi failed (%r)!\n", Status)); + return; + } + + Status = SmmCommunicationPpi->Communicate ( + SmmCommunicationPpi, + (VOID *)CommBuffer, + &CommSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SmmCommunicationPpi->Communicate return failure (%r)!\n", Status)); + } + + DEBUG ((DEBUG_INFO, "Signal %g to SMM - Exit (%r)\n", HandlerType, Status)); + return; } /** @@ -390,11 +405,33 @@ S3ResumeBootOs ( // AsmWriteIdtr (&PeiS3ResumeState->Idtr); + if (PeiS3ResumeState->ReturnStatus != EFI_SUCCESS) { + // + // Report Status code that boot script execution is failed + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR) + ); + } + + // + // NOTE: Because Debug Timer interrupt and system interrupts will be disabled + // in BootScriptExecuteDxe, the rest code in S3ResumeBootOs() cannot be halted + // by soft debugger. + // + + PERF_INMODULE_END ("ScriptExec"); + // // Install BootScriptDonePpi // + PERF_INMODULE_BEGIN ("BootScriptDonePpi"); + Status = PeiServicesInstallPpi (&mPpiListPostScriptTable); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); + + PERF_INMODULE_END ("BootScriptDonePpi"); // // Get ACPI Table Address @@ -404,38 +441,62 @@ S3ResumeBootOs ( if ((Facs == NULL) || (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) { + // + // Report Status code that no valid vector is found + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) + ); CpuDeadLoop (); return ; } + // + // Install EndOfPeiPpi + // + PERF_INMODULE_BEGIN("EndOfPeiPpi"); + + Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable); + ASSERT_EFI_ERROR (Status); + + PERF_INMODULE_END("EndOfPeiPpi"); + + PERF_INMODULE_BEGIN("EndOfS3Resume"); + + DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n")); + // + // Signal EndOfS3Resume to SMM. + // + SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid); + + PERF_INMODULE_END ("EndOfS3Resume"); + // // report status code on S3 resume // REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE); - // - // Install EndOfPeiPpi - // - Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable); - ASSERT_EFI_ERROR(Status); - - PERF_CODE ( - WriteToOsS3PerformanceData (); - ); - AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl; if (Facs->XFirmwareWakingVector != 0) { // // Switch to native waking vector // TempStackTop = (UINTN)&TempStack + sizeof(TempStack); + DEBUG (( + DEBUG_INFO, + "%a() Stack Base: 0x%x, Stack Size: 0x%x\n", + __FUNCTION__, + TempStackTop, + sizeof (TempStack) + )); if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) && ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) && - ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) { + ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) { // // X64 long mode waking vector // - DEBUG (( EFI_D_ERROR, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector)); + DEBUG ((DEBUG_INFO, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector)); if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { AsmEnablePaging64 ( 0x38, @@ -445,14 +506,23 @@ S3ResumeBootOs ( (UINT64)(UINTN)TempStackTop ); } else { + // + // Report Status code that no valid waking vector is found + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) + ); DEBUG (( EFI_D_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n")); ASSERT (FALSE); + CpuDeadLoop (); + return ; } } else { // // IA32 protected mode waking vector (Page disabled) // - DEBUG (( EFI_D_ERROR, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector)); + DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector)); SwitchStack ( (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector, NULL, @@ -464,10 +534,18 @@ S3ResumeBootOs ( // // 16bit Realmode waking vector // - DEBUG (( EFI_D_ERROR, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector)); + DEBUG ((DEBUG_INFO, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector)); AsmTransferControl (Facs->FirmwareWakingVector, 0x0); } + // + // Report Status code the failure of S3Resume + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR) + ); + // // Never run to here // @@ -476,16 +554,18 @@ S3ResumeBootOs ( /** Restore S3 page table because we do not trust ACPINvs content. - If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. + If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. @param S3NvsPageTableAddress PageTableAddress in ACPINvs + @param Build4GPageTableOnly If BIOS just build 4G page table only **/ VOID RestoreS3PageTables ( - IN UINTN S3NvsPageTableAddress + IN UINTN S3NvsPageTableAddress, + IN BOOLEAN Build4GPageTableOnly ) { -/* if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { UINT32 RegEax; UINT32 RegEdx; UINT8 PhysicalAddressBits; @@ -502,30 +582,38 @@ RestoreS3PageTables ( VOID *Hob; BOOLEAN Page1GSupport; PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + UINT64 AddressEncMask; + + // + // Make sure AddressEncMask is contained to smallest supported address field + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; // // NOTE: We have to ASSUME the page table generation format, because we do not know whole page table information. // The whole page table is too large to be saved in SMRAM. // - // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page. + // The assumption is : whole page table is allocated in CONTINUOUS memory and CR3 points to TOP page. // - DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x\n", S3NvsPageTableAddress)); + DEBUG ((DEBUG_INFO, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly)); // - // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it. + // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress; S3NvsPageTableAddress += SIZE_4KB; - + Page1GSupport = FALSE; - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000001) { - AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT26) != 0) { - Page1GSupport = TRUE; + if (PcdGetBool(PcdUse1GPageTable)) { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + Page1GSupport = TRUE; + } } } - + // // Get physical address bits supported. // @@ -541,7 +629,7 @@ RestoreS3PageTables ( PhysicalAddressBits = 36; } } - + // // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. // @@ -550,6 +638,14 @@ RestoreS3PageTables ( PhysicalAddressBits = 48; } + // + // NOTE: In order to save time to create full page table, we just create 4G page table by default. + // And let PF handler in BootScript driver to create more on request. + // + if (Build4GPageTableOnly) { + PhysicalAddressBits = 32; + ZeroMem (PageMap, EFI_PAGES_TO_SIZE(2)); + } // // Calculate the table entries needed. // @@ -560,7 +656,7 @@ RestoreS3PageTables ( NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39)); NumberOfPdpEntriesNeeded = 512; } - + PageMapLevel4Entry = PageMap; PageAddress = 0; for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) { @@ -570,22 +666,22 @@ RestoreS3PageTables ( // PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress; S3NvsPageTableAddress += SIZE_4KB; - + // // Make a PML4 Entry // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry; + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; PageMapLevel4Entry->Bits.ReadWrite = 1; PageMapLevel4Entry->Bits.Present = 1; if (Page1GSupport) { PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry; - + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { // // Fill in the Page Directory entries // - PageDirectory1GEntry->Uint64 = (UINT64)PageAddress; + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectory1GEntry->Bits.ReadWrite = 1; PageDirectory1GEntry->Bits.Present = 1; PageDirectory1GEntry->Bits.MustBe1 = 1; @@ -595,22 +691,22 @@ RestoreS3PageTables ( // // 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 = (PAGE_TABLE_ENTRY *)S3NvsPageTableAddress; S3NvsPageTableAddress += SIZE_4KB; - + // // Fill in a Page Directory Pointer Entries // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry; + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; PageDirectoryPointerEntry->Bits.ReadWrite = 1; PageDirectoryPointerEntry->Bits.Present = 1; - + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 = (UINT64)PageAddress; + PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectoryEntry->Bits.ReadWrite = 1; PageDirectoryEntry->Bits.Present = 1; PageDirectoryEntry->Bits.MustBe1 = 1; @@ -620,12 +716,11 @@ RestoreS3PageTables ( } return ; } else { - // - // If DXE is running 32-bit mode, no need to establish page table. - // + // + // If DXE is running 32-bit mode, no need to establish page table. + // return ; - } */ - return; + } } /** @@ -648,11 +743,10 @@ S3ResumeExecuteBootScript ( PEI_SMM_ACCESS_PPI *SmmAccess; UINTN Index; VOID *GuidHob; - IA32_DESCRIPTOR *IdtDescriptor; - VOID *IdtBuffer; PEI_S3_RESUME_STATE *PeiS3ResumeState; + BOOLEAN InterruptStatus; - DEBUG ((EFI_D_ERROR, "S3ResumeExecuteBootScript()\n")); + DEBUG ((DEBUG_INFO, "S3ResumeExecuteBootScript()\n")); // // Attempt to use content from SMRAM first @@ -665,7 +759,7 @@ S3ResumeExecuteBootScript ( // // Send SMI to APs - // + // SendSmiIpiAllExcludingSelf (); // // Send SMI to BSP @@ -678,68 +772,82 @@ S3ResumeExecuteBootScript ( NULL, (VOID **) &SmmAccess ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Close all SMRAM regions before executing boot script\n")); - DEBUG ((EFI_D_ERROR, "Close all SMRAM regions before executing boot script\n")); + for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { + Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + } - for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR(Status); Index++) { - Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + DEBUG ((DEBUG_INFO, "Lock all SMRAM regions before executing boot script\n")); + + for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { + Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + } } - DEBUG ((EFI_D_ERROR, "Lock all SMRAM regions before executing boot script\n")); - - for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR(Status); Index++) { - Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); - } + DEBUG ((DEBUG_INFO, "Signal S3SmmInitDone\n")); + // + // Install S3SmmInitDone PPI. + // + Status = PeiServicesInstallPpi (&mPpiListS3SmmInitDoneTable); + ASSERT_EFI_ERROR (Status); + // + // Signal S3SmmInitDone to SMM. + // + SignalToSmmByCommunication (&gEdkiiS3SmmInitDoneGuid); } if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { - // - // Need reconstruct page table here, since we do not trust ACPINvs. - // - RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress); AsmWriteCr3 ((UINTN)AcpiS3Context->S3NvsPageTableAddress); } - if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { - // - // On some platform, such as ECP, a dispatch node in boot script table may execute a 32-bit PEIM which may need PeiServices - // pointer. So PeiServices need preserve in (IDTBase- sizeof (UINTN)). - // - IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile); - // - // Make sure the newly allcated IDT align with 16-bytes - // - IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16)); - ASSERT (IdtBuffer != NULL); - CopyMem((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1)); - IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16); - *(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer (); - } - + InterruptStatus = SaveAndDisableInterrupts (); // // Need to make sure the GDT is loaded with values that support long mode and real mode. // AsmWriteGdtr (&mGdt); + // + // update segment selectors per the new GDT. + // + AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR); + // + // Restore interrupt state. + // + SetInterruptState (InterruptStatus); // // Prepare data for return back // PeiS3ResumeState = AllocatePool (sizeof(*PeiS3ResumeState)); - ASSERT (PeiS3ResumeState != NULL); - DEBUG (( EFI_D_ERROR, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState)); + if (PeiS3ResumeState == NULL) { + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED) + ); + ASSERT (FALSE); + } + DEBUG ((DEBUG_INFO, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState)); PeiS3ResumeState->ReturnCs = 0x10; PeiS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs; - PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)(UINTN)&Status; + PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status); // // Save IDT // AsmReadIdtr (&PeiS3ResumeState->Idtr); + // + // Report Status Code to indicate S3 boot script execution + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT); + + PERF_INMODULE_BEGIN ("ScriptExec"); + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { // // X64 S3 Resume // - DEBUG (( EFI_D_ERROR, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n")); + DEBUG ((DEBUG_INFO, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n")); // // Switch to long mode to complete resume. @@ -755,7 +863,7 @@ S3ResumeExecuteBootScript ( // // IA32 S3 Resume // - DEBUG (( EFI_D_ERROR, "transfer control to Standalone Boot Script Executor\r\n")); + DEBUG ((DEBUG_INFO, "transfer control to Standalone Boot Script Executor\r\n")); SwitchStack ( (SWITCH_STACK_ENTRY_POINT) (UINTN) EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint, (VOID *)AcpiS3Context, @@ -810,7 +918,6 @@ S3RestoreConfig2 ( PEI_SMM_ACCESS_PPI *SmmAccess; UINTN Index; ACPI_S3_CONTEXT *AcpiS3Context; - EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; EFI_PHYSICAL_ADDRESS TempEfiBootScriptExecutorVariable; EFI_PHYSICAL_ADDRESS TempAcpiS3Context; BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable; @@ -818,28 +925,14 @@ S3RestoreConfig2 ( EFI_SMRAM_DESCRIPTOR *SmramDescriptor; SMM_S3_RESUME_STATE *SmmS3ResumeState; VOID *GuidHob; + BOOLEAN Build4GPageTableOnly; + BOOLEAN InterruptStatus; + IA32_CR0 Cr0; - DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n")); + TempAcpiS3Context = 0; + TempEfiBootScriptExecutorVariable = 0; - Status = PeiServicesLocatePpi ( - &gPeiSmmAccessPpiGuid, - 0, - NULL, - (VOID **) &SmmAccess - ); - for (Index = 0; !EFI_ERROR(Status); Index++) { - Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); - } - - Status = PeiServicesLocatePpi ( - &gEfiPeiReadOnlyVariable2PpiGuid, - 0, - NULL, - (VOID **) &VariableServices - ); - if (EFI_ERROR(Status)) { - return Status; - } + DEBUG ((DEBUG_INFO, "Enter S3 PEIM\r\n")); VarSize = sizeof (EFI_PHYSICAL_ADDRESS); Status = RestoreLockBox ( @@ -847,41 +940,45 @@ S3RestoreConfig2 ( &TempAcpiS3Context, &VarSize ); - ASSERT_EFI_ERROR(Status); - - AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context; - ASSERT (AcpiS3Context != NULL); + ASSERT_EFI_ERROR (Status); Status = RestoreLockBox ( &gEfiAcpiS3ContextGuid, NULL, NULL ); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); - VarSize = sizeof (TempEfiBootScriptExecutorVariable); + AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context; + ASSERT (AcpiS3Context != NULL); + + VarSize = sizeof (EFI_PHYSICAL_ADDRESS); Status = RestoreLockBox ( &gEfiBootScriptExecutorVariableGuid, &TempEfiBootScriptExecutorVariable, &VarSize ); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); Status = RestoreLockBox ( &gEfiBootScriptExecutorContextGuid, NULL, NULL ); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *) (UINTN) TempEfiBootScriptExecutorVariable; + ASSERT (EfiBootScriptExecutorVariable != NULL); - DEBUG (( EFI_D_ERROR, "AcpiS3Context = %x\n", AcpiS3Context)); - DEBUG (( EFI_D_ERROR, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector)); - DEBUG (( EFI_D_ERROR, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable)); - DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress)); - DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress)); - DEBUG (( EFI_D_ERROR, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint)); + DEBUG (( DEBUG_INFO, "AcpiS3Context = %x\n", AcpiS3Context)); + DEBUG (( DEBUG_INFO, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase)); + DEBUG (( DEBUG_INFO, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize)); + DEBUG (( DEBUG_INFO, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint)); // // Additional step for BootScript integrity - we only handle BootScript and BootScriptExecutor. @@ -889,17 +986,46 @@ S3RestoreConfig2 ( // We just use restore all lock box in place, no need restore one by one. // Status = RestoreAllLockBoxInPlace (); - ASSERT_EFI_ERROR(Status); - if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { // Something wrong CpuDeadLoop (); } + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + // + // Need reconstruct page table here, since we do not trust ACPINvs. + // + if (IsLongModeWakingVector (AcpiS3Context)) { + Build4GPageTableOnly = FALSE; + } else { + Build4GPageTableOnly = TRUE; + } + RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress, Build4GPageTableOnly); + } + // // Attempt to use content from SMRAM first // GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); if (GuidHob != NULL) { + // + // Below SwitchStack/AsmEnablePaging64 function has + // assumption that it's in 32 bits mode now. + // Add ASSERT code to indicate this assumption. + // + ASSERT(sizeof (UINTN) == sizeof (UINT32)); + + Status = PeiServicesLocatePpi ( + &gPeiSmmAccessPpiGuid, + 0, + NULL, + (VOID **) &SmmAccess + ); + for (Index = 0; !EFI_ERROR (Status); Index++) { + Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); + } + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; @@ -907,26 +1033,21 @@ S3RestoreConfig2 ( SmmS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeExecuteBootScript; SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable; - SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)(UINTN)&Status; + SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status); - DEBUG (( EFI_D_ERROR, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature)); - DEBUG (( EFI_D_ERROR, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase)); - DEBUG (( EFI_D_ERROR, "SMM S3 Stack Size = %x\n", SmmS3ResumeState->SmmS3StackSize)); - DEBUG (( EFI_D_ERROR, "SMM S3 Resume Entry Point = %x\n", SmmS3ResumeState->SmmS3ResumeEntryPoint)); - DEBUG (( EFI_D_ERROR, "SMM S3 CR0 = %x\n", SmmS3ResumeState->SmmS3Cr0)); - DEBUG (( EFI_D_ERROR, "SMM S3 CR3 = %x\n", SmmS3ResumeState->SmmS3Cr3)); - DEBUG (( EFI_D_ERROR, "SMM S3 CR4 = %x\n", SmmS3ResumeState->SmmS3Cr4)); - DEBUG (( EFI_D_ERROR, "SMM S3 Return CS = %x\n", SmmS3ResumeState->ReturnCs)); - DEBUG (( EFI_D_ERROR, "SMM S3 Return Entry Point = %x\n", SmmS3ResumeState->ReturnEntryPoint)); - DEBUG (( EFI_D_ERROR, "SMM S3 Return Context1 = %x\n", SmmS3ResumeState->ReturnContext1)); - DEBUG (( EFI_D_ERROR, "SMM S3 Return Context2 = %x\n", SmmS3ResumeState->ReturnContext2)); - DEBUG (( EFI_D_ERROR, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer)); - DEBUG (( EFI_D_ERROR, "SMM S3 Smst = %x\n", SmmS3ResumeState->Smst)); - - // - // Disable interrupt of Debug timer. - // - SaveAndSetDebugTimerInterrupt (FALSE); + DEBUG (( DEBUG_INFO, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature)); + DEBUG (( DEBUG_INFO, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase)); + DEBUG (( DEBUG_INFO, "SMM S3 Stack Size = %x\n", SmmS3ResumeState->SmmS3StackSize)); + DEBUG (( DEBUG_INFO, "SMM S3 Resume Entry Point = %x\n", SmmS3ResumeState->SmmS3ResumeEntryPoint)); + DEBUG (( DEBUG_INFO, "SMM S3 CR0 = %x\n", SmmS3ResumeState->SmmS3Cr0)); + DEBUG (( DEBUG_INFO, "SMM S3 CR3 = %x\n", SmmS3ResumeState->SmmS3Cr3)); + DEBUG (( DEBUG_INFO, "SMM S3 CR4 = %x\n", SmmS3ResumeState->SmmS3Cr4)); + DEBUG (( DEBUG_INFO, "SMM S3 Return CS = %x\n", SmmS3ResumeState->ReturnCs)); + DEBUG (( DEBUG_INFO, "SMM S3 Return Entry Point = %x\n", SmmS3ResumeState->ReturnEntryPoint)); + DEBUG (( DEBUG_INFO, "SMM S3 Return Context1 = %x\n", SmmS3ResumeState->ReturnContext1)); + DEBUG (( DEBUG_INFO, "SMM S3 Return Context2 = %x\n", SmmS3ResumeState->ReturnContext2)); + DEBUG (( DEBUG_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer)); + DEBUG (( DEBUG_INFO, "SMM S3 Smst = %x\n", SmmS3ResumeState->Smst)); if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) { SwitchStack ( @@ -941,11 +1062,38 @@ S3RestoreConfig2 ( // Switch to long mode to complete resume. // + InterruptStatus = SaveAndDisableInterrupts (); // // Need to make sure the GDT is loaded with values that support long mode and real mode. // AsmWriteGdtr (&mGdt); + // + // update segment selectors per the new GDT. + // + AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR); + // + // Restore interrupt state. + // + SetInterruptState (InterruptStatus); + + Cr0.UintN = AsmReadCr0 (); + if (Cr0.Bits.PG != 0) { + // + // We're in 32-bit mode, with paging enabled. We can't set CR3 to + // the 64-bit page tables without first disabling paging. + // + Cr0.Bits.PG = 0; + AsmWriteCr0 (Cr0.UintN); + } AsmWriteCr3 ((UINTN)SmmS3ResumeState->SmmS3Cr3); + + // + // Disable interrupt of Debug timer, since IDT table cannot work in long mode. + // NOTE: On x64 platforms, because DisablePaging64() will disable interrupts, + // the code in S3ResumeExecuteBootScript() cannot be halted by soft debugger. + // + SaveAndSetDebugTimerInterrupt (FALSE); + AsmEnablePaging64 ( 0x38, SmmS3ResumeState->SmmS3ResumeEntryPoint, @@ -964,7 +1112,7 @@ S3RestoreConfig2 ( Main entry for S3 Resume PEIM. This routine is to install EFI_PEI_S3_RESUME2_PPI. - + @param FileHandle Handle of the file being invoked. @param PeiServices Pointer to PEI Services table. @@ -984,7 +1132,7 @@ PeimS3ResumeEntryPoint ( // Install S3 Resume Ppi // Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; } diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf new file mode 100644 index 000000000..aae984d13 --- /dev/null +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf @@ -0,0 +1,101 @@ +## @file +# S3 Resume Module installs EFI_PEI_S3_RESUME2_PPI. +# +# This module works with StandAloneBootScriptExecutor to S3 resume to OS. +# This module will excute the boot script saved during last boot and after that, +# control is passed to OS waking up handler. +# +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2017, AMD Incorporated. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = S3Resume2Pei + MODULE_UNI_FILE = S3Resume2Pei.uni + FILE_GUID = 89E549B0-7CFE-449d-9BA3-10D8B2312D71 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PeimS3ResumeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +# +# This module is not always workable in IA32 and X64 mode. It has below result: +# when it works with SMM mode: +# =============================== +# SMM:used SMM:unused +# PEI:IA32 works works +# PEI:X64 fails works +# =============================== +# + +[Sources] + S3Resume.c + +[Sources.IA32] + Ia32/AsmFuncs.nasm + +[Sources.X64] + X64/AsmFuncs.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + PeiServicesTablePointerLib + PerformanceLib + HobLib + PeiServicesLib + PeimEntryPoint + BaseLib + DebugLib + PcdLib + IoLib + BaseMemoryLib + MemoryAllocationLib + DebugAgentLib + LocalApicLib + ReportStatusCodeLib + LockBoxLib + +[Guids] + gEfiBootScriptExecutorVariableGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox + gEfiBootScriptExecutorContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox + ## SOMETIMES_CONSUMES ## HOB + ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox + gEfiAcpiVariableGuid + gEfiAcpiS3ContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox + gEdkiiEndOfS3ResumeGuid ## SOMETIMES_CONSUMES ## UNDEFINED # Used to do smm communication + ## SOMETIMES_PRODUCES ## UNDEFINED # Install PPI + ## SOMETIMES_CONSUMES ## UNDEFINED # Used to do smm communication + gEdkiiS3SmmInitDoneGuid + +[Ppis] + gEfiPeiS3Resume2PpiGuid ## PRODUCES + gPeiSmmAccessPpiGuid ## SOMETIMES_CONSUMES + gPeiPostScriptTablePpiGuid ## SOMETIMES_PRODUCES + gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES + gEfiPeiSmmCommunicationPpiGuid ## SOMETIMES_CONSUMES + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + S3Resume2PeiExtra.uni diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni new file mode 100644 index 000000000..6b76cab89 --- /dev/null +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni @@ -0,0 +1,20 @@ +// /** @file +// S3 Resume Module installs EFI_PEI_S3_RESUME2_PPI. +// +// This module works with StandAloneBootScriptExecutor to S3 resume to OS. +// This module will excute the boot script saved during last boot and after that, +// control is passed to OS waking up handler. +// +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "S3 Resume Module installs EFI_PEI_S3_RESUME2_PPI" + +#string STR_MODULE_DESCRIPTION #language en-US "This module works with StandAloneBootScriptExecutor to S3 resume to OS.\n" + "This module will execute the boot script saved during last boot and after that,\n" + "control is passed to the OS waking up handler." + diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni new file mode 100644 index 000000000..d84d13f5e --- /dev/null +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// S3Resume2Pei Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"S3 Resume v2 PEI Module" + + diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.nasm b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.nasm new file mode 100644 index 000000000..beabea234 --- /dev/null +++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.nasm @@ -0,0 +1,35 @@ +;------------------------------------------------------------------------------ ; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; AsmFuncs.Asm +; +; Abstract: +; +; Assembly function to set segment selectors. +; +; Notes: +; +;------------------------------------------------------------------------------ + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmSetDataSelectors ( +; IN UINT16 SelectorValue +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmSetDataSelectors) +ASM_PFX(AsmSetDataSelectors): +o16 mov ds, cx +o16 mov es, cx +o16 mov fs, cx +o16 mov gs, cx +o16 mov ss, cx + ret + diff --git a/rEFIt_UEFI/Platform/BootLog.cpp b/rEFIt_UEFI/Platform/BootLog.cpp index e46c776c1..3f8eba4f9 100644 --- a/rEFIt_UEFI/Platform/BootLog.cpp +++ b/rEFIt_UEFI/Platform/BootLog.cpp @@ -13,7 +13,7 @@ #include "DataHubCpu.h" #include "../Platform/Settings.h" -extern EFI_GUID gEfiMiscSubClassGuid; +#include "guid.h" /** Prints Number of bytes in a row (hex and ascii). Row size is MaxNumber. */ diff --git a/rEFIt_UEFI/Platform/BootOptions.cpp b/rEFIt_UEFI/Platform/BootOptions.cpp index 6ce8e921d..cb9587dcf 100644 --- a/rEFIt_UEFI/Platform/BootOptions.cpp +++ b/rEFIt_UEFI/Platform/BootOptions.cpp @@ -136,7 +136,7 @@ StrStriBasic ( * If SubType == 0 then it is ignored. */ EFI_DEVICE_PATH_PROTOCOL * -FindDevicePathNodeWithType ( +Clover_FindDevicePathNodeWithType ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINT8 Type, IN UINT8 SubType OPTIONAL @@ -202,12 +202,12 @@ CreateBootOptionDevicePath ( // // Find HD Media dev path node and extract only that portion of dev path // - TmpDevPath = DuplicateDevicePath (FindDevicePathNodeWithType (*DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP)); + TmpDevPath = DuplicateDevicePath (Clover_FindDevicePathNodeWithType (*DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP)); if (TmpDevPath != NULL) { FreePool(*DevicePath); *DevicePath = TmpDevPath; } /* else { - TmpDevPath = DuplicateDevicePath (FindDevicePathNodeWithType (*DevicePath, HARDWARE_DEVICE_PATH, HW_VENDOR_DP)); + TmpDevPath = DuplicateDevicePath (Clover_FindDevicePathNodeWithType (*DevicePath, HARDWARE_DEVICE_PATH, HW_VENDOR_DP)); if (TmpDevPath != NULL) { FreePool(*DevicePath); *DevicePath = TmpDevPath; @@ -1173,7 +1173,7 @@ DeleteBootOptionsContainingFile ( //PrintBootOption (&BootOption, Index); - FilePathDP = (FILEPATH_DEVICE_PATH*) FindDevicePathNodeWithType (BootOption.FilePathList, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); + FilePathDP = (FILEPATH_DEVICE_PATH*) Clover_FindDevicePathNodeWithType (BootOption.FilePathList, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); if ((FilePathDP != NULL) && (StriStr (FilePathDP->PathName, FileName) != NULL)) { diff --git a/rEFIt_UEFI/Platform/BootOptions.h b/rEFIt_UEFI/Platform/BootOptions.h index 4f3760d71..e032ee685 100644 --- a/rEFIt_UEFI/Platform/BootOptions.h +++ b/rEFIt_UEFI/Platform/BootOptions.h @@ -54,7 +54,7 @@ typedef struct { /** Finds and returns pointer to specified DevPath node in DevicePath or NULL. */ EFI_DEVICE_PATH_PROTOCOL * -FindDevicePathNodeWithType ( +Clover_FindDevicePathNodeWithType ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINT8 Type, IN UINT8 SubType OPTIONAL diff --git a/rEFIt_UEFI/Platform/Events.cpp b/rEFIt_UEFI/Platform/Events.cpp index e8c87aad7..aa0ffd96c 100644 --- a/rEFIt_UEFI/Platform/Events.cpp +++ b/rEFIt_UEFI/Platform/Events.cpp @@ -259,7 +259,7 @@ OnExitBootServices(IN EFI_EVENT Event, IN VOID *Context) // Patch kernel and kexts if needed // LOADER_ENTRY *Entry = ((REFIT_ABSTRACT_MENU_ENTRY*)Context)->getLOADER_ENTRY(); - if (Entry) { + if ( Entry && Entry->OSVersion.startWith("10") ) { Entry->KernelAndKextsPatcherStart(); } diff --git a/rEFIt_UEFI/Platform/Injectors.cpp b/rEFIt_UEFI/Platform/Injectors.cpp index 0d88572df..32c6606ad 100644 --- a/rEFIt_UEFI/Platform/Injectors.cpp +++ b/rEFIt_UEFI/Platform/Injectors.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "Injectors.h" #include "../Platform/Settings.h" @@ -251,7 +251,7 @@ EFI_INTERFACE_SCREEN_INFO mScreenInfo= GetScreenInfo }; -#define EFI_OS_INFO_PROTOCOL_REVISION 0x01 +//#define EFI_OS_INFO_PROTOCOL_REVISION 0x01 // OpenCore define this to 03 // OS_INFO_VENDOR_NAME #define OS_INFO_VENDOR_NAME "Apple Inc." @@ -354,12 +354,12 @@ EFI_KEYBOARD_INFO_PROTOCOL mKeyboardInfo = { EFI_STATUS EFIAPI GetQuirksConfig (IN OCQUIRKS_PROTOCOL *This, - OUT OC_ABC_SETTINGS *Buffer, + OUT OC_ABC_SETTINGS_4CLOVER *Buffer, OUT BOOLEAN *GopEnable ) { DBG("GetQuirksConfig called\n"); - CopyMem(Buffer, &gQuirks, sizeof(OC_ABC_SETTINGS)); + CopyMem(Buffer, &gQuirks, sizeof(OC_ABC_SETTINGS_4CLOVER)); *GopEnable = gProvideConsoleGopEnable; return EFI_SUCCESS; } diff --git a/rEFIt_UEFI/Platform/Injectors.h b/rEFIt_UEFI/Platform/Injectors.h index 59e6c9a26..4aa9ac9a1 100644 --- a/rEFIt_UEFI/Platform/Injectors.h +++ b/rEFIt_UEFI/Platform/Injectors.h @@ -8,7 +8,7 @@ #ifndef PLATFORM_INJECTORS_H_ #define PLATFORM_INJECTORS_H_ -#include +#include extern UINT32 mPropSize; extern UINT8 *mProperties; @@ -17,7 +17,7 @@ extern UINT32 cPropSize; extern UINT8 *cProperties; extern XString8 cDeviceProperties; extern CHAR8 *BootOSName; -extern OC_ABC_SETTINGS gQuirks; +extern OC_ABC_SETTINGS_4CLOVER gQuirks; EFI_STATUS SetPrivateVarProto (VOID); diff --git a/rEFIt_UEFI/Platform/Nvram.cpp b/rEFIt_UEFI/Platform/Nvram.cpp index c878cea58..7ce190db1 100644 --- a/rEFIt_UEFI/Platform/Nvram.cpp +++ b/rEFIt_UEFI/Platform/Nvram.cpp @@ -48,9 +48,9 @@ CHAR16 *gEfiBootLoaderPath; EFI_GUID *gEfiBootDeviceGuid; // Lilu / OpenCore -EFI_GUID gOcVendorVariableGuid = { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } }; -EFI_GUID gOcReadOnlyVariableGuid = { 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } }; -EFI_GUID gOcWriteOnlyVariableGuid = { 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } }; +//EFI_GUID gOcVendorVariableGuid = { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } }; +//EFI_GUID gOcReadOnlyVariableGuid = { 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } }; +//EFI_GUID gOcWriteOnlyVariableGuid = { 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } }; // Ozmosis EFI_GUID mOzmosisProprietary1Guid = { 0x1F8E0C02, 0x58A9, 0x4E34, { 0xAE, 0x22, 0x2B, 0x63, 0x74, 0x5F, 0xA1, 0x01 } }; @@ -733,12 +733,12 @@ BootVolumeMediaDevicePathNodesEqual ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 ) { - DevicePath1 = FindDevicePathNodeWithType (DevicePath1, MEDIA_DEVICE_PATH, 0); + DevicePath1 = Clover_FindDevicePathNodeWithType (DevicePath1, MEDIA_DEVICE_PATH, 0); if (DevicePath1 == NULL) { return FALSE; } - DevicePath2 = FindDevicePathNodeWithType (DevicePath2, MEDIA_DEVICE_PATH, 0); + DevicePath2 = Clover_FindDevicePathNodeWithType (DevicePath2, MEDIA_DEVICE_PATH, 0); if (DevicePath2 == NULL) { return FALSE; } @@ -841,12 +841,12 @@ GetEfiBootDeviceFromNvram () // if gEfiBootVolume contains FilePathNode, then split them into gEfiBootVolume dev path and gEfiBootLoaderPath // gEfiBootLoaderPath = NULL; - FileDevPath = (FILEPATH_DEVICE_PATH *)FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); + FileDevPath = (FILEPATH_DEVICE_PATH *)Clover_FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); if (FileDevPath != NULL) { gEfiBootLoaderPath = (__typeof__(gEfiBootLoaderPath))AllocateCopyPool(StrSize(FileDevPath->PathName), FileDevPath->PathName); // copy DevPath and write end of path node after in place of file path node gEfiBootVolume = DuplicateDevicePath (gEfiBootVolume); - FileDevPath = (FILEPATH_DEVICE_PATH *)FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); + FileDevPath = (FILEPATH_DEVICE_PATH *)Clover_FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP); SetDevicePathEndNode (FileDevPath); // gEfiBootVolume now contains only Volume path } @@ -1192,7 +1192,7 @@ FindStartupDiskVolume ( // Check if gEfiBootVolume is disk or partition volume // EfiBootVolumeStr = FileDevicePathToXStringW(gEfiBootVolume); - IsPartitionVolume = NULL != FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, 0); + IsPartitionVolume = NULL != Clover_FindDevicePathNodeWithType (gEfiBootVolume, MEDIA_DEVICE_PATH, 0); DBG(" - Volume: %ls = %ls\n", IsPartitionVolume ? L"partition" : L"disk", EfiBootVolumeStr.wc_str()); // @@ -1229,7 +1229,7 @@ FindStartupDiskVolume ( LOADER_ENTRY& LoaderEntry = *MainMenu->Entries[Index].getLOADER_ENTRY(); REFIT_VOLUME* Volume = LoaderEntry.Volume; EFI_DEVICE_PATH *DevicePath = LoaderEntry.DevicePath; - EFI_DEVICE_PATH *MediaPath = FindDevicePathNodeWithType(DevicePath, MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP); + EFI_DEVICE_PATH *MediaPath = Clover_FindDevicePathNodeWithType(DevicePath, MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP); if (MediaPath) { EFI_GUID *MediaPathGuid = (EFI_GUID *)&((VENDOR_DEVICE_PATH_WITH_DATA*)MediaPath)->VendorDefinedData; XStringW MediaPathGuidStr = GuidLEToXStringW(MediaPathGuid); diff --git a/rEFIt_UEFI/Platform/Posix/stdbool.h b/rEFIt_UEFI/Platform/Posix/stdbool.h new file mode 100644 index 000000000..70f7c945c --- /dev/null +++ b/rEFIt_UEFI/Platform/Posix/stdbool.h @@ -0,0 +1,21 @@ +/* + * stdbool.h + * + * Created on: Sep 1, 2020 + * Author: jief + */ + +#ifndef PLATFORM_POSIX_STDBOOL_H_ +#define PLATFORM_POSIX_STDBOOL_H_ + + +#ifndef __cplusplus + +#define bool _Bool +#define true 1 +#define false 0 + +#endif + + +#endif /* PLATFORM_POSIX_STDBOOL_H_ */ diff --git a/rEFIt_UEFI/Platform/Posix/stdlib.h b/rEFIt_UEFI/Platform/Posix/stdlib.h index 61353dd53..568ab6330 100644 --- a/rEFIt_UEFI/Platform/Posix/stdlib.h +++ b/rEFIt_UEFI/Platform/Posix/stdlib.h @@ -1,10 +1,15 @@ #ifndef __CLOVER_STDLIB_H__ #define __CLOVER_STDLIB_H__ - +#ifdef __cplusplus extern "C" { +#endif + #include + +#ifdef __cplusplus } +#endif #include "stddef.h" // for size_t @@ -15,7 +20,7 @@ inline void* malloc(size_t size) return AllocatePool(size); } -inline void* realloc(void *ptr, size_t newsize, size_t oldsize) // not the posix realloc. For EFI we need oldsize +inline void* reallocWithOldSize(void *ptr, size_t newsize, size_t oldsize) // not the posix realloc. For EFI we need oldsize { return ReallocatePool(oldsize, newsize, ptr); } diff --git a/rEFIt_UEFI/Platform/Settings.cpp b/rEFIt_UEFI/Platform/Settings.cpp index 95a4f7219..b58ac8db5 100644 --- a/rEFIt_UEFI/Platform/Settings.cpp +++ b/rEFIt_UEFI/Platform/Settings.cpp @@ -32,7 +32,7 @@ #include "../../Version.h" #include "../Platform/Settings.h" -#include +#include "../../Include/Protocol/OcQuirksProtocol4Clover.h" #ifndef DEBUG_ALL #define DEBUG_SET 1 @@ -140,7 +140,7 @@ EFI_GUID gUuid; EMU_VARIABLE_CONTROL_PROTOCOL *gEmuVariableControl = NULL; extern BOOLEAN NeedPMfix; -OC_ABC_SETTINGS gQuirks; +OC_ABC_SETTINGS_4CLOVER gQuirks; BOOLEAN gProvideConsoleGopEnable; //extern INTN OldChosenAudio; @@ -2803,57 +2803,57 @@ GetEarlyUserSettings ( if (DictPointer != NULL) { const TagStruct* Prop; Prop = DictPointer->propertyForKey( "AvoidRuntimeDefrag"); - gQuirks.AvoidRuntimeDefrag = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.AvoidRuntimeDefrag? QUIRK_DEFRAG:0; + gQuirks.OcAbcSettings.AvoidRuntimeDefrag = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.AvoidRuntimeDefrag? QUIRK_DEFRAG:0; Prop = DictPointer->propertyForKey( "DevirtualiseMmio"); - gQuirks.DevirtualiseMmio = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.DevirtualiseMmio? QUIRK_MMIO:0; + gQuirks.OcAbcSettings.DevirtualiseMmio = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.DevirtualiseMmio? QUIRK_MMIO:0; Prop = DictPointer->propertyForKey( "DisableSingleUser"); - gQuirks.DisableSingleUser = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.DisableSingleUser? QUIRK_SU:0; + gQuirks.OcAbcSettings.DisableSingleUser = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.DisableSingleUser? QUIRK_SU:0; Prop = DictPointer->propertyForKey( "DisableVariableWrite"); - gQuirks.DisableVariableWrite = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.DisableVariableWrite? QUIRK_VAR:0; + gQuirks.OcAbcSettings.DisableVariableWrite = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.DisableVariableWrite? QUIRK_VAR:0; Prop = DictPointer->propertyForKey( "DiscardHibernateMap"); - gQuirks.DiscardHibernateMap = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.DiscardHibernateMap? QUIRK_HIBER:0; + gQuirks.OcAbcSettings.DiscardHibernateMap = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.DiscardHibernateMap? QUIRK_HIBER:0; Prop = DictPointer->propertyForKey( "EnableSafeModeSlide"); - gQuirks.EnableSafeModeSlide = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.EnableSafeModeSlide? QUIRK_SAFE:0; + gQuirks.OcAbcSettings.EnableSafeModeSlide = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.EnableSafeModeSlide? QUIRK_SAFE:0; Prop = DictPointer->propertyForKey( "EnableWriteUnprotector"); - gQuirks.EnableWriteUnprotector = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.EnableWriteUnprotector? QUIRK_UNPROT:0; + gQuirks.OcAbcSettings.EnableWriteUnprotector = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.EnableWriteUnprotector? QUIRK_UNPROT:0; Prop = DictPointer->propertyForKey( "ForceExitBootServices"); - gQuirks.ForceExitBootServices = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.ForceExitBootServices? QUIRK_EXIT:0; + gQuirks.OcAbcSettings.ForceExitBootServices = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.ForceExitBootServices? QUIRK_EXIT:0; Prop = DictPointer->propertyForKey( "ProtectMemoryRegions"); - gQuirks.ProtectMemoryRegions = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.ProtectMemoryRegions? QUIRK_REGION:0; + gQuirks.OcAbcSettings.ProtectMemoryRegions = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.ProtectMemoryRegions? QUIRK_REGION:0; Prop = DictPointer->propertyForKey( "ProtectSecureBoot"); - gQuirks.ProtectSecureBoot = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.ProtectMemoryRegions? QUIRK_SECURE:0; + gQuirks.OcAbcSettings.ProtectSecureBoot = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.ProtectMemoryRegions? QUIRK_SECURE:0; Prop = DictPointer->propertyForKey( "ProtectUefiServices"); - gQuirks.ProtectUefiServices = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.ProtectUefiServices? QUIRK_UEFI:0; + gQuirks.OcAbcSettings.ProtectUefiServices = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.ProtectUefiServices? QUIRK_UEFI:0; Prop = DictPointer->propertyForKey( "ProvideConsoleGopEnable"); gProvideConsoleGopEnable = IsPropertyNotNullAndTrue(Prop); Prop = DictPointer->propertyForKey( "ProvideCustomSlide"); - gQuirks.ProvideCustomSlide = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.ProvideCustomSlide? QUIRK_CUSTOM:0; + gQuirks.OcAbcSettings.ProvideCustomSlide = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.ProvideCustomSlide? QUIRK_CUSTOM:0; Prop = DictPointer->propertyForKey( "ProvideMaxSlide"); - gQuirks.ProvideMaxSlide = GetPropertyAsInteger(Prop, 0); + gQuirks.OcAbcSettings.ProvideMaxSlide = GetPropertyAsInteger(Prop, 0); Prop = DictPointer->propertyForKey( "RebuildAppleMemoryMap"); - gQuirks.RebuildAppleMemoryMap = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.RebuildAppleMemoryMap? QUIRK_MAP:0; + gQuirks.OcAbcSettings.RebuildAppleMemoryMap = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.RebuildAppleMemoryMap? QUIRK_MAP:0; Prop = DictPointer->propertyForKey( "SetupVirtualMap"); - gQuirks.SetupVirtualMap = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.SetupVirtualMap? QUIRK_VIRT:0; + gQuirks.OcAbcSettings.SetupVirtualMap = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.SetupVirtualMap? QUIRK_VIRT:0; Prop = DictPointer->propertyForKey( "SignalAppleOS"); - gQuirks.SignalAppleOS = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.SignalAppleOS? QUIRK_OS:0; + gQuirks.OcAbcSettings.SignalAppleOS = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.SignalAppleOS? QUIRK_OS:0; Prop = DictPointer->propertyForKey( "SyncRuntimePermissions"); - gQuirks.SyncRuntimePermissions = IsPropertyNotNullAndTrue(Prop); - gSettings.QuirksMask |= gQuirks.SyncRuntimePermissions? QUIRK_PERM:0; + gQuirks.OcAbcSettings.SyncRuntimePermissions = IsPropertyNotNullAndTrue(Prop); + gSettings.QuirksMask |= gQuirks.OcAbcSettings.SyncRuntimePermissions? QUIRK_PERM:0; const TagArray* Dict2 = DictPointer->arrayPropertyForKey("MmioWhitelist"); // array of dict if (Dict2 != NULL) { INTN Count = Dict2->arrayContent().size(); @@ -2862,28 +2862,28 @@ GetEarlyUserSettings ( //OC_SCHEMA_BOOLEAN_IN ("Enabled", OC_MMIO_WL_STRUCT, Enabled), if (Count > 0) { gQuirks.MmioWhitelistLabels = (__typeof__(gQuirks.MmioWhitelistLabels))AllocatePool(sizeof(char*) * Count); - gQuirks.MmioWhitelist = (__typeof__(gQuirks.MmioWhitelist))AllocatePool(sizeof(*gQuirks.MmioWhitelist) * Count); + gQuirks.OcAbcSettings.MmioWhitelist = (__typeof__(gQuirks.OcAbcSettings.MmioWhitelist))AllocatePool(sizeof(*gQuirks.OcAbcSettings.MmioWhitelist) * Count); gQuirks.MmioWhitelistEnabled = (__typeof__(gQuirks.MmioWhitelistEnabled))AllocatePool(sizeof(BOOLEAN) * Count); - gQuirks.MmioWhitelistSize = 0; + gQuirks.OcAbcSettings.MmioWhitelistSize = 0; for (INTN i = 0; i < Count; i++) { const TagDict* Dict3 = Dict2->dictElementAt(i, "MmioWhitelist"_XS8); - gQuirks.MmioWhitelistLabels[gQuirks.MmioWhitelistSize] = (__typeof__(char *))AllocateZeroPool(256); + gQuirks.MmioWhitelistLabels[gQuirks.OcAbcSettings.MmioWhitelistSize] = (__typeof__(char *))AllocateZeroPool(256); const TagStruct* Prop2 = Dict3->propertyForKey("Comment"); if (Prop2 != NULL && (Prop2->isString()) && Prop2->getString()->stringValue().notEmpty()) { - snprintf(gQuirks.MmioWhitelistLabels[gQuirks.MmioWhitelistSize], 255, "%s", Prop2->getString()->stringValue().c_str()); + snprintf(gQuirks.MmioWhitelistLabels[gQuirks.OcAbcSettings.MmioWhitelistSize], 255, "%s", Prop2->getString()->stringValue().c_str()); } else { - snprintf(gQuirks.MmioWhitelistLabels[gQuirks.MmioWhitelistSize], 255, " (NoLabel)"); + snprintf(gQuirks.MmioWhitelistLabels[gQuirks.OcAbcSettings.MmioWhitelistSize], 255, " (NoLabel)"); } Prop2 = Dict3->propertyForKey("Address"); if (Prop2 != 0) { - gQuirks.MmioWhitelist[gQuirks.MmioWhitelistSize] = GetPropertyAsInteger(Prop2, 0); + gQuirks.OcAbcSettings.MmioWhitelist[gQuirks.OcAbcSettings.MmioWhitelistSize] = GetPropertyAsInteger(Prop2, 0); Prop2 = Dict3->propertyForKey("Enabled"); - gQuirks.MmioWhitelistEnabled[gQuirks.MmioWhitelistSize] = IsPropertyNotNullAndTrue(Prop2); + gQuirks.MmioWhitelistEnabled[gQuirks.OcAbcSettings.MmioWhitelistSize] = IsPropertyNotNullAndTrue(Prop2); } - gQuirks.MmioWhitelistSize++; + gQuirks.OcAbcSettings.MmioWhitelistSize++; } } } diff --git a/rEFIt_UEFI/Platform/boot.h b/rEFIt_UEFI/Platform/boot.h index 1c8995f8d..cbddb2340 100644 --- a/rEFIt_UEFI/Platform/boot.h +++ b/rEFIt_UEFI/Platform/boot.h @@ -80,28 +80,40 @@ typedef struct EfiMemoryRange { * Video information.. */ -struct Boot_VideoV1 { - UINT32 v_baseAddr; /* Base address of video memory */ - UINT32 v_display; /* Display Code (if Applicable */ - UINT32 v_rowBytes; /* Number of bytes per pixel row */ - UINT32 v_width; /* Width */ - UINT32 v_height; /* Height */ - UINT32 v_depth; /* Pixel Depth */ -}; -typedef struct Boot_VideoV1 Boot_VideoV1; +#include +/* Bitfields for boot_args->flags */ +//#define kBootArgsFlagRebootOnPanic (1 << 0) +//#define kBootArgsFlagHiDPI (1 << 1) +//#define kBootArgsFlagBlack (1 << 2) +//#define kBootArgsFlagCSRActiveConfig (1 << 3) +//#define kBootArgsFlagCSRPendingConfig (1 << 4) +//#define kBootArgsFlagCSRBoot (1 << 5) +//#define kBootArgsFlagBlackBg (1 << 6) +//#define kBootArgsFlagLoginUI (1 << 7) +//#define kBootArgsFlagInstallUI (1 << 8) -struct Boot_Video { - uint32_t v_display; /* Display Code (if Applicable */ - uint32_t v_rowBytes; /* Number of bytes per pixel row */ - uint32_t v_width; /* Width */ - uint32_t v_height; /* Height */ - uint32_t v_depth; /* Pixel Depth */ - uint8_t v_rotate; /* Rotation */ - uint8_t v_resv_byte[3]; /* Reserved */ - uint32_t v_resv[6]; /* Reserved */ - uint64_t v_baseAddr; /* Base address of video memory */ -}; -typedef struct Boot_Video Boot_Video; +//struct Boot_VideoV1 { +// UINT32 v_baseAddr; /* Base address of video memory */ +// UINT32 v_display; /* Display Code (if Applicable */ +// UINT32 v_rowBytes; /* Number of bytes per pixel row */ +// UINT32 v_width; /* Width */ +// UINT32 v_height; /* Height */ +// UINT32 v_depth; /* Pixel Depth */ +//}; +//typedef struct Boot_VideoV1 Boot_VideoV1; +// +//struct Boot_Video { +// uint32_t v_display; /* Display Code (if Applicable */ +// uint32_t v_rowBytes; /* Number of bytes per pixel row */ +// uint32_t v_width; /* Width */ +// uint32_t v_height; /* Height */ +// uint32_t v_depth; /* Pixel Depth */ +// uint8_t v_rotate; /* Rotation */ +// uint8_t v_resv_byte[3]; /* Reserved */ +// uint32_t v_resv[6]; /* Reserved */ +// uint64_t v_baseAddr; /* Base address of video memory */ +//}; +//typedef struct Boot_Video Boot_Video; /* Values for v_display */ @@ -135,17 +147,6 @@ typedef struct Boot_Video Boot_Video; #define kBootArgsEfiMode32 32 #define kBootArgsEfiMode64 64 -/* Bitfields for boot_args->flags */ -#define kBootArgsFlagRebootOnPanic (1 << 0) -#define kBootArgsFlagHiDPI (1 << 1) -#define kBootArgsFlagBlack (1 << 2) -#define kBootArgsFlagCSRActiveConfig (1 << 3) -#define kBootArgsFlagCSRPendingConfig (1 << 4) -#define kBootArgsFlagCSRBoot (1 << 5) -#define kBootArgsFlagBlackBg (1 << 6) -#define kBootArgsFlagLoginUI (1 << 7) -#define kBootArgsFlagInstallUI (1 << 8) - /* Rootless configuration flags */ #define CSR_ALLOW_UNTRUSTED_KEXTS (1 << 0) #define CSR_ALLOW_UNRESTRICTED_FS (1 << 1) @@ -182,106 +183,106 @@ typedef struct Boot_Video Boot_Video; #define CSR_VALID_CAPABILITIES (CSR_CAPABILITY_UNLIMITED | CSR_CAPABILITY_CONFIG | CSR_CAPABILITY_APPLE_INTERNAL) -//BootArgs1 used for 32bit systems up to 10.6.8 -typedef struct { - UINT16 Revision; /* Revision of boot_args structure */ - UINT16 Version; /* Version of boot_args structure */ - - CHAR8 CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ - - UINT32 MemoryMap; /* Physical address of memory map */ - UINT32 MemoryMapSize; - UINT32 MemoryMapDescriptorSize; - UINT32 MemoryMapDescriptorVersion; - - Boot_VideoV1 Video; /* Video Information */ - - UINT32 deviceTreeP; /* Physical address of flattened device tree */ - UINT32 deviceTreeLength; /* Length of flattened tree */ - - UINT32 kaddr; /* Physical address of beginning of kernel text */ - UINT32 ksize; /* Size of combined kernel text+data+efi */ - - UINT32 efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ - UINT32 efiRuntimeServicesPageCount; - UINT32 efiSystemTable; /* physical address of system table in runtime area */ - - UINT8 efiMode; /* 32 = 32-bit, 64 = 64-bit */ - UINT8 __reserved1[3]; - UINT32 __reserved2[1]; - UINT32 performanceDataStart; /* physical address of log */ - UINT32 performanceDataSize; - UINT64 efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ - UINT32 __reserved3[2]; - -} BootArgs1; -//version2 as used in Lion and up -typedef struct { - - UINT16 Revision; /* Revision of boot_args structure */ - UINT16 Version; /* Version of boot_args structure */ - - UINT8 efiMode; /* 32 = 32-bit, 64 = 64-bit */ - UINT8 debugMode; /* Bit field with behavior changes */ - UINT16 flags; - - CHAR8 CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ - - UINT32 MemoryMap; /* Physical address of memory map */ - UINT32 MemoryMapSize; - UINT32 MemoryMapDescriptorSize; - UINT32 MemoryMapDescriptorVersion; - - Boot_VideoV1 VideoV1; /* Old Video Information */ - - UINT32 deviceTreeP; /* Physical address of flattened device tree */ - UINT32 deviceTreeLength; /* Length of flattened tree */ - - UINT32 kaddr; /* Physical address of beginning of kernel text */ - UINT32 ksize; /* Size of combined kernel text+data+efi */ - - UINT32 efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ - UINT32 efiRuntimeServicesPageCount; - UINT64 efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ - - UINT32 efiSystemTable; /* physical address of system table in runtime area */ - UINT32 kslide; /* in Lion: reserved and 0; in ML: kernel image "sliding offset" (KASLR slide) */ - - UINT32 performanceDataStart; /* physical address of log */ - UINT32 performanceDataSize; - - UINT32 keyStoreDataStart; /* physical address of key store data */ - UINT32 keyStoreDataSize; - UINT64 bootMemStart; /* physical address of interpreter boot memory */ - UINT64 bootMemSize; - UINT64 PhysicalMemorySize; - UINT64 FSBFrequency; - UINT64 pciConfigSpaceBaseAddress; - UINT32 pciConfigSpaceStartBusNumber; - UINT32 pciConfigSpaceEndBusNumber; - UINT32 csrActiveConfig; - UINT32 csrCapabilities; - UINT32 boot_SMC_plimit; - UINT16 bootProgressMeterStart; - UINT16 bootProgressMeterEnd; - Boot_Video Video; /* Video Information */ - - UINT32 apfsDataStart;/* Physical address of apfs volume key structure */ - UINT32 apfsDataSize; - - /* Version 2, Revision 1 */ - UINT64 KC_hdrs_vaddr; /* First kernel virtual address pointing to Mach-O headers */ - - UINT64 arvRootHashStart; /* Physical address of root hash file */ - UINT64 arvRootHashSize; - - UINT64 arvManifestStart; /* Physical address of manifest file */ - UINT64 arvManifestSize; - - /* Reserved */ - UINT32 __reserved4[700]; - -} BootArgs2; +////BootArgs1 used for 32bit systems up to 10.6.8 +//typedef struct { +// UINT16 Revision; /* Revision of boot_args structure */ +// UINT16 Version; /* Version of boot_args structure */ +// +// CHAR8 CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ +// +// UINT32 MemoryMap; /* Physical address of memory map */ +// UINT32 MemoryMapSize; +// UINT32 MemoryMapDescriptorSize; +// UINT32 MemoryMapDescriptorVersion; +// +// Boot_VideoV1 Video; /* Video Information */ +// +// UINT32 deviceTreeP; /* Physical address of flattened device tree */ +// UINT32 deviceTreeLength; /* Length of flattened tree */ +// +// UINT32 kaddr; /* Physical address of beginning of kernel text */ +// UINT32 ksize; /* Size of combined kernel text+data+efi */ +// +// UINT32 efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ +// UINT32 efiRuntimeServicesPageCount; +// UINT32 efiSystemTable; /* physical address of system table in runtime area */ +// +// UINT8 efiMode; /* 32 = 32-bit, 64 = 64-bit */ +// UINT8 __reserved1[3]; +// UINT32 __reserved2[1]; +// UINT32 performanceDataStart; /* physical address of log */ +// UINT32 performanceDataSize; +// UINT64 efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ +// UINT32 __reserved3[2]; +// +//} BootArgs1; +////version2 as used in Lion and up +//typedef struct { +// +// UINT16 Revision; /* Revision of boot_args structure */ +// UINT16 Version; /* Version of boot_args structure */ +// +// UINT8 efiMode; /* 32 = 32-bit, 64 = 64-bit */ +// UINT8 debugMode; /* Bit field with behavior changes */ +// UINT16 flags; +// +// CHAR8 CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ +// +// UINT32 MemoryMap; /* Physical address of memory map */ +// UINT32 MemoryMapSize; +// UINT32 MemoryMapDescriptorSize; +// UINT32 MemoryMapDescriptorVersion; +// +// Boot_VideoV1 VideoV1; /* Old Video Information */ +// +// UINT32 deviceTreeP; /* Physical address of flattened device tree */ +// UINT32 deviceTreeLength; /* Length of flattened tree */ +// +// UINT32 kaddr; /* Physical address of beginning of kernel text */ +// UINT32 ksize; /* Size of combined kernel text+data+efi */ +// +// UINT32 efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ +// UINT32 efiRuntimeServicesPageCount; +// UINT64 efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ +// +// UINT32 efiSystemTable; /* physical address of system table in runtime area */ +// UINT32 kslide; /* in Lion: reserved and 0; in ML: kernel image "sliding offset" (KASLR slide) */ +// +// UINT32 performanceDataStart; /* physical address of log */ +// UINT32 performanceDataSize; +// +// UINT32 keyStoreDataStart; /* physical address of key store data */ +// UINT32 keyStoreDataSize; +// UINT64 bootMemStart; /* physical address of interpreter boot memory */ +// UINT64 bootMemSize; +// UINT64 PhysicalMemorySize; +// UINT64 FSBFrequency; +// UINT64 pciConfigSpaceBaseAddress; +// UINT32 pciConfigSpaceStartBusNumber; +// UINT32 pciConfigSpaceEndBusNumber; +// UINT32 csrActiveConfig; +// UINT32 csrCapabilities; +// UINT32 boot_SMC_plimit; +// UINT16 bootProgressMeterStart; +// UINT16 bootProgressMeterEnd; +// Boot_Video Video; /* Video Information */ +// +// UINT32 apfsDataStart;/* Physical address of apfs volume key structure */ +// UINT32 apfsDataSize; +// +// /* Version 2, Revision 1 */ +// UINT64 KC_hdrs_vaddr; /* First kernel virtual address pointing to Mach-O headers */ +// +// UINT64 arvRootHashStart; /* Physical address of root hash file */ +// UINT64 arvRootHashSize; +// +// UINT64 arvManifestStart; /* Physical address of manifest file */ +// UINT64 arvManifestSize; +// +// /* Reserved */ +// UINT32 __reserved4[700]; +// +//} BootArgs2; #endif /* _PEXPERT_I386_BOOT_H */ diff --git a/rEFIt_UEFI/Platform/cpu.h b/rEFIt_UEFI/Platform/cpu.h index 2a379d4f5..5d552ab15 100644 --- a/rEFIt_UEFI/Platform/cpu.h +++ b/rEFIt_UEFI/Platform/cpu.h @@ -9,6 +9,7 @@ #define PLATFORM_CPU_H_ #include "platformdata.h" +#include #define CPU_MODEL_PENTIUM_M 0x09 #define CPU_MODEL_DOTHAN 0x0D @@ -82,67 +83,67 @@ const char CPU_STRING_UNKNOWN[] = "Unknown CPU Type"; * The CPUID_FEATURE_XXX values define 64-bit values * returned in %ecx:%edx to a CPUID request with %eax of 1: */ -#define CPUID_FEATURE_FPU _Bit(0) /* Floating point unit on-chip */ -#define CPUID_FEATURE_VME _Bit(1) /* Virtual Mode Extension */ -#define CPUID_FEATURE_DE _Bit(2) /* Debugging Extension */ -#define CPUID_FEATURE_PSE _Bit(3) /* Page Size Extension */ -#define CPUID_FEATURE_TSC _Bit(4) /* Time Stamp Counter */ -#define CPUID_FEATURE_MSR _Bit(5) /* Model Specific Registers */ -#define CPUID_FEATURE_PAE _Bit(6) /* Physical Address Extension */ -#define CPUID_FEATURE_MCE _Bit(7) /* Machine Check Exception */ -#define CPUID_FEATURE_CX8 _Bit(8) /* CMPXCHG8B */ -#define CPUID_FEATURE_APIC _Bit(9) /* On-chip APIC */ -#define CPUID_FEATURE_SEP _Bit(11) /* Fast System Call */ -#define CPUID_FEATURE_MTRR _Bit(12) /* Memory Type Range Register */ -#define CPUID_FEATURE_PGE _Bit(13) /* Page Global Enable */ -#define CPUID_FEATURE_MCA _Bit(14) /* Machine Check Architecture */ -#define CPUID_FEATURE_CMOV _Bit(15) /* Conditional Move Instruction */ -#define CPUID_FEATURE_PAT _Bit(16) /* Page Attribute Table */ -#define CPUID_FEATURE_PSE36 _Bit(17) /* 36-bit Page Size Extension */ -#define CPUID_FEATURE_PSN _Bit(18) /* Processor Serial Number */ -#define CPUID_FEATURE_CLFSH _Bit(19) /* CLFLUSH Instruction supported */ -#define CPUID_FEATURE_DS _Bit(21) /* Debug Store */ -#define CPUID_FEATURE_ACPI _Bit(22) /* Thermal monitor and Clock Ctrl */ -#define CPUID_FEATURE_MMX _Bit(23) /* MMX supported */ -#define CPUID_FEATURE_FXSR _Bit(24) /* Fast floating pt save/restore */ -#define CPUID_FEATURE_SSE _Bit(25) /* Streaming SIMD extensions */ -#define CPUID_FEATURE_SSE2 _Bit(26) /* Streaming SIMD extensions 2 */ -#define CPUID_FEATURE_SS _Bit(27) /* Self-Snoop */ -#define CPUID_FEATURE_HTT _Bit(28) /* Hyper-Threading Technology */ -#define CPUID_FEATURE_TM _Bit(29) /* Thermal Monitor (TM1) */ -#define CPUID_FEATURE_PBE _Bit(31) /* Pend Break Enable */ - -#define CPUID_FEATURE_SSE3 _HBit(0) /* Streaming SIMD extensions 3 */ -#define CPUID_FEATURE_PCLMULQDQ _HBit(1) /* PCLMULQDQ Instruction */ -#define CPUID_FEATURE_DTES64 _HBit(2) /* 64-bit DS layout */ -#define CPUID_FEATURE_MONITOR _HBit(3) /* Monitor/mwait */ -#define CPUID_FEATURE_DSCPL _HBit(4) /* Debug Store CPL */ -#define CPUID_FEATURE_VMX _HBit(5) /* VMX */ -#define CPUID_FEATURE_SMX _HBit(6) /* SMX */ -#define CPUID_FEATURE_EST _HBit(7) /* Enhanced SpeedsTep (GV3) */ -#define CPUID_FEATURE_TM2 _HBit(8) /* Thermal Monitor 2 */ -#define CPUID_FEATURE_SSSE3 _HBit(9) /* Supplemental SSE3 instructions */ -#define CPUID_FEATURE_CID _HBit(10) /* L1 Context ID */ -#define CPUID_FEATURE_SEGLIM64 _HBit(11) /* 64-bit segment limit checking */ -#define CPUID_FEATURE_CX16 _HBit(13) /* CmpXchg16b instruction */ -#define CPUID_FEATURE_xTPR _HBit(14) /* Send Task PRiority msgs */ -#define CPUID_FEATURE_PDCM _HBit(15) /* Perf/Debug Capability MSR */ - -#define CPUID_FEATURE_PCID _HBit(17) /* ASID-PCID support */ -#define CPUID_FEATURE_DCA _HBit(18) /* Direct Cache Access */ -#define CPUID_FEATURE_SSE4_1 _HBit(19) /* Streaming SIMD extensions 4.1 */ -#define CPUID_FEATURE_SSE4_2 _HBit(20) /* Streaming SIMD extensions 4.2 */ -#define CPUID_FEATURE_xAPIC _HBit(21) /* Extended APIC Mode */ -#define CPUID_FEATURE_MOVBE _HBit(22) /* MOVBE instruction */ -#define CPUID_FEATURE_POPCNT _HBit(23) /* POPCNT instruction */ -#define CPUID_FEATURE_TSCTMR _HBit(24) /* TSC deadline timer */ -#define CPUID_FEATURE_AES _HBit(25) /* AES instructions */ -#define CPUID_FEATURE_XSAVE _HBit(26) /* XSAVE instructions */ -#define CPUID_FEATURE_OSXSAVE _HBit(27) /* XGETBV/XSETBV instructions */ -#define CPUID_FEATURE_AVX1_0 _HBit(28) /* AVX 1.0 instructions */ -#define CPUID_FEATURE_RDRAND _HBit(29) /* RDRAND instruction */ -#define CPUID_FEATURE_F16C _HBit(30) /* Float16 convert instructions */ -#define CPUID_FEATURE_VMM _HBit(31) /* VMM (Hypervisor) present */ +//#define CPUID_FEATURE_FPU _Bit(0) /* Floating point unit on-chip */ +//#define CPUID_FEATURE_VME _Bit(1) /* Virtual Mode Extension */ +//#define CPUID_FEATURE_DE _Bit(2) /* Debugging Extension */ +//#define CPUID_FEATURE_PSE _Bit(3) /* Page Size Extension */ +//#define CPUID_FEATURE_TSC _Bit(4) /* Time Stamp Counter */ +//#define CPUID_FEATURE_MSR _Bit(5) /* Model Specific Registers */ +//#define CPUID_FEATURE_PAE _Bit(6) /* Physical Address Extension */ +//#define CPUID_FEATURE_MCE _Bit(7) /* Machine Check Exception */ +//#define CPUID_FEATURE_CX8 _Bit(8) /* CMPXCHG8B */ +//#define CPUID_FEATURE_APIC _Bit(9) /* On-chip APIC */ +//#define CPUID_FEATURE_SEP _Bit(11) /* Fast System Call */ +//#define CPUID_FEATURE_MTRR _Bit(12) /* Memory Type Range Register */ +//#define CPUID_FEATURE_PGE _Bit(13) /* Page Global Enable */ +//#define CPUID_FEATURE_MCA _Bit(14) /* Machine Check Architecture */ +//#define CPUID_FEATURE_CMOV _Bit(15) /* Conditional Move Instruction */ +//#define CPUID_FEATURE_PAT _Bit(16) /* Page Attribute Table */ +//#define CPUID_FEATURE_PSE36 _Bit(17) /* 36-bit Page Size Extension */ +//#define CPUID_FEATURE_PSN _Bit(18) /* Processor Serial Number */ +//#define CPUID_FEATURE_CLFSH _Bit(19) /* CLFLUSH Instruction supported */ +//#define CPUID_FEATURE_DS _Bit(21) /* Debug Store */ +//#define CPUID_FEATURE_ACPI _Bit(22) /* Thermal monitor and Clock Ctrl */ +//#define CPUID_FEATURE_MMX _Bit(23) /* MMX supported */ +//#define CPUID_FEATURE_FXSR _Bit(24) /* Fast floating pt save/restore */ +//#define CPUID_FEATURE_SSE _Bit(25) /* Streaming SIMD extensions */ +//#define CPUID_FEATURE_SSE2 _Bit(26) /* Streaming SIMD extensions 2 */ +//#define CPUID_FEATURE_SS _Bit(27) /* Self-Snoop */ +//#define CPUID_FEATURE_HTT _Bit(28) /* Hyper-Threading Technology */ +//#define CPUID_FEATURE_TM _Bit(29) /* Thermal Monitor (TM1) */ +//#define CPUID_FEATURE_PBE _Bit(31) /* Pend Break Enable */ +// +//#define CPUID_FEATURE_SSE3 _HBit(0) /* Streaming SIMD extensions 3 */ +//#define CPUID_FEATURE_PCLMULQDQ _HBit(1) /* PCLMULQDQ Instruction */ +//#define CPUID_FEATURE_DTES64 _HBit(2) /* 64-bit DS layout */ +//#define CPUID_FEATURE_MONITOR _HBit(3) /* Monitor/mwait */ +//#define CPUID_FEATURE_DSCPL _HBit(4) /* Debug Store CPL */ +//#define CPUID_FEATURE_VMX _HBit(5) /* VMX */ +//#define CPUID_FEATURE_SMX _HBit(6) /* SMX */ +//#define CPUID_FEATURE_EST _HBit(7) /* Enhanced SpeedsTep (GV3) */ +//#define CPUID_FEATURE_TM2 _HBit(8) /* Thermal Monitor 2 */ +//#define CPUID_FEATURE_SSSE3 _HBit(9) /* Supplemental SSE3 instructions */ +//#define CPUID_FEATURE_CID _HBit(10) /* L1 Context ID */ +//#define CPUID_FEATURE_SEGLIM64 _HBit(11) /* 64-bit segment limit checking */ +//#define CPUID_FEATURE_CX16 _HBit(13) /* CmpXchg16b instruction */ +//#define CPUID_FEATURE_xTPR _HBit(14) /* Send Task PRiority msgs */ +//#define CPUID_FEATURE_PDCM _HBit(15) /* Perf/Debug Capability MSR */ +// +//#define CPUID_FEATURE_PCID _HBit(17) /* ASID-PCID support */ +//#define CPUID_FEATURE_DCA _HBit(18) /* Direct Cache Access */ +//#define CPUID_FEATURE_SSE4_1 _HBit(19) /* Streaming SIMD extensions 4.1 */ +//#define CPUID_FEATURE_SSE4_2 _HBit(20) /* Streaming SIMD extensions 4.2 */ +//#define CPUID_FEATURE_xAPIC _HBit(21) /* Extended APIC Mode */ +//#define CPUID_FEATURE_MOVBE _HBit(22) /* MOVBE instruction */ +//#define CPUID_FEATURE_POPCNT _HBit(23) /* POPCNT instruction */ +//#define CPUID_FEATURE_TSCTMR _HBit(24) /* TSC deadline timer */ +//#define CPUID_FEATURE_AES _HBit(25) /* AES instructions */ +//#define CPUID_FEATURE_XSAVE _HBit(26) /* XSAVE instructions */ +//#define CPUID_FEATURE_OSXSAVE _HBit(27) /* XGETBV/XSETBV instructions */ +//#define CPUID_FEATURE_AVX1_0 _HBit(28) /* AVX 1.0 instructions */ +//#define CPUID_FEATURE_RDRAND _HBit(29) /* RDRAND instruction */ +//#define CPUID_FEATURE_F16C _HBit(30) /* Float16 convert instructions */ +//#define CPUID_FEATURE_VMM _HBit(31) /* VMM (Hypervisor) present */ /* * Leaf 7, subleaf 0 additional features. @@ -157,20 +158,20 @@ const char CPU_STRING_UNKNOWN[] = "Unknown CPU Type"; * The CPUID_EXTFEATURE_XXX values define 64-bit values * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001: */ -#define CPUID_EXTFEATURE_SYSCALL _Bit(11) /* SYSCALL/sysret */ -#define CPUID_EXTFEATURE_XD _Bit(20) /* eXecute Disable */ -#define CPUID_EXTFEATURE_1GBPAGE _Bit(26) /* 1G-Byte Page support */ -#define CPUID_EXTFEATURE_RDTSCP _Bit(27) /* RDTSCP */ -#define CPUID_EXTFEATURE_EM64T _Bit(29) /* Extended Mem 64 Technology */ - -//#define CPUID_EXTFEATURE_LAHF _HBit(20) /* LAFH/SAHF instructions */ -// New definition with Snow kernel -#define CPUID_EXTFEATURE_LAHF _HBit(0) /* LAHF/SAHF instructions */ -/* - * The CPUID_EXTFEATURE_XXX values define 64-bit values - * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007: - */ -#define CPUID_EXTFEATURE_TSCI _Bit(8) /* TSC Invariant */ +//#define CPUID_EXTFEATURE_SYSCALL _Bit(11) /* SYSCALL/sysret */ +//#define CPUID_EXTFEATURE_XD _Bit(20) /* eXecute Disable */ +//#define CPUID_EXTFEATURE_1GBPAGE _Bit(26) /* 1G-Byte Page support */ // ATTENTION : seems wrong. It's BIT21 in Cpuid.h. Not used in Clover. +//#define CPUID_EXTFEATURE_RDTSCP _Bit(27) /* RDTSCP */ +//#define CPUID_EXTFEATURE_EM64T _Bit(29) /* Extended Mem 64 Technology */ +// +////#define CPUID_EXTFEATURE_LAHF _HBit(20) /* LAFH/SAHF instructions */ +//// New definition with Snow kernel +//#define CPUID_EXTFEATURE_LAHF _HBit(0) /* LAHF/SAHF instructions */ +///* +// * The CPUID_EXTFEATURE_XXX values define 64-bit values +// * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007: +// */ +//#define CPUID_EXTFEATURE_TSCI _Bit(8) /* TSC Invariant */ #define CPUID_CACHE_SIZE 16 /* Number of descriptor values */ diff --git a/rEFIt_UEFI/Platform/guid.cpp b/rEFIt_UEFI/Platform/guid.cpp index 18bec96ed..990f48c47 100644 --- a/rEFIt_UEFI/Platform/guid.cpp +++ b/rEFIt_UEFI/Platform/guid.cpp @@ -22,10 +22,10 @@ //EFI_GUID gAppleEFINVRAMTRBSecureGuid = {0xF68DA75E, 0x1B55, 0x4E70, {0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA}}; //EFI_GUID gDataHubOptionsGuid = {0x0021001C, 0x3CE3, 0x41F8, {0x99, 0xC6, 0xEC, 0xF5, 0xDA, 0x75, 0x47, 0x31}}; EFI_GUID gNotifyMouseActivity = {0xF913C2C2, 0x5351, 0x4FDB, {0x93, 0x44, 0x70, 0xFF, 0xED, 0xB8, 0x42, 0x25}}; -EFI_GUID gEfiDataHubProtocolGuid = {0xAE80D021, 0x618E, 0x11D4, {0xBC, 0xD7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}}; -EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; -EFI_GUID gEfiProcessorSubClassGuid = {0x26FDEB7E, 0xB8AF, 0x4CCF, {0xAA, 0x97, 0x02, 0x63, 0x3C, 0xE4, 0x8C, 0xA7}}; -EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; +//EFI_GUID gEfiDataHubProtocolGuid = {0xAE80D021, 0x618E, 0x11D4, {0xBC, 0xD7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}}; +//EFI_GUID gEfiMiscSubClassGuid = {0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81}}; +//EFI_GUID gEfiProcessorSubClassGuid = {0x26FDEB7E, 0xB8AF, 0x4CCF, {0xAA, 0x97, 0x02, 0x63, 0x3C, 0xE4, 0x8C, 0xA7}}; +//EFI_GUID gEfiMemorySubClassGuid = {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97}}; //EFI_GUID gMsgLogProtocolGuid = {0x511CE018, 0x0018, 0x4002, {0x20, 0x12, 0x17, 0x38, 0x05, 0x01, 0x02, 0x03}}; //EFI_GUID gEfiLegacy8259ProtocolGuid = {0x38321DBA, 0x4FE0, 0x4E17, {0x8A, 0xEC, 0x41, 0x30, 0x55, 0xEA, 0xED, 0xC1}}; EFI_GUID gAppleDeviceControlProtocolGuid = {0x8ECE08D8, 0xA6D4, 0x430B, {0xA7, 0xB0, 0x2D, 0xF3, 0x18, 0xE7, 0x88, 0x4A}}; diff --git a/rEFIt_UEFI/Platform/kernel_patcher.h b/rEFIt_UEFI/Platform/kernel_patcher.h index 97000845e..3518fb3f3 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.h +++ b/rEFIt_UEFI/Platform/kernel_patcher.h @@ -124,6 +124,7 @@ typedef struct SEGMENT { UINT32 SizeNamesTable; } SEGMENT; +extern LIST_ENTRY gKextList; // Jief : globals variables... not great. //extern EFI_PHYSICAL_ADDRESS KernelRelocBase; //extern BootArgs1 *bootArgs1; diff --git a/rEFIt_UEFI/Platform/kext_inject.cpp b/rEFIt_UEFI/Platform/kext_inject.cpp index 200e629c1..df0af1dbd 100644 --- a/rEFIt_UEFI/Platform/kext_inject.cpp +++ b/rEFIt_UEFI/Platform/kext_inject.cpp @@ -1,4 +1,10 @@ +/* + * + */ #include // Only use angled for Platform, else, xcode project won't compile +extern "C" { +#include +} #include "kext_inject.h" #include "DataHubCpu.h" #include "../Platform/plist/plist.h" @@ -336,6 +342,53 @@ VOID LOADER_ENTRY::AddKexts(const XStringW& SrcDir, const XStringW& Path, cpu_ty } +// Jief : this should replace LOADER_ENTRY::AddKexts +VOID LOADER_ENTRY::AddKextsInArray(const XStringW& SrcDir, const XStringW& Path, cpu_type_t archCpuType, XObjArray* kextArray) +{ + XStringW FileName; + XStringW PlugInName; + SIDELOAD_KEXT *CurrentKext; + SIDELOAD_KEXT *CurrentPlugInKext; + + MsgLog("Preparing kexts injection from %ls\n", SrcDir.wc_str()); + CurrentKext = InjectKextList; + while (CurrentKext) { +// DBG(" current kext name=%ls path=%ls, match against=%ls\n", CurrentKext->FileName, CurrentKext->KextDirNameUnderOEMPath, Path); + if ( CurrentKext->KextDirNameUnderOEMPath == Path ) { + FileName = SWPrintf("%ls\\%ls", SrcDir.wc_str(), CurrentKext->FileName.wc_str()); + // snwprintf(FileName, 512, "%s\\%s", SrcDir, CurrentKext->FileName); + if (!(CurrentKext->MenuItem.BValue)) { + // inject require + MsgLog("->Extra kext: %ls (v.%ls)\n", FileName.wc_str(), CurrentKext->Version.wc_str()); +// Status = AddKext(SelfVolume->RootDir, FileName.wc_str(), archCpuType); + kextArray->AddReference(CurrentKext, false); // do not free, CurrentKext belongs to an other object + // decide which plugins to inject + CurrentPlugInKext = CurrentKext->PlugInList; + while (CurrentPlugInKext) { + PlugInName = SWPrintf("%ls\\%ls\\%ls", FileName.wc_str(), L"Contents\\PlugIns", CurrentPlugInKext->FileName.wc_str()); + // snwprintf(PlugInName, 512, L"%s\\%s\\%s", FileName, "Contents\\PlugIns", CurrentPlugInKext->FileName); + if (!(CurrentPlugInKext->MenuItem.BValue)) { + // inject PlugIn require + MsgLog(" |-- PlugIn kext: %ls (v.%ls)\n", PlugInName.wc_str(), CurrentPlugInKext->Version.wc_str()); +// AddKext(SelfVolume->RootDir, PlugInName.wc_str(), archCpuType); + kextArray->AddReference(CurrentPlugInKext, false); // do not free, CurrentKext belongs to an other object + } else { + MsgLog(" |-- Disabled plug-in kext: %ls (v.%ls)\n", PlugInName.wc_str(), CurrentPlugInKext->Version.wc_str()); + } + CurrentPlugInKext = CurrentPlugInKext->Next; + } // end of plug-in kext injection + } else { + // disable current kext injection + if ( SrcDir.containsIC(L"Off") ) { + MsgLog("Disabled kext: %ls (v.%ls)\n", FileName.wc_str(), CurrentKext->Version.wc_str()); + } + } + } + CurrentKext = CurrentKext->Next; + } // end of kext injection + +} + EFI_STATUS LOADER_ENTRY::LoadKexts() { XStringW SrcDir; @@ -439,6 +492,8 @@ EFI_STATUS LOADER_ENTRY::LoadKexts() DBG("GetOtherKextsDir(FALSE) return NULL\n"); } + if ( !OSVersion.contains(".") ) panic("!OSVersion.contains('.')"); + XStringW osMajorVersion = OSVersion.subString(0, OSVersion.indexOf('.')); // Add kext from 10 { XStringW OSAllVersionKextsDir; @@ -446,90 +501,74 @@ EFI_STATUS LOADER_ENTRY::LoadKexts() XStringW OSVersionKextsDirName; XStringW DirName; XStringW DirPath; - OSAllVersionKextsDir = SWPrintf("%ls\\kexts\\10", OEMPath.wc_str()); - // snwprintf(OSAllVersionKextsDir, sizeof(OSAllVersionKextsDir), "%s\\kexts\\10", OEMPath); - AddKexts(OSAllVersionKextsDir, L"10"_XSW, archCpuType); + + OSAllVersionKextsDir = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), osMajorVersion.wc_str()); + AddKexts(OSAllVersionKextsDir, osMajorVersion, archCpuType); if (OSTYPE_IS_OSX_INSTALLER(LoaderType)) { - DirName = SWPrintf("10_install"); - // snwprintf(DirName, sizeof(DirName), "10_install"); + DirName = SWPrintf("%ls_install", osMajorVersion.wc_str()); } else if (OSTYPE_IS_OSX_RECOVERY(LoaderType)) { - DirName = SWPrintf("10_recovery"); - // snwprintf(DirName, sizeof(DirName), "10_recovery"); + DirName = SWPrintf("%ls_recovery", osMajorVersion.wc_str()); } else { - DirName = SWPrintf("10_normal"); - // snwprintf(DirName, sizeof(DirName), "10_normal"); + DirName = SWPrintf("%ls_normal", osMajorVersion.wc_str()); } DirPath = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), DirName.wc_str()); - // snwprintf(DirPath, sizeof(DirPath), "%s\\kexts\\%s", OEMPath, DirName); AddKexts(DirPath, DirName, archCpuType); - // Add kext from 10.{version} + // Add kext from ${osMajorVersion}.{version} OSShortVersionKextsDir = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), UniShortOSVersion.wc_str()); - // snwprintf(OSShortVersionKextsDir, sizeof(OSShortVersionKextsDir), "%s\\kexts\\%s", OEMPath, UniShortOSVersion); AddKexts( OSShortVersionKextsDir, UniShortOSVersion, archCpuType); if (OSTYPE_IS_OSX_INSTALLER(LoaderType)) { DirName = SWPrintf("%ls_install", UniShortOSVersion.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_install", UniShortOSVersion); } else if (OSTYPE_IS_OSX_RECOVERY(LoaderType)) { DirName = SWPrintf("%ls_recovery", UniShortOSVersion.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_recovery", UniShortOSVersion); } else { DirName = SWPrintf("%ls_normal", UniShortOSVersion.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_normal", UniShortOSVersion); } DirPath = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), DirName.wc_str()); - // snwprintf(DirPath, sizeof(DirPath), "%s\\kexts\\%s", OEMPath, DirName); AddKexts(DirPath, DirName, archCpuType); // Add kext from : - // 10.{version}.0 if NO minor version - // 10.{version}.{minor version} if minor version is > 0 + // ${osMajorVersion}.{version}.0 if NO minor version + // ${osMajorVersion}.{version}.{minor version} if minor version is > 0 if ( UniShortOSVersion == OSVersion ) { OSVersionKextsDirName = SWPrintf("%s.0", OSVersion.c_str()); - // snwprintf(OSVersionKextsDirName, sizeof(OSVersionKextsDirName), "%a.0", OSVersion); } else { OSVersionKextsDirName = SWPrintf("%s", OSVersion.c_str()); - // snwprintf(OSVersionKextsDirName, sizeof(OSVersionKextsDirName), "%a", OSVersion); } DirPath = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), OSVersionKextsDirName.wc_str()); - // snwprintf(DirPath, sizeof(DirPath), "%s\\kexts\\%s", OEMPath, OSVersionKextsDirName); AddKexts(DirPath, OSVersionKextsDirName, archCpuType); if ( OSTYPE_IS_OSX_INSTALLER(LoaderType)) { DirName = SWPrintf("%ls_install", OSVersionKextsDirName.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_install", OSVersionKextsDirName); } else if (OSTYPE_IS_OSX_RECOVERY(LoaderType)) { DirName = SWPrintf("%ls_recovery", OSVersionKextsDirName.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_recovery", OSVersionKextsDirName); } else { DirName = SWPrintf("%ls_normal", OSVersionKextsDirName.wc_str()); - // snwprintf(DirName, sizeof(DirName), "%s_normal", OSVersionKextsDirName); } DirPath = SWPrintf("%ls\\kexts\\%ls", OEMPath.wc_str(), DirName.wc_str()); - // snwprintf(DirPath, sizeof(DirPath), "%s\\kexts\\%s", OEMPath, DirName); AddKexts(DirPath, DirName, archCpuType); } // reserve space in the device tree if (GetKextCount() > 0) { - mm_extra_size = GetKextCount() * (sizeof(DeviceTreeNodeProperty) + sizeof(_DeviceTreeBuffer)); - mm_extra = (__typeof__(mm_extra))AllocateZeroPool(mm_extra_size - sizeof(DeviceTreeNodeProperty)); - /*Status = */LogDataHub(&gEfiMiscSubClassGuid, L"mm_extra", mm_extra, (UINT32)(mm_extra_size - sizeof(DeviceTreeNodeProperty))); + mm_extra_size = GetKextCount() * (sizeof(DTProperty) + sizeof(_DeviceTreeBuffer)); + mm_extra = (__typeof__(mm_extra))AllocateZeroPool(mm_extra_size - sizeof(DTProperty)); + /*Status = */LogDataHub(&gEfiMiscSubClassGuid, L"mm_extra", mm_extra, (UINT32)(mm_extra_size - sizeof(DTProperty))); extra_size = GetKextsSize(); - extra = (__typeof__(extra))AllocateZeroPool(extra_size - sizeof(DeviceTreeNodeProperty) + EFI_PAGE_SIZE); - /*Status = */LogDataHub(&gEfiMiscSubClassGuid, L"extra", extra, (UINT32)(extra_size - sizeof(DeviceTreeNodeProperty) + EFI_PAGE_SIZE)); + extra = (__typeof__(extra))AllocateZeroPool(extra_size - sizeof(DTProperty) + EFI_PAGE_SIZE); + /*Status = */LogDataHub(&gEfiMiscSubClassGuid, L"extra", extra, (UINT32)(extra_size - sizeof(DTProperty) + EFI_PAGE_SIZE)); // MsgLog("count: %d \n", GetKextCount()); // MsgLog("mm_extra_size: %d \n", mm_extra_size); // MsgLog("extra_size: %d \n", extra_size); - // MsgLog("offset: %d \n", extra_size - sizeof(DeviceTreeNodeProperty) + EFI_PAGE_SIZE); + // MsgLog("offset: %d \n", extra_size - sizeof(DTProperty) + EFI_PAGE_SIZE); //no more needed FreePool(mm_extra); FreePool(extra); @@ -631,7 +670,7 @@ typedef struct { int LOADER_ENTRY::is_mkext_v1(UINT8* drvPtr) { - _DeviceTreeBuffer *dtb = (_DeviceTreeBuffer*) (((UINT8*)drvPtr) + sizeof(DeviceTreeNodeProperty)); + _DeviceTreeBuffer *dtb = (_DeviceTreeBuffer*) (((UINT8*)drvPtr) + sizeof(DTProperty)); MKextHeader* mkext_ptr = (MKextHeader*)(UINTN)(dtb->paddr); if (mkext_ptr->Magic == MKEXT_MAGIC @@ -645,7 +684,7 @@ int LOADER_ENTRY::is_mkext_v1(UINT8* drvPtr) void LOADER_ENTRY::patch_mkext_v1(UINT8 *drvPtr) { - _DeviceTreeBuffer *dtb = (_DeviceTreeBuffer*) (((UINT8*)drvPtr) + sizeof(DeviceTreeNodeProperty)); + _DeviceTreeBuffer *dtb = (_DeviceTreeBuffer*) (((UINT8*)drvPtr) + sizeof(DTProperty)); MKextHeader* mkext_ptr = (MKextHeader*)(UINTN)dtb->paddr; UINT32 mkext_len = SwapBytes32(mkext_ptr->Length); @@ -719,7 +758,7 @@ EFI_STATUS LOADER_ENTRY::InjectKexts(IN UINT32 deviceTreeP, IN UINT32* deviceTre CHAR8 *ptr; OpaqueDTPropertyIterator OPropIter; DTPropertyIterator iter = &OPropIter; - DeviceTreeNodeProperty *prop = NULL; + DTProperty *prop = NULL; UINT8 *infoPtr = 0; UINT8 *extraPtr = 0; @@ -794,12 +833,12 @@ EFI_STATUS LOADER_ENTRY::InjectKexts(IN UINT32 deviceTreeP, IN UINT32* deviceTre // make space for memory map entries platformEntry->NumProperties -= 2; - offset = sizeof(DeviceTreeNodeProperty) + ((DeviceTreeNodeProperty*) infoPtr)->Length; + offset = sizeof(DTProperty) + ((DTProperty*) infoPtr)->Length; CopyMem(drvPtr+offset, drvPtr, infoPtr-drvPtr); // make space behind device tree // platformEntry->nProperties--; - offset = sizeof(DeviceTreeNodeProperty)+((DeviceTreeNodeProperty*) extraPtr)->Length; + offset = sizeof(DTProperty)+((DTProperty*) extraPtr)->Length; CopyMem(extraPtr, extraPtr+offset, dtLen-(UINTN)(extraPtr-dtEntry)-offset); *deviceTreeLength -= (UINT32)offset; @@ -816,14 +855,14 @@ EFI_STATUS LOADER_ENTRY::InjectKexts(IN UINT32 deviceTreeP, IN UINT32* deviceTre drvinfo->bundlePathPhysAddr += (UINT32) KextBase; memmapEntry->NumProperties++; - prop = ((DeviceTreeNodeProperty*) drvPtr); + prop = ((DTProperty*) drvPtr); prop->Length = sizeof(_DeviceTreeBuffer); - mm = (_DeviceTreeBuffer*) (((UINT8*)prop) + sizeof(DeviceTreeNodeProperty)); + mm = (_DeviceTreeBuffer*) (((UINT8*)prop) + sizeof(DTProperty)); mm->paddr = (UINT32)KextBase; mm->length = KextEntry->kext.length; snprintf(prop->Name, 31, "Driver-%X", (UINT32)KextBase); - drvPtr += sizeof(DeviceTreeNodeProperty) + sizeof(_DeviceTreeBuffer); + drvPtr += sizeof(DTProperty) + sizeof(_DeviceTreeBuffer); KextBase = RoundPage(KextBase + KextEntry->kext.length); DBG_RT(" %llu - %s\n", Index, (CHAR8 *)(UINTN)drvinfo->bundlePathPhysAddr); DBG(" %llu - %s\n", Index, (CHAR8 *)(UINTN)drvinfo->bundlePathPhysAddr); diff --git a/rEFIt_UEFI/Platform/kext_patcher.cpp b/rEFIt_UEFI/Platform/kext_patcher.cpp index ad9412ad1..8e05383c1 100644 --- a/rEFIt_UEFI/Platform/kext_patcher.cpp +++ b/rEFIt_UEFI/Platform/kext_patcher.cpp @@ -10,6 +10,8 @@ extern "C" { #include #include #include +#include + #ifdef __cplusplus } #endif @@ -1613,7 +1615,7 @@ VOID LOADER_ENTRY::PatchLoadedKexts() //DBG(L"Prop: %s\n", PropName); if (AsciiStrStr(PropName,"Driver-")) { // PropEntry _DeviceTreeBuffer is the value of Driver-XXXXXX property - PropEntry = (_DeviceTreeBuffer*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DeviceTreeNodeProperty)); + PropEntry = (_DeviceTreeBuffer*)(((UINT8*)PropIter->CurrentProperty) + sizeof(DTProperty)); //if (DbgCount < 3) DBG(L"%s: paddr = %hhX, length = %hhX\n", PropName, PropEntry->paddr, PropEntry->length); // PropEntry->paddr points to _BooterKextFileInfo diff --git a/rEFIt_UEFI/gui/menu_items/menu_items.h b/rEFIt_UEFI/gui/menu_items/menu_items.h index bfae4e177..945e655de 100644 --- a/rEFIt_UEFI/gui/menu_items/menu_items.h +++ b/rEFIt_UEFI/gui/menu_items/menu_items.h @@ -92,6 +92,7 @@ class REFIT_SIMPLE_MENU_ENTRY_TAG; class REFIT_MENU_ENTRY_ITEM_ABSTRACT; class REFIT_MENU_ITEM_BOOTNUM; class XPointer; +class SIDELOAD_KEXT; /********************************************************** REFIT_ABSTRACT_MENU_ENTRY *************************************************************/ @@ -464,6 +465,7 @@ class REFIT_ABSTRACT_MENU_ENTRY EFI_STATUS AddKext(IN EFI_FILE *RootDir, IN CONST CHAR16 *FileName, IN cpu_type_t archCpuType); void LoadPlugInKexts(IN EFI_FILE *RootDir, IN CONST CHAR16 *DirName, IN cpu_type_t archCpuType, IN BOOLEAN Force); void AddKexts(const XStringW& SrcDir, const XStringW& Path, cpu_type_t archCpuType); + void AddKextsInArray(const XStringW& SrcDir, const XStringW& Path, cpu_type_t archCpuType, XObjArray* kextArray); void KextPatcherRegisterKexts(void *FSInject, void *ForceLoadKexts); void KextPatcherStart(); void PatchPrelinkedKexts(); @@ -489,6 +491,7 @@ class REFIT_ABSTRACT_MENU_ENTRY void Stall(int Pause) { if ( KernelAndKextPatches.KPDebug ) { gBS->Stall(Pause); } }; void StartLoader(); + void StartLoader11(); void AddDefaultMenu(); LOADER_ENTRY* getPartiallyDuplicatedEntry() const; virtual LOADER_ENTRY* getLOADER_ENTRY() { return this; }; diff --git a/rEFIt_UEFI/include/Efi.h b/rEFIt_UEFI/include/Efi.h index 228e9d7f5..e78d84f89 100644 --- a/rEFIt_UEFI/include/Efi.h +++ b/rEFIt_UEFI/include/Efi.h @@ -31,7 +31,7 @@ extern "C" { #include #include #include -#include +//#include #include #include #include @@ -63,6 +63,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/rEFIt_UEFI/include/XToolsConf.h b/rEFIt_UEFI/include/XToolsConf.h index 40501a36e..945dedb6a 100755 --- a/rEFIt_UEFI/include/XToolsConf.h +++ b/rEFIt_UEFI/include/XToolsConf.h @@ -19,7 +19,7 @@ */ #define __XTOOLS_CHECK_OVERFLOW__ -#define Xrealloc(ptr, newsize, oldsize) realloc(ptr, newsize, oldsize) +#define Xrealloc(ptr, newsize, oldsize) reallocWithOldSize(ptr, newsize, oldsize) #endif diff --git a/rEFIt_UEFI/refit.inf b/rEFIt_UEFI/refit.inf index c58909ac5..b3cf2eedf 100644 --- a/rEFIt_UEFI/refit.inf +++ b/rEFIt_UEFI/refit.inf @@ -298,6 +298,7 @@ cpp_unit_test/strncmp_test.h cpp_unit_test/XArray_tests.cpp cpp_unit_test/XArray_tests.h + cpp_unit_test/XBuffer_tests.cpp cpp_unit_test/XBuffer_tests.h cpp_unit_test/XObjArray_tests.cpp cpp_unit_test/XObjArray_tests.h @@ -316,11 +317,13 @@ [Packages] CloverPkg.dec + OpenCorePkg/OpenCorePkg.dec MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec NetworkPkg/NetworkPkg.dec IntelFrameworkPkg/IntelFrameworkPkg.dec IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] UefiApplicationEntryPoint @@ -330,7 +333,7 @@ BaseMemoryLib BaseLib DevicePathLib - DeviceTreeLib + OcDeviceTreeLib DebugLib DxeServicesLib DxeServicesTableLib @@ -348,6 +351,8 @@ WaveLib BaseDebugPrintErrorLevelLib BaseSerialPortLib + OpenCoreLib + OcDebugLogLib [Guids] gEfiAcpiTableGuid @@ -386,6 +391,9 @@ gEfiCertRsa2048Sha256Guid gEfiCertTypeRsa2048Sha256Guid + gOcVendorVariableGuid + gOcReadOnlyVariableGuid + gOcWriteOnlyVariableGuid gAppleOSLoadedNamedEventGuid gBootChimeVendorVariableGuid diff --git a/rEFIt_UEFI/refit/main.cpp b/rEFIt_UEFI/refit/main.cpp index 0f0690116..305f283b2 100644 --- a/rEFIt_UEFI/refit/main.cpp +++ b/rEFIt_UEFI/refit/main.cpp @@ -72,6 +72,10 @@ #include "../Platform/kext_inject.h" #include "../gui/REFIT_MENU_SCREEN.h" +extern "C" { +#include "../../OpenCorePkg/Include/Acidanthera/OpenCore.h" +} + #ifndef DEBUG_ALL #define DEBUG_MAIN 1 #else @@ -564,6 +568,11 @@ VOID CheckEmptyFB() VOID LOADER_ENTRY::StartLoader() { + if ( OSVersion.startWith("11") ) { + StartLoader11(); + return; + } + EFI_STATUS Status; EFI_TEXT_STRING ConOutOutputString = 0; EFI_HANDLE ImageHandle = NULL; @@ -645,6 +654,7 @@ VOID LOADER_ENTRY::StartLoader() //DumpKernelAndKextPatches(KernelAndKextPatches); DBG("start loader\n"); + XStringW devicePathString = DevicePathToXStringW(DevicePath); // Load image into memory (will be started later) Status = LoadEFIImage(DevicePath, LoaderPath.basename(), NULL, &ImageHandle); if (EFI_ERROR(Status)) { @@ -964,6 +974,644 @@ VOID LOADER_ENTRY::StartLoader() + DBG("Closing log\n"); + if (SavePreBootLog) { + Status = SaveBooterLog(SelfRootDir, PREBOOT_LOG); + if (EFI_ERROR(Status)) { + /*Status = */SaveBooterLog(NULL, PREBOOT_LOG); + } + } + +// DBG("StartEFIImage\n"); +// StartEFIImage(DevicePath, LoadOptions, +// Basename(LoaderPath), Basename(LoaderPath), NULL, NULL); + +// DBG("StartEFILoadedImage\n"); + StartEFILoadedImage(ImageHandle, LoadOptions, Basename(LoaderPath.wc_str()), LoaderPath.basename(), NULL); + // Unlock boot screen + if (EFI_ERROR(Status = UnlockBootScreen())) { + DBG("Failed to unlock custom boot screen: %s!\n", efiStrError(Status)); + } + if (OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)) { + // return back orig OutputString + gST->ConOut->OutputString = ConOutOutputString; + } + +// PauseForKey(L"FinishExternalScreen"); + FinishExternalScreen(); +// PauseForKey(L"System started?!"); +} +extern "C" { +#include +#include +#include +#include +extern OC_GLOBAL_CONFIG mOpenCoreConfiguration; +extern OC_STORAGE_CONTEXT mOpenCoreStorage; +extern OC_CPU_INFO mOpenCoreCpuInfo; +extern OC_BOOTSTRAP_PROTOCOL mOpenCoreBootStrap; +extern OC_RSA_PUBLIC_KEY* mOpenCoreVaultKey; + +EFI_STATUS +EFIAPI +OcKernelFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +EFI_STATUS +EFIAPI +InternalEfiLoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +EFI_STATUS +EFIAPI +OcStartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +VOID +OcLoadBooterUefiSupport ( + IN OC_GLOBAL_CONFIG *Config + ); +} // extern "C" + +#define OC_STRING_ASSIGN(ocString, value) do { \ + ocString.DynValue = NULL; \ + strcpy(ocString.Value, value); \ + ocString.MaxSize = sizeof(ocString.Value); \ + ocString.Size = strlen(value)+1; \ +} while (0) + +VOID LOADER_ENTRY::StartLoader11() +{ + EFI_STATUS Status; + EFI_TEXT_STRING ConOutOutputString = 0; + EFI_HANDLE ImageHandle = NULL; + EFI_LOADED_IMAGE *LoadedImage = NULL; + CONST CHAR8 *InstallerVersion; + UINTN i; + NSVGfont *font; // , *nextFont; + + + DbgHeader("StartLoader11"); + + +// if (Settings.notEmpty()) { +// DBG(" Settings: %ls\n", Settings.wc_str()); +// Status = LoadUserSettings(SelfRootDir, Settings, &dict); +// if (!EFI_ERROR(Status)) { +// DBG(" - found custom settings for this entry: %ls\n", Settings.wc_str()); +// gBootChanged = TRUE; +// Status = GetUserSettings(dict); +// if (EFI_ERROR(Status)) { +// DBG(" - ... but: %s\n", efiStrError(Status)); +// } else { +// if ((gSettings.CpuFreqMHz > 100) && (gSettings.CpuFreqMHz < 20000)) { +// gCPUStructure.MaxSpeed = gSettings.CpuFreqMHz; +// } +// //CopyMem(KernelAndKextPatches, +// // &gSettings.KernelAndKextPatches, +// // sizeof(KERNEL_AND_KEXT_PATCHES)); +// //DBG("Custom KernelAndKextPatches copyed to started entry\n"); +// } +// } else { +// DBG(" - [!] LoadUserSettings failed: %s\n", efiStrError(Status)); +// } +// } + +// DBG("Finally: ExternalClock=%lluMHz BusSpeed=%llukHz CPUFreq=%uMHz", +// DivU64x32(gCPUStructure.ExternalClock + kilo - 1, kilo), +// DivU64x32(gCPUStructure.FSBFrequency + kilo - 1, kilo), +// gCPUStructure.MaxSpeed); +// if (gSettings.QPI) { +// DBG(" QPI: hw.busfrequency=%lluHz\n", MultU64x32(gSettings.QPI, Mega)); +// } else { +// // to match the value of hw.busfrequency in the terminal +// DBG(" PIS: hw.busfrequency=%lluHz\n", MultU64x32(LShiftU64(DivU64x32(gCPUStructure.ExternalClock + kilo - 1, kilo), 2), Mega)); +// } +// +// +// if (OSVersion.notEmpty() && (AsciiOSVersionToUint64(OSVersion) >= AsciiOSVersionToUint64("10.11"_XS8))) { +// if (OSFLAG_ISSET(Flags, OSFLAG_NOSIP)) { +// gSettings.CsrActiveConfig = (UINT32)0xB7F; +// gSettings.BooterConfig = 0x28; +// } +//// ReadSIPCfg(); +// } +// +// FilterKextPatches(); +// FilterKernelPatches(); +// FilterBootPatches(); +// if (LoadedImage && !BooterPatch((UINT8*)LoadedImage->ImageBase, LoadedImage->ImageSize)) { +// DBG("Will not patch boot.efi\n"); +// } +// +// // Set boot argument for kernel if no caches, this should force kernel loading +// if ( OSFLAG_ISSET(Flags, OSFLAG_NOCACHES) && !LoadOptions.containsStartWithIC("Kernel=") ) { +// XString8 KernelLocation; +// +// if (OSVersion.notEmpty() && AsciiOSVersionToUint64(OSVersion) <= AsciiOSVersionToUint64("10.9"_XS8)) { +// KernelLocation.S8Printf("\"Kernel=/mach_kernel\""); +// } else { +// // used for 10.10, 10.11, and new version. +// KernelLocation.S8Printf("\"Kernel=/System/Library/Kernels/kernel\""); +// } +// LoadOptions.AddID(KernelLocation); +// } +// +// //we are booting OSX - restore emulation if it's not installed before g boot.efi +// if (gEmuVariableControl != NULL) { +// gEmuVariableControl->InstallEmulation(gEmuVariableControl); +// } +// +// // first patchACPI and find PCIROOT and RTC +// // but before ACPI patch we need smbios patch +// CheckEmptyFB(); +// PatchSmbios(); +//// DBG("PatchACPI\n"); +// PatchACPI(Volume, OSVersion); +// +// // If KPDebug is true boot in verbose mode to see the debug messages +// if (KernelAndKextPatches.KPDebug) { +// LoadOptions.AddID("-v"_XS8); +// } +// +// DbgHeader("RestSetup macOS"); +// +//// DBG("SetDevices\n"); +// SetDevices(this); +//// DBG("SetFSInjection\n"); +// SetFSInjection(); +// //PauseForKey(L"SetFSInjection"); +//// DBG("SetVariablesForOSX\n"); +// SetVariablesForOSX(this); +//// DBG("SetVariablesForOSX\n"); +// EventsInitialize(this); +//// DBG("FinalizeSmbios\n"); +// FinalizeSmbios(); +// +// SetCPUProperties(); +// +// if (OSFLAG_ISSET(Flags, OSFLAG_HIBERNATED)) { +// DoHibernateWake = PrepareHibernation(Volume); +// } +// SetupDataForOSX(DoHibernateWake); +// +// +// if ( gDriversFlags.AptioFixLoaded && +// !DoHibernateWake && +// !LoadOptions.containsStartWithIC("slide=") ) { +// // Add slide=0 argument for ML+ if not present +// LoadOptions.AddID("slide=0"_XS8); +// } + + XObjArray kextArray; + if (!DoHibernateWake) { + AddKextsInArray(LStringW(L"Kexts\\11"), LStringW(L"11"), CPU_TYPE_X86_64, &kextArray); + } + + memset(&mOpenCoreConfiguration, 0, sizeof(mOpenCoreConfiguration)); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Scheme.KernelCache, "Auto"); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Misc.Security.SecureBootModel, "Default"); + mOpenCoreConfiguration.Kernel.Scheme.FuzzyMatch = 0; + mOpenCoreConfiguration.Kernel.Force.Count = 0; + + mOpenCoreConfiguration.Kernel.Add.Count = kextArray.size(); + mOpenCoreConfiguration.Kernel.Add.AllocCount = mOpenCoreConfiguration.Kernel.Add.Count; + mOpenCoreConfiguration.Kernel.Add.ValueSize = sizeof(OC_KERNEL_ADD_ENTRY); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 + mOpenCoreConfiguration.Kernel.Add.Values = (OC_KERNEL_ADD_ENTRY**)AllocatePool(mOpenCoreConfiguration.Kernel.Add.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Add.Values)); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 + + for (size_t kextIdx = 0 ; kextIdx < kextArray.size() ; kextIdx++ ) + { + const SIDELOAD_KEXT& KextEntry = kextArray[kextIdx]; + DBG("load kext : KextDirNameUnderOEMPath=%ls FileName=%ls\n", KextEntry.KextDirNameUnderOEMPath.wc_str(), KextEntry.FileName.wc_str()); + size_t allocSize = sizeof(__typeof_am__(*mOpenCoreConfiguration.Kernel.Add.Values[kextIdx])); + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx] = (OC_KERNEL_ADD_ENTRY*) AllocatePool (allocSize); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Enabled = 1; + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Arch, "Any"); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Comment, ""); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->MaxKernel, ""); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->MinKernel, ""); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Identifier, ""); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->BundlePath, S8Printf("%ls/%ls", KextEntry.KextDirNameUnderOEMPath.wc_str(), KextEntry.FileName.wc_str()).c_str()); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ExecutablePath, S8Printf("Contents/MacOS/%ls", KextEntry.FileName.subString(0, KextEntry.FileName.indexOf(".")).wc_str()).c_str()); + OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistPath, "Contents/Info.plist"); // TODO : is always Contents/Info.plist ? + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ImageData = NULL; + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ImageDataSize = 0; + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistData = NULL; + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistDataSize = 0; + } + // Seems that Lilu must be first. + if ( kextArray.size() > 1 ) { + for (size_t kextIdx = 1 ; kextIdx < kextArray.size() ; kextIdx++ ) { + if ( XString8(LString8(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->BundlePath.Value)).contains("Lilu.kext") ) { + OC_KERNEL_ADD_ENTRY* v0 = mOpenCoreConfiguration.Kernel.Add.Values[0]; + mOpenCoreConfiguration.Kernel.Add.Values[0] = mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]; + mOpenCoreConfiguration.Kernel.Add.Values[kextIdx] = v0; + } + } + } + + + EFI_HANDLE EntryHandle = NULL; + Status = InternalEfiLoadImage ( + FALSE, + gImageHandle, + DevicePath, + NULL, + 0, + &EntryHandle + ); + if ( EFI_ERROR(Status) ) return; // TODO message ? + + EFI_STATUS OptionalStatus = gBS->HandleProtocol ( + EntryHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + if ( EFI_ERROR(OptionalStatus) ) return; // TODO message ? + XStringW loadOptions = SWPrintf("-v"); + LoadedImage->LoadOptions = (void*)loadOptions.wc_str(); + LoadedImage->LoadOptionsSize = (UINT32)loadOptions.sizeInBytesIncludingTerminator(); + + + Status = OcStartImage (EntryHandle, 0, NULL); + if ( EFI_ERROR(Status) ) return; // TODO message ? + + + + +return; + + + //Free memory + for (i = 0; i < ConfigsNum; i++) { + if (ConfigsList[i]) { + FreePool(ConfigsList[i]); + ConfigsList[i] = NULL; + } + } + for (i = 0; i < DsdtsNum; i++) { + if (DsdtsList[i]) { + FreePool(DsdtsList[i]); + DsdtsList[i] = NULL; + } + } + OptionMenu.FreeMenu(); + //there is a place to free memory + // GuiAnime + // mainParser + // BuiltinIcons + // OSIcons + NSVGfontChain *fontChain = fontsDB; + while (fontChain) { + font = fontChain->font; + NSVGfontChain *nextChain = fontChain->next; + if (font) { + nsvg__deleteFont(font); + fontChain->font = NULL; + } + FreePool(fontChain); + fontChain = nextChain; + } + fontsDB = NULL; +// nsvg__deleteParser(mainParser); //temporary disabled + //destruct_globals_objects(NULL); //we can't destruct our globals here. We need, for example, Volumes. + + //DumpKernelAndKextPatches(KernelAndKextPatches); + DBG("start loader\n"); + XStringW devicePathString = DevicePathToXStringW(DevicePath); + // Load image into memory (will be started later) + Status = LoadEFIImage(DevicePath, LoaderPath.basename(), NULL, &ImageHandle); + if (EFI_ERROR(Status)) { + DBG("Image is not loaded, status=%s\n", efiStrError(Status)); + return; // no reason to continue if loading image failed + } + egClearScreen(&BootBgColor); //if not set then it is already MenuBackgroundPixel + +// KillMouse(); + +// if (LoaderType == OSTYPE_OSX) { + if (OSTYPE_IS_OSX(LoaderType) || + OSTYPE_IS_OSX_RECOVERY(LoaderType) || + OSTYPE_IS_OSX_INSTALLER(LoaderType)) { + + // To display progress bar properly (especially in FV2 mode) boot.efi needs to be in graphics mode. + // Unfortunately many UEFI implementations change the resolution when SetMode happens. + // This is not what boot.efi expects, and it freely calls SetMode at its will. + // As a result we see progress bar at improper resolution and the background is also missing (10.12.x+). + // + // libeg already has a workaround for SetMode behaviour, so we extend it for boot.efi support. + // The approach tries to be follows: + // 1. Ensure we have graphics mode set (since it is a must in the future). + // 2. Request text mode for boot.efi, which it expects by default (here a SetMode libeg hack will trigger + // on problematic UEFI implementations like AMI). + egSetGraphicsModeEnabled(TRUE); + egSetGraphicsModeEnabled(FALSE); + + DBG("GetOSVersion:"); + + //needed for boot.efi patcher + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); + // Correct OSVersion if it was not found + // This should happen only for 10.7-10.9 OSTYPE_OSX_INSTALLER + // For these cases, take OSVersion from loaded boot.efi image in memory + if (/*LoaderType == OSTYPE_OSX_INSTALLER ||*/ OSVersion.isEmpty()) { + + if (!EFI_ERROR(Status)) { + // version in boot.efi appears as "Mac OS X 10.?" + /* + Start OSName Mac OS X 10.12 End OSName Start OSVendor Apple Inc. End + */ + // InstallerVersion = SearchString((CHAR8*)LoadedImage->ImageBase, LoadedImage->ImageSize, "Mac OS X ", 9); + InstallerVersion = AsciiStrStr((CHAR8*)LoadedImage->ImageBase, "Mac OS X "); + if (InstallerVersion != NULL) { // string was found + InstallerVersion += 9; // advance to version location + + if (strncmp(InstallerVersion, "10.7", 4) && + strncmp(InstallerVersion, "10.8", 4) && + strncmp(InstallerVersion, "10.9", 4) && + strncmp(InstallerVersion, "10.10", 5) && + strncmp(InstallerVersion, "10.11", 5) && + strncmp(InstallerVersion, "10.12", 5) && + strncmp(InstallerVersion, "10.13", 5) && + strncmp(InstallerVersion, "10.14", 5) && + strncmp(InstallerVersion, "10.15", 5) && + strncmp(InstallerVersion, "10.16", 5) && + strncmp(InstallerVersion, "11.0", 4)) { + InstallerVersion = NULL; // flag known version was not found + } + if (InstallerVersion != NULL) { // known version was found in image + OSVersion.takeValueFrom(InstallerVersion); + DBG("Corrected OSVersion: %s\n", OSVersion.c_str()); + } + } + } + + BuildVersion.setEmpty(); + } + + if (BuildVersion.notEmpty()) { + DBG(" %s (%s)\n", OSVersion.c_str(), BuildVersion.c_str()); + } else { + DBG(" %s\n", OSVersion.c_str()); + } + + if (OSVersion.notEmpty() && (AsciiOSVersionToUint64(OSVersion) >= AsciiOSVersionToUint64("10.11"_XS8))) { + if (OSFLAG_ISSET(Flags, OSFLAG_NOSIP)) { + gSettings.CsrActiveConfig = (UINT32)0xB7F; + gSettings.BooterConfig = 0x28; + } +// ReadSIPCfg(); + } + + FilterKextPatches(); + FilterKernelPatches(); + FilterBootPatches(); + if (LoadedImage && !BooterPatch((UINT8*)LoadedImage->ImageBase, LoadedImage->ImageSize)) { + DBG("Will not patch boot.efi\n"); + } + + // Set boot argument for kernel if no caches, this should force kernel loading + if ( OSFLAG_ISSET(Flags, OSFLAG_NOCACHES) && !LoadOptions.containsStartWithIC("Kernel=") ) { + XString8 KernelLocation; + + if (OSVersion.notEmpty() && AsciiOSVersionToUint64(OSVersion) <= AsciiOSVersionToUint64("10.9"_XS8)) { + KernelLocation.S8Printf("\"Kernel=/mach_kernel\""); + } else { + // used for 10.10, 10.11, and new version. + KernelLocation.S8Printf("\"Kernel=/System/Library/Kernels/kernel\""); + } + LoadOptions.AddID(KernelLocation); + } + + //we are booting OSX - restore emulation if it's not installed before g boot.efi + if (gEmuVariableControl != NULL) { + gEmuVariableControl->InstallEmulation(gEmuVariableControl); + } + + // first patchACPI and find PCIROOT and RTC + // but before ACPI patch we need smbios patch + CheckEmptyFB(); + PatchSmbios(); +// DBG("PatchACPI\n"); + PatchACPI(Volume, OSVersion); + + // If KPDebug is true boot in verbose mode to see the debug messages + if (KernelAndKextPatches.KPDebug) { + LoadOptions.AddID("-v"_XS8); + } + + DbgHeader("RestSetup macOS"); + +// DBG("SetDevices\n"); + SetDevices(this); +// DBG("SetFSInjection\n"); + SetFSInjection(); + //PauseForKey(L"SetFSInjection"); +// DBG("SetVariablesForOSX\n"); + SetVariablesForOSX(this); +// DBG("SetVariablesForOSX\n"); + EventsInitialize(this); +// DBG("FinalizeSmbios\n"); + FinalizeSmbios(); + + SetCPUProperties(); + + if (OSFLAG_ISSET(Flags, OSFLAG_HIBERNATED)) { + DoHibernateWake = PrepareHibernation(Volume); + } + SetupDataForOSX(DoHibernateWake); + + + if ( gDriversFlags.AptioFixLoaded && + !DoHibernateWake && + !LoadOptions.containsStartWithIC("slide=") ) { + // Add slide=0 argument for ML+ if not present + LoadOptions.AddID("slide=0"_XS8); + } + + + /** + * syscl - append "-xcpm" argument conditionally if set KernelXCPM on Intel Haswell+ low-end CPUs + */ + if (KernelAndKextPatches.KPKernelXCPM && + gCPUStructure.Vendor == CPU_VENDOR_INTEL && gCPUStructure.Model >= CPU_MODEL_HASWELL && + (AsciiStrStr(gCPUStructure.BrandString, "Celeron") || AsciiStrStr(gCPUStructure.BrandString, "Pentium")) && + (AsciiOSVersionToUint64(OSVersion) >= AsciiOSVersionToUint64("10.8.5"_XS8)) && + (AsciiOSVersionToUint64(OSVersion) < AsciiOSVersionToUint64("10.12"_XS8)) && + (!LoadOptions.containsIC("-xcpm"))) { + // add "-xcpm" argv if not present on Haswell+ Celeron/Pentium + LoadOptions.AddID("-xcpm"_XS8); + } + + // add -xcpm on Ivy Bridge if set KernelXCPM and system version is 10.8.5 - 10.11.x + if (KernelAndKextPatches.KPKernelXCPM && + gCPUStructure.Model == CPU_MODEL_IVY_BRIDGE && + (AsciiOSVersionToUint64(OSVersion) >= AsciiOSVersionToUint64("10.8.5"_XS8)) && + (AsciiOSVersionToUint64(OSVersion) < AsciiOSVersionToUint64("10.12"_XS8)) && + (!LoadOptions.containsIC("-xcpm"))) { + // add "-xcpm" argv if not present on Ivy Bridge + LoadOptions.AddID("-xcpm"_XS8); + } + + if (AudioIo) { + AudioIo->StopPlayback(AudioIo); +// CheckSyncSound(true); + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding = NULL; + Status = gBS->HandleProtocol(AudioDriverHandle, &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBinding); + if (DriverBinding) { + DriverBinding->Stop(DriverBinding, AudioDriverHandle, 0, NULL); + } + } + +// DBG("Set FakeCPUID: 0x%X\n", gSettings.FakeCPUID); +// DBG("LoadKexts\n"); + // LoadKexts writes to DataHub, where large writes can prevent hibernate wake (happens when several kexts present in Clover's kexts dir) + if (!DoHibernateWake) { + LoadKexts(); + } + + // blocking boot.efi output if -v is not specified + // note: this blocks output even if -v is specified in + // /Library/Preferences/SystemConfiguration/com.apple.Boot.plist + // which is wrong + // apianti - only block console output if using graphics + // but don't block custom boot logo + if (LoadOptions.containsIC("-v")) { + Flags = OSFLAG_UNSET(Flags, OSFLAG_USEGRAPHICS); + } + } + else if (OSTYPE_IS_WINDOWS(LoaderType)) { + + if (AudioIo) { + AudioIo->StopPlayback(AudioIo); + } + + DBG("Closing events for Windows\n"); + gBS->CloseEvent (OnReadyToBootEvent); + gBS->CloseEvent (ExitBootServiceEvent); + gBS->CloseEvent (mSimpleFileSystemChangeEvent); + + + if (gEmuVariableControl != NULL) { + gEmuVariableControl->UninstallEmulation(gEmuVariableControl); + } + + PatchACPI_OtherOS(L"Windows", FALSE); + //PauseForKey(L"continue"); + + } + else if (OSTYPE_IS_LINUX(LoaderType) || (LoaderType == OSTYPE_LINEFI)) { + + DBG("Closing events for Linux\n"); + gBS->CloseEvent (OnReadyToBootEvent); + gBS->CloseEvent (ExitBootServiceEvent); + gBS->CloseEvent (mSimpleFileSystemChangeEvent); + + if (gEmuVariableControl != NULL) { + gEmuVariableControl->UninstallEmulation(gEmuVariableControl); + } + //FinalizeSmbios(); + PatchACPI_OtherOS(L"Linux", FALSE); + //PauseForKey(L"continue"); + } + + if (gSettings.LastBootedVolume) { + if ( APFSTargetUUID.notEmpty() ) { + // Jief : we need to LoaderPath. If not, GUI can't know which target was selected. + SetStartupDiskVolume(Volume, LoaderPath); + }else{ + // Jief : I'm not sure why NullXStringW was given if LoaderType == OSTYPE_OSX. + // Let's do it like it was before when not in case of APFSTargetUUID + SetStartupDiskVolume(Volume, LoaderType == OSTYPE_OSX ? NullXStringW : LoaderPath); + } + } else if (gSettings.DefaultVolume.notEmpty()) { + // DefaultVolume specified in Config.plist or in Boot Option + // we'll remove macOS Startup Disk vars which may be present if it is used + // to reboot into another volume + RemoveStartupDiskVolume(); + } +/* + { + // UINT32 machineSignature = 0; + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer = NULL; + EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs = NULL; + + // DBG("---dump hibernations data---\n"); + FadtPointer = GetFadt(); + if (FadtPointer != NULL) { + Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE*)(UINTN)(FadtPointer->FirmwareCtrl); + + DBG(" Firmware wake address=%08lx\n", Facs->FirmwareWakingVector); + DBG(" Firmware wake 64 addr=%16llx\n", Facs->XFirmwareWakingVector); + DBG(" Hardware signature =%08lx\n", Facs->HardwareSignature); + DBG(" GlobalLock =%08lx\n", Facs->GlobalLock); + DBG(" Flags =%08lx\n", Facs->Flags); + DBG(" HS at offset 0x%08X\n", OFFSET_OF(EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, HardwareSignature)); + // machineSignature = Facs->HardwareSignature; + } + } +*/ + +// DBG("BeginExternalScreen\n"); + BeginExternalScreen(OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)/*, L"Booting OS"*/); + + if (!OSTYPE_IS_WINDOWS(LoaderType) && !OSTYPE_IS_LINUX(LoaderType)) { + if (OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)) { + // save orig OutputString and replace it with + // null implementation + ConOutOutputString = gST->ConOut->OutputString; + gST->ConOut->OutputString = NullConOutOutputString; + } + + // Initialize the boot screen + if (EFI_ERROR(Status = InitBootScreen(this))) { + if (Status != EFI_ABORTED) DBG("Failed to initialize custom boot screen: %s!\n", efiStrError(Status)); + } + else if (EFI_ERROR(Status = LockBootScreen())) { + DBG("Failed to lock custom boot screen: %s!\n", efiStrError(Status)); + } + } // !OSTYPE_IS_WINDOWS + + if (OSTYPE_IS_OSX(LoaderType) || + OSTYPE_IS_OSX_RECOVERY(LoaderType) || + OSTYPE_IS_OSX_INSTALLER(LoaderType)) { + + if (DoHibernateWake) { + DBG("Closing events for wake\n"); + gBS->CloseEvent (OnReadyToBootEvent); + gBS->CloseEvent (ExitBootServiceEvent); + gBS->CloseEvent (mSimpleFileSystemChangeEvent); +// gBS->CloseEvent (mVirtualAddressChangeEvent); + // When doing hibernate wake, save to DataHub only up to initial size of log + SavePreBootLog = FALSE; + } else { + // delete boot-switch-vars if exists + Status = gRT->SetVariable(L"boot-switch-vars", &gEfiAppleBootGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); + DeleteNvramVariable(L"IOHibernateRTCVariables", &gEfiAppleBootGuid); + DeleteNvramVariable(L"boot-image", &gEfiAppleBootGuid); + + } + SetupBooterLog(!DoHibernateWake); + } + + + DBG("Closing log\n"); if (SavePreBootLog) { Status = SaveBooterLog(SelfRootDir, PREBOOT_LOG); @@ -1765,7 +2413,6 @@ XStringW g_str2(L"g_str:foobar2"); //XStringW g_str12(L"g_str:foobar2"); #endif - // // main entry point // @@ -1825,12 +2472,36 @@ RefitMain (IN EFI_HANDLE ImageHandle, if ( !EFI_ERROR(Status) ) DBG("Clover : Image base = 0x%llX\n", (uintptr_t)LoadedImage->ImageBase); // do not change, it's used by grep to feed the debugger #ifdef JIEF_DEBUG - gBS->Stall(1500000); // to give time to gdb to connect +// gBS->Stall(3500000); // to give time to gdb to connect // gBS->Stall(0500000); // to give time to gdb to connect // PauseForKey(L"press\n"); #endif } + construct_globals_objects(gImageHandle); // do this after SelfLoadedImage is initialized + + + EFI_LOADED_IMAGE* OcLoadedImage; + Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &OcLoadedImage); + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileSystem = LocateFileSystem(OcLoadedImage->DeviceHandle, OcLoadedImage->FilePath); + Status = OcStorageInitFromFs(&mOpenCoreStorage, FileSystem, L"EFI\\CLOVER", NULL); + + OcConfigureLogProtocol ( + 127, + 0, + 2151678018, + 2147483648, + OPEN_CORE_LOG_PREFIX_PATH, + mOpenCoreStorage.FileSystem + ); + DEBUG ((DEBUG_INFO, "OC: Log initialized...\n")); + OcAppleDebugLogInstallProtocol(0); + OcLoadBooterUefiSupport(&mOpenCoreConfiguration); + OcLoadKernelSupport(&mOpenCoreStorage, &mOpenCoreConfiguration, &mOpenCoreCpuInfo); + OcImageLoaderInit (); + + + #ifdef JIEF_DEBUG // all_tests(); // PauseForKey(L"press\n"); @@ -2076,6 +2747,85 @@ RefitMain (IN EFI_HANDLE ImageHandle, gEmuVariableControl->InstallEmulation(gEmuVariableControl); } +// +// +// OC_GLOBAL_CONFIG* Config = &mOpenCoreConfiguration; +// +// +// memset(Config, 0, sizeof(*Config)); +// OC_STRING_ASSIGN(Config->Kernel.Scheme.KernelCache, "Auto"); +// OC_STRING_ASSIGN(Config->Misc.Security.SecureBootModel, "Default"); +// Config->Kernel.Scheme.FuzzyMatch = 0; +// Config->Kernel.Force.Count = 0; +// +// Config->Kernel.Add.Count = 2; +// Config->Kernel.Add.AllocCount = Config->Kernel.Add.Count; +// Config->Kernel.Add.ValueSize = sizeof(OC_KERNEL_ADD_ENTRY); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 +// Config->Kernel.Add.Values = (OC_KERNEL_ADD_ENTRY**)AllocatePool(Config->Kernel.Add.AllocCount*sizeof(*Config->Kernel.Add.Values)); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 +// +// Config->Kernel.Add.Values[0] = (OC_KERNEL_ADD_ENTRY*)AllocatePool(sizeof(__typeof_am__(*Config->Kernel.Add.Values[0]))); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 +// Config->Kernel.Add.Values[0]->Enabled = 1; +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->Arch, "Any"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->Comment, "Comment Lilu.kext"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->MaxKernel, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->MinKernel, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->Identifier, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->BundlePath, "11/Lilu.kext"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->ExecutablePath, "Contents/MacOS/Lilu"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[0]->PlistPath, "Contents/Info.plist"); +// Config->Kernel.Add.Values[0]->ImageData = NULL; +// Config->Kernel.Add.Values[0]->ImageDataSize = 0; +// Config->Kernel.Add.Values[0]->PlistData = NULL; +// Config->Kernel.Add.Values[0]->PlistDataSize = 0; +// +// Config->Kernel.Add.Values[1] = (OC_KERNEL_ADD_ENTRY*)AllocatePool(sizeof(__typeof_am__(*Config->Kernel.Add.Values[1]))); // sizeof(OC_KERNEL_ADD_ENTRY) == 680 +// Config->Kernel.Add.Values[1]->Enabled = 1; +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->Arch, "Any"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->Comment, "Comment VirtualSMC.kext"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->MaxKernel, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->MinKernel, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->Identifier, ""); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->BundlePath, "11/VirtualSMC.kext"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->ExecutablePath, "Contents/MacOS/VirtualSMC"); +// OC_STRING_ASSIGN(Config->Kernel.Add.Values[1]->PlistPath, "Contents/Info.plist"); +// Config->Kernel.Add.Values[1]->ImageData = NULL; +// Config->Kernel.Add.Values[1]->ImageDataSize = 0; +// Config->Kernel.Add.Values[1]->PlistData = NULL; +// Config->Kernel.Add.Values[1]->PlistDataSize = 0; +// + +// UINTN HandleCount = 0; +// EFI_HANDLE *Handles = NULL; +// Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles); +// UINTN HandleIndex; +// for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { +// EFI_DEVICE_PATH_PROTOCOL* DevicePath = DevicePathFromHandle(Handles[HandleIndex]); +// XStringW DevicePathXString = DevicePathToXStringW(DevicePath); +// if ( LString8("PciRoot(0x0)/Pci(0x11,0x0)/Pci(0x5,0x0)/Sata(0x1,0x0,0x0)/HD(3,0,0,0x40040,0x1BBFFC0)") == DevicePathXString ) break; +// } +// EFI_DEVICE_PATH_PROTOCOL* jfkImagePath = FileDevicePath(Handles[HandleIndex], L"\\System\\Library\\CoreServices\\boot.efi"); +// XStringW DevicePathXString = DevicePathToXStringW(jfkImagePath); +// +// EFI_HANDLE EntryHandle = NULL; +// Status = InternalEfiLoadImage ( +// FALSE, +// gImageHandle, +// jfkImagePath, +// NULL, +// 0, +// &EntryHandle +// ); +// // OcLoadBootEntry (Context, Context-> +// Status = OcStartImage (EntryHandle, 0, NULL); + + + + + + + + + DbgHeader("InitScreen"); if (!GlobalConfig.FastBoot) { diff --git a/rEFIt_UEFI/refit/menu.cpp b/rEFIt_UEFI/refit/menu.cpp index 842e74df2..ae666543d 100644 --- a/rEFIt_UEFI/refit/menu.cpp +++ b/rEFIt_UEFI/refit/menu.cpp @@ -60,6 +60,13 @@ #include "../Platform/Injectors.h" #include "../gui/REFIT_MENU_SCREEN.h" +extern "C" { +#include +extern OC_GLOBAL_CONFIG mOpenCoreConfiguration; + +} // extern "C" + + #ifndef DEBUG_ALL #define DEBUG_MENU 1 #else @@ -913,22 +920,22 @@ VOID ApplyInputs(VOID) i++; //101 - Quirks if (InputItems[i].Valid) { gSettings.QuirksMask = InputItems[i].IValue; - gQuirks.AvoidRuntimeDefrag = ((gSettings.QuirksMask & QUIRK_DEFRAG) != 0); //1 - gQuirks.DevirtualiseMmio = ((gSettings.QuirksMask & QUIRK_MMIO) != 0); //0 - gQuirks.DisableSingleUser = ((gSettings.QuirksMask & QUIRK_SU) != 0); //0 - gQuirks.DisableVariableWrite = ((gSettings.QuirksMask & QUIRK_VAR) != 0); //0 - gQuirks.DiscardHibernateMap = ((gSettings.QuirksMask & QUIRK_HIBER) != 0); //0 - gQuirks.EnableSafeModeSlide = ((gSettings.QuirksMask & QUIRK_SAFE) != 0); //1 - gQuirks.EnableWriteUnprotector = ((gSettings.QuirksMask & QUIRK_UNPROT) != 0); //1 - gQuirks.ForceExitBootServices = ((gSettings.QuirksMask & QUIRK_EXIT) != 0); //0 - gQuirks.ProtectMemoryRegions = ((gSettings.QuirksMask & QUIRK_REGION) != 0); //0 - gQuirks.ProtectSecureBoot = ((gSettings.QuirksMask & QUIRK_SECURE) != 0); //0 - gQuirks.ProtectUefiServices = ((gSettings.QuirksMask & QUIRK_UEFI) != 0); //0 - gQuirks.ProvideCustomSlide = ((gSettings.QuirksMask & QUIRK_CUSTOM) != 0); //1 - gQuirks.RebuildAppleMemoryMap = ((gSettings.QuirksMask & QUIRK_MAP) != 0); //0 - gQuirks.SetupVirtualMap = ((gSettings.QuirksMask & QUIRK_VIRT) != 0); //1 - gQuirks.SignalAppleOS = ((gSettings.QuirksMask & QUIRK_OS) != 0); //0 - gQuirks.SyncRuntimePermissions = ((gSettings.QuirksMask & QUIRK_PERM) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.AvoidRuntimeDefrag = ((gSettings.QuirksMask & QUIRK_DEFRAG) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.DevirtualiseMmio = ((gSettings.QuirksMask & QUIRK_MMIO) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.DisableSingleUser = ((gSettings.QuirksMask & QUIRK_SU) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.DisableVariableWrite = ((gSettings.QuirksMask & QUIRK_VAR) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.DiscardHibernateMap = ((gSettings.QuirksMask & QUIRK_HIBER) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.EnableSafeModeSlide = ((gSettings.QuirksMask & QUIRK_SAFE) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.EnableWriteUnprotector = ((gSettings.QuirksMask & QUIRK_UNPROT) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.ForceExitBootServices = ((gSettings.QuirksMask & QUIRK_EXIT) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.ProtectMemoryRegions = ((gSettings.QuirksMask & QUIRK_REGION) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.ProtectSecureBoot = ((gSettings.QuirksMask & QUIRK_SECURE) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.ProtectUefiServices = ((gSettings.QuirksMask & QUIRK_UEFI) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.ProvideCustomSlide = ((gSettings.QuirksMask & QUIRK_CUSTOM) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.RebuildAppleMemoryMap = ((gSettings.QuirksMask & QUIRK_MAP) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.SetupVirtualMap = ((gSettings.QuirksMask & QUIRK_VIRT) != 0); //1 + mOpenCoreConfiguration.Booter.Quirks.SignalAppleOS = ((gSettings.QuirksMask & QUIRK_OS) != 0); //0 + mOpenCoreConfiguration.Booter.Quirks.SyncRuntimePermissions = ((gSettings.QuirksMask & QUIRK_PERM) != 0); //1 DBG("applied Quirks mask:%x\n", gSettings.QuirksMask); //default is 0xA861 } i++; //102 @@ -2437,7 +2444,7 @@ REFIT_ABSTRACT_MENU_ENTRY* SubMenuBLC() SubScreen->AddMenuCheck("Hi DPI", kBootArgsFlagHiDPI, 65); SubScreen->AddMenuCheck("Black Screen", kBootArgsFlagBlack, 65); SubScreen->AddMenuCheck("CSR Active Config", kBootArgsFlagCSRActiveConfig, 65); - SubScreen->AddMenuCheck("CSR Pending Config", kBootArgsFlagCSRPendingConfig, 65); + SubScreen->AddMenuCheck("CSR Pending Config", kBootArgsFlagCSRConfigMode, 65); SubScreen->AddMenuCheck("CSR Boot", kBootArgsFlagCSRBoot, 65); SubScreen->AddMenuCheck("Black Background", kBootArgsFlagBlackBg, 65); SubScreen->AddMenuCheck("Login UI", kBootArgsFlagLoginUI, 65);